2009-07-24 22:45:44 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield
|
2004-05-07 23:18:59 +08:00
|
|
|
*
|
2009-07-24 22:45:44 +08:00
|
|
|
* This application is open source and may be redistributed and/or modified
|
2004-05-07 23:18:59 +08:00
|
|
|
* freely and without restriction, both in commericial and non commericial
|
|
|
|
* applications, as long as this copyright notice is maintained.
|
|
|
|
*
|
|
|
|
* This application is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-11-17 23:03:51 +08:00
|
|
|
/* file: src/osgPlugins/scale/ReaderWriterSCALE.cpp
|
|
|
|
* author: Mike Weiblen http://mew.cx/ 2004-07-15
|
|
|
|
* copyright: (C) 2004 Michael Weiblen
|
|
|
|
* license: OpenSceneGraph Public License (OSGPL)
|
2004-05-07 23:18:59 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <osg/Notify>
|
|
|
|
#include <osg/Matrix>
|
|
|
|
#include <osg/MatrixTransform>
|
|
|
|
|
|
|
|
#include <osgDB/ReaderWriter>
|
|
|
|
#include <osgDB/FileNameUtils>
|
|
|
|
#include <osgDB/Registry>
|
|
|
|
#include <osgDB/ReadFile>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#define EXTENSION_NAME "scale"
|
|
|
|
|
2005-06-29 18:23:34 +08:00
|
|
|
|
2005-11-02 18:29:38 +08:00
|
|
|
static bool getFilenameAndParams(const std::string& input, std::string& filename, std::string& params)
|
2005-06-29 18:23:34 +08:00
|
|
|
{
|
|
|
|
// find the start of the params list, accounting for nesting of [] and () brackets,
|
|
|
|
// note, we are working backwards.
|
|
|
|
int noNestedBrackets = 0;
|
|
|
|
std::string::size_type pos = input.size();
|
|
|
|
for(; pos>0; )
|
|
|
|
{
|
|
|
|
--pos;
|
|
|
|
char c = input[pos];
|
|
|
|
if (c==']') ++noNestedBrackets;
|
|
|
|
else if (c=='[') --noNestedBrackets;
|
|
|
|
else if (c==')') ++noNestedBrackets;
|
|
|
|
else if (c=='(') --noNestedBrackets;
|
|
|
|
else if (c=='.' && noNestedBrackets==0) break;
|
|
|
|
}
|
|
|
|
|
2005-11-17 23:03:51 +08:00
|
|
|
// get the next "extension", which actually contains the pseudo-loader parameters
|
|
|
|
params = input.substr(pos+1, std::string::npos );
|
|
|
|
if( params.empty() )
|
|
|
|
{
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_WARN << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl;
|
2005-11-17 23:03:51 +08:00
|
|
|
return false;
|
|
|
|
}
|
2005-06-29 18:23:34 +08:00
|
|
|
|
2009-07-24 22:45:44 +08:00
|
|
|
// clear the params string of any brackets.
|
2005-06-29 18:23:34 +08:00
|
|
|
std::string::size_type params_pos = params.size();
|
|
|
|
for(; params_pos>0; )
|
|
|
|
{
|
|
|
|
--params_pos;
|
|
|
|
char c = params[params_pos];
|
|
|
|
if (c==']' || c=='[' || c==')' || c=='(')
|
|
|
|
{
|
|
|
|
params.erase(params_pos,1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-17 23:03:51 +08:00
|
|
|
// strip the "params extension", which must leave a sub-filename.
|
|
|
|
filename = input.substr(0, pos );
|
2005-06-29 18:23:34 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-05-07 23:18:59 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
2004-07-17 18:33:26 +08:00
|
|
|
* An OSG reader plugin for the ".scale" pseudo-loader, which inserts a
|
|
|
|
* scale transform above the loaded geometry.
|
|
|
|
* This pseudo-loader make it simple to change the size of a saved model
|
|
|
|
* by specifying a correcting scale factor as part of the filename.
|
|
|
|
*
|
2009-07-24 22:45:44 +08:00
|
|
|
* Usage: <modelfile.ext>.<sx>,<sy>,<sz>.scale
|
|
|
|
* <modelfile.ext>.<su>.scale
|
2004-07-17 18:33:26 +08:00
|
|
|
* where:
|
2009-07-24 22:45:44 +08:00
|
|
|
* <modelfile.ext> = a model filename.
|
2005-11-17 23:03:51 +08:00
|
|
|
* <sx> = scale factor along the X axis.
|
|
|
|
* <sy> = scale factor along the Y axis.
|
|
|
|
* <sz> = scale factor along the Z axis.
|
|
|
|
* <su> = uniform scale factor applied to all axes.
|
2004-07-17 18:33:26 +08:00
|
|
|
*
|
|
|
|
* example: osgviewer cow.osg.5.scale cessna.osg
|
2004-05-07 23:18:59 +08:00
|
|
|
*/
|
2004-07-17 18:33:26 +08:00
|
|
|
|
2004-05-07 23:18:59 +08:00
|
|
|
class ReaderWriterSCALE : public osgDB::ReaderWriter
|
|
|
|
{
|
|
|
|
public:
|
2008-07-14 06:18:59 +08:00
|
|
|
ReaderWriterSCALE()
|
|
|
|
{
|
|
|
|
supportsExtension(EXTENSION_NAME,"Scale Pseudo loader");
|
|
|
|
}
|
2004-05-07 23:18:59 +08:00
|
|
|
|
2004-10-26 18:26:43 +08:00
|
|
|
virtual const char* className() const { return "scaling pseudo-loader"; }
|
2004-05-07 23:18:59 +08:00
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual bool acceptsExtension(const std::string& extension) const
|
2009-07-24 22:45:44 +08:00
|
|
|
{
|
2005-11-17 23:03:51 +08:00
|
|
|
return osgDB::equalCaseInsensitive( extension, EXTENSION_NAME );
|
2004-05-07 23:18:59 +08:00
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
2004-05-07 23:18:59 +08:00
|
|
|
{
|
2005-11-17 23:03:51 +08:00
|
|
|
std::string ext = osgDB::getLowerCaseFileExtension(fileName);
|
|
|
|
if( !acceptsExtension(ext) )
|
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
2004-05-07 23:18:59 +08:00
|
|
|
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_INFO << "ReaderWriterSCALE( \"" << fileName << "\" )" << std::endl;
|
2004-05-07 23:18:59 +08:00
|
|
|
|
2005-11-17 23:03:51 +08:00
|
|
|
// strip the pseudo-loader extension
|
|
|
|
std::string tmpName = osgDB::getNameLessExtension( fileName );
|
2004-05-07 23:18:59 +08:00
|
|
|
|
2005-06-29 18:23:34 +08:00
|
|
|
if (tmpName.empty())
|
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
|
|
|
|
|
|
|
std::string subFileName, params;
|
|
|
|
if (!getFilenameAndParams(tmpName, subFileName, params))
|
|
|
|
{
|
2005-11-17 23:03:51 +08:00
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( subFileName.empty())
|
|
|
|
{
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_WARN << "Missing subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl;
|
2005-11-17 23:03:51 +08:00
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_INFO << " params = \"" << params << "\"" << std::endl;
|
|
|
|
OSG_INFO << " subFileName = \"" << subFileName << "\"" << std::endl;
|
2005-11-17 23:03:51 +08:00
|
|
|
|
|
|
|
float sx, sy, sz;
|
|
|
|
int count = sscanf( params.c_str(), "%f,%f,%f", &sx, &sy, &sz );
|
|
|
|
if( count == 1 )
|
|
|
|
{
|
|
|
|
// if only one value supplied, apply uniform scaling
|
|
|
|
sy = sx;
|
|
|
|
sz = sx;
|
|
|
|
}
|
|
|
|
else if( count != 3 )
|
|
|
|
{
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_WARN << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl;
|
2005-11-17 23:03:51 +08:00
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// recursively load the subfile.
|
|
|
|
osg::Node *node = osgDB::readNodeFile( subFileName, options );
|
|
|
|
if( !node )
|
|
|
|
{
|
|
|
|
// propagate the read failure upwards
|
2010-05-29 01:07:24 +08:00
|
|
|
OSG_WARN << "Subfile \"" << subFileName << "\" could not be loaded" << std::endl;
|
2005-11-17 23:03:51 +08:00
|
|
|
return ReadResult::FILE_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::MatrixTransform *xform = new osg::MatrixTransform;
|
|
|
|
xform->setDataVariance( osg::Object::STATIC );
|
|
|
|
xform->setMatrix( osg::Matrix::scale( sx, sy, sz ) );
|
|
|
|
xform->addChild( node );
|
|
|
|
|
2009-10-30 23:17:38 +08:00
|
|
|
#ifndef OSG_GLES2_AVAILABLE
|
|
|
|
// turn on GL_NORMALIZE to prevent problems with scaled normals
|
|
|
|
osg::StateSet* ss = xform->getOrCreateStateSet();
|
|
|
|
ss->setMode( GL_NORMALIZE, osg::StateAttribute::ON );
|
|
|
|
#endif
|
|
|
|
|
2005-11-17 23:03:51 +08:00
|
|
|
return xform;
|
2004-05-07 23:18:59 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Add ourself to the Registry to instantiate the reader/writer.
|
2007-07-06 21:54:26 +08:00
|
|
|
REGISTER_OSGPLUGIN(scale, ReaderWriterSCALE)
|
2004-05-07 23:18:59 +08:00
|
|
|
|
|
|
|
/*EOF*/
|
|
|
|
|