root/OpenSceneGraph/trunk/src/osgPlugins/scale/ReaderWriterSCALE.cpp @ 13041

Revision 13041, 5.9 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield
2 *
3 * This application is open source and may be redistributed and/or modified
4 * freely and without restriction, both in commercial and non commercial
5 * applications, as long as this copyright notice is maintained.
6 *
7 * This application is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 *
11*/
12
13/* file:        src/osgPlugins/scale/ReaderWriterSCALE.cpp
14 * author:        Mike Weiblen http://mew.cx/ 2004-07-15
15 * copyright:        (C) 2004 Michael Weiblen
16 * license:        OpenSceneGraph Public License (OSGPL)
17*/
18
19#include <osg/Notify>
20#include <osg/Matrix>
21#include <osg/MatrixTransform>
22
23#include <osgDB/ReaderWriter>
24#include <osgDB/FileNameUtils>
25#include <osgDB/Registry>
26#include <osgDB/ReadFile>
27
28#include <stdio.h>
29
30#define EXTENSION_NAME "scale"
31
32
33static bool getFilenameAndParams(const std::string& input, std::string& filename, std::string& params)
34{
35        // find the start of the params list, accounting for nesting of [] and () brackets,
36        // note, we are working backwards.
37        int noNestedBrackets = 0;
38        std::string::size_type pos = input.size();
39        for(; pos>0; )
40        {
41            --pos;
42            char c = input[pos];
43            if (c==']') ++noNestedBrackets;
44            else if (c=='[') --noNestedBrackets;
45            else if (c==')') ++noNestedBrackets;
46            else if (c=='(') --noNestedBrackets;
47            else if (c=='.' && noNestedBrackets==0) break;
48        }
49
50        // get the next "extension", which actually contains the pseudo-loader parameters
51        params = input.substr(pos+1, std::string::npos );
52        if( params.empty() )
53        {
54            OSG_WARN << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl;
55            return false;
56        }
57
58        // clear the params string of any brackets.
59        std::string::size_type params_pos = params.size();
60        for(; params_pos>0; )
61        {
62            --params_pos;
63            char c = params[params_pos];
64            if (c==']' || c=='[' || c==')' || c=='(')
65            {
66                params.erase(params_pos,1);
67            }
68        }
69
70        // strip the "params extension", which must leave a sub-filename.
71        filename = input.substr(0, pos );
72
73        return true;
74}
75
76///////////////////////////////////////////////////////////////////////////
77
78/**
79 * An OSG reader plugin for the ".scale" pseudo-loader, which inserts a
80 * scale transform above the loaded geometry.
81 * This pseudo-loader make it simple to change the size of a saved model
82 * by specifying a correcting scale factor as part of the filename.
83 *
84 * Usage: <modelfile.ext>.<sx>,<sy>,<sz>.scale
85 *        <modelfile.ext>.<su>.scale
86 * where:
87 *      <modelfile.ext> = a model filename.
88 *      <sx> = scale factor along the X axis.
89 *      <sy> = scale factor along the Y axis.
90 *      <sz> = scale factor along the Z axis.
91 *      <su> = uniform scale factor applied to all axes.
92 *
93 * example: osgviewer cow.osg.5.scale cessna.osg
94 */
95
96class ReaderWriterSCALE : public osgDB::ReaderWriter
97{
98public:
99    ReaderWriterSCALE()
100    {
101        supportsExtension(EXTENSION_NAME,"Scale Pseudo loader");
102    }
103
104    virtual const char* className() const { return "scaling pseudo-loader"; }
105
106    virtual bool acceptsExtension(const std::string& extension) const
107    {
108        return osgDB::equalCaseInsensitive( extension, EXTENSION_NAME );
109    }
110
111    virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
112    {
113        std::string ext = osgDB::getLowerCaseFileExtension(fileName);
114        if( !acceptsExtension(ext) )
115            return ReadResult::FILE_NOT_HANDLED;
116
117        OSG_INFO << "ReaderWriterSCALE( \"" << fileName << "\" )" << std::endl;
118
119        // strip the pseudo-loader extension
120        std::string tmpName = osgDB::getNameLessExtension( fileName );
121
122        if (tmpName.empty())
123            return ReadResult::FILE_NOT_HANDLED;
124
125        std::string subFileName, params;
126        if (!getFilenameAndParams(tmpName, subFileName, params))
127        {
128            return ReadResult::FILE_NOT_HANDLED;
129        }
130
131        if( subFileName.empty())
132        {
133            OSG_WARN << "Missing subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl;
134            return ReadResult::FILE_NOT_HANDLED;
135        }
136
137        OSG_INFO << " params = \"" << params << "\"" << std::endl;
138        OSG_INFO << " subFileName = \"" << subFileName << "\"" << std::endl;
139
140        float sx, sy, sz;
141        int count = sscanf( params.c_str(), "%f,%f,%f", &sx, &sy, &sz );
142        if( count == 1 )
143        {
144            // if only one value supplied, apply uniform scaling
145            sy = sx;
146            sz = sx;
147        }
148        else if( count != 3 )
149        {
150            OSG_WARN << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl;
151            return ReadResult::FILE_NOT_HANDLED;
152        }
153
154        // recursively load the subfile.
155        osg::Node *node = osgDB::readNodeFile( subFileName, options );
156        if( !node )
157        {
158            // propagate the read failure upwards
159            OSG_WARN << "Subfile \"" << subFileName << "\" could not be loaded" << std::endl;
160            return ReadResult::FILE_NOT_HANDLED;
161        }
162
163        osg::MatrixTransform *xform = new osg::MatrixTransform;
164        xform->setDataVariance( osg::Object::STATIC );
165        xform->setMatrix( osg::Matrix::scale( sx, sy, sz ) );
166        xform->addChild( node );
167
168        #ifndef OSG_GLES2_AVAILABLE
169            // turn on GL_NORMALIZE to prevent problems with scaled normals
170            osg::StateSet* ss = xform->getOrCreateStateSet();
171            ss->setMode( GL_NORMALIZE, osg::StateAttribute::ON );
172        #endif
173
174        return xform;
175    }
176};
177
178
179// Add ourself to the Registry to instantiate the reader/writer.
180REGISTER_OSGPLUGIN(scale, ReaderWriterSCALE)
181
182/*EOF*/
Note: See TracBrowser for help on using the browser.