root/OpenSceneGraph/trunk/src/osgPlugins/obj/OBJWriterNodeVisitor.h @ 13041

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

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1// -*-c++-*-
2
3/*
4 * Wavefront OBJ loader for Open Scene Graph
5 *
6 * Copyright (C) 2001 Ulrich Hertlein <u.hertlein@web.de>
7 *
8 * Modified by Robert Osfield to support per Drawable coord, normal and
9 * texture coord arrays, bug fixes, and support for texture mapping.
10 *
11 * Writing support added 2007 by Stephan Huber, http://digitalmind.de,
12 * some ideas taken from the dae-plugin
13 *
14 * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
15 * real-time rendering of large 3D photo-realistic models.
16 * The OSG homepage is http://www.openscenegraph.org/
17 */
18
19 #ifndef OBJ_WRITER_NODE_VISITOR_HEADER__
20 #define OBJ_WRITER_NODE_VISITOR_HEADER__
21
22
23#include <string>
24#include <stack>
25#include <sstream>
26
27#include <osg/Notify>
28#include <osg/Node>
29#include <osg/MatrixTransform>
30#include <osg/Geode>
31
32#include <osg/Geometry>
33#include <osg/StateSet>
34#include <osg/Material>
35#include <osg/Texture2D>
36#include <osg/TexGen>
37#include <osg/TexMat>
38
39#include <osgDB/Registry>
40#include <osgDB/ReadFile>
41#include <osgDB/FileUtils>
42#include <osgDB/FileNameUtils>
43
44
45
46
47#include <map>
48#include <set>
49
50class OBJWriterNodeVisitor: public osg::NodeVisitor {
51
52    public:
53        OBJWriterNodeVisitor(std::ostream& fout, const std::string materialFileName = "") :
54            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
55            _fout(fout),
56            _currentStateSet(new osg::StateSet()),
57            _lastVertexIndex(1),
58            _lastNormalIndex(1),
59            _lastTexIndex(1)
60        {
61            _fout << "# file written by OpenSceneGraph" << std::endl << std::endl;
62
63            if (!materialFileName.empty()) {
64                _fout << "mtllib " << materialFileName << std::endl << std::endl;
65            }
66        }
67
68        virtual void apply(osg::Geode &node);
69
70        virtual void apply(osg::Group &node)
71        {
72            _nameStack.push_back( node.getName().empty() ? node.className() : node.getName() );
73            _fout << std::endl;
74            _fout << "g " << getUniqueName() << std::endl;
75
76            osg::NodeVisitor::traverse( node );
77            _nameStack.pop_back();
78        }
79
80        void traverse (osg::Node &node)
81        {
82            pushStateSet(node.getStateSet());
83
84            osg::NodeVisitor::traverse( node );
85
86            popStateSet(node.getStateSet());
87        }
88
89        void pushStateSet(osg::StateSet* ss)
90        {
91          if (NULL!=ss) {
92            // Save our current stateset
93            _stateSetStack.push(_currentStateSet.get());
94
95            // merge with node stateset
96            _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
97            _currentStateSet->merge(*ss);
98          }
99        }
100
101
102        void popStateSet(osg::StateSet* ss)
103        {
104            if (NULL!=ss) {
105              // restore the previous stateset
106              _currentStateSet = _stateSetStack.top();
107              _stateSetStack.pop();
108            }
109        }
110
111
112        void writeMaterials(std::ostream& fout);
113
114
115
116        class OBJMaterial {
117            public:
118                OBJMaterial() {}
119                OBJMaterial(osg::Material* mat, osg::Texture* tex);
120
121                osg::Vec4  diffuse, ambient, specular;
122                std::string    image;
123                std::string name;
124        };
125
126    protected:
127        struct CompareStateSet
128        {
129            bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
130            {
131                //std::cout << "CompareStateSet: " << ss1->compare(*ss2, false) << " " << ss1 << " " << ss2 << std::endl;
132                return ss1->compare(*ss2, true) < 0;
133            }
134        };
135
136
137    private:
138
139        OBJWriterNodeVisitor& operator = (const OBJWriterNodeVisitor&) { return *this; }
140
141        void processGeometry(osg::Geometry* geo, osg::Matrix& m);
142        void processArray(const std::string& key, osg::Array* array, const osg::Matrix& m = osg::Matrix::identity(), bool isNormal = false);
143
144        void processStateSet(osg::StateSet* stateset);
145
146        std::string getUniqueName(const std::string& defaultValue = "");
147
148        typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
149        typedef std::map< osg::ref_ptr<osg::StateSet>, OBJMaterial, CompareStateSet> MaterialMap;
150
151
152        std::ostream&                            _fout;
153        std::list<std::string>                    _nameStack;
154        StateSetStack                            _stateSetStack;
155        osg::ref_ptr<osg::StateSet>                _currentStateSet;
156        std::map<std::string, unsigned int>        _nameMap;
157        unsigned int                            _lastVertexIndex, _lastNormalIndex, _lastTexIndex;
158        MaterialMap                                _materialMap;
159
160};
161
162#endif
Note: See TracBrowser for help on using the browser.