root/OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h @ 10945

Revision 10945, 8.2 kB (checked in by robert, 4 years ago)

Convert dos line endings

RevLine 
[10945]1// -*-c++-*-
2
3/*
4* 3DS reader/writer for Open Scene Graph
5*
6* Copyright (C) ???
7*
8* Writing support added 2007 by Sukender (Benoit Neil), http://sukender.free.fr,
9* strongly inspired by the OBJ writer object by Stephan Huber
10*
11* The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
12* real-time rendering of large 3D photo-realistic models.
13* The OSG homepage is http://www.openscenegraph.org/
14*/
15
16#ifndef _3DS_WRITER_NODE_VISITOR_HEADER__
17#define _3DS_WRITER_NODE_VISITOR_HEADER__
18
19#include <string>
20#include <stack>
21#include <sstream>
22
23#include <osg/Notify>
24#include <osg/Node>
25#include <osg/MatrixTransform>
26#include <osg/Geode>
27
28#include <osg/Geometry>
29#include <osg/StateSet>
30#include <osg/Material>
31#include <osg/Texture2D>
32#include <osg/TexGen>
33#include <osg/TexMat>
34
35#include <osgDB/Registry>
36#include <osgDB/ReadFile>
37#include <osgDB/FileUtils>
38#include <osgDB/FileNameUtils>
39
40#include <map>
41
42#include "lib3ds/lib3ds.h"
43#include "WriterCompareTriangle.h"
44
45void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix);
46
47typedef std::map<std::pair<unsigned int, unsigned int>, unsigned int> MapIndices;
48typedef std::vector<std::pair<Triangle, int> > ListTriangle; //the int is the drawable of the triangle
49
50class WriterNodeVisitor: public osg::NodeVisitor
51{
52
53    public:
54        static const unsigned int MAX_VERTICES = 65000;
55        static const unsigned int MAX_FACES    = MAX_VERTICES;
56
57        WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & fileName,
58                        const osgDB::ReaderWriter::Options* options,
59                        const std::string & srcDirectory) :
60            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
61            _suceedLastApply(true),
62            _srcDirectory(srcDirectory),
63            file3ds(file3ds),
64            _currentStateSet(new osg::StateSet()),
65            _lastGeneratedNumberedName(0),
66            _lastMaterialIndex(0),
67            _lastMeshIndex(0),
68            _cur3dsNode(NULL),
69            options(options),
70            _imageCount(0)
71        {
72            //supportsOption("flipTexture", "flip texture upside-down");
73            if (!fileName.empty())
74                _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front();
75        }
76
77        bool        suceedLastApply() const;
78        void        failedApply();
79        virtual void apply(osg::Geode &node);
80
81        virtual void apply(osg::Group &node);
82        virtual void apply(osg::MatrixTransform &node);
83
84        void traverse (osg::Node &node)
85        {
86            pushStateSet(node.getStateSet());
87            osg::NodeVisitor::traverse( node );
88            popStateSet(node.getStateSet());
89        }
90
91        void pushStateSet(osg::StateSet* ss)
92        {
93        if (NULL!=ss) {
94            // Save our current stateset
95            _stateSetStack.push(_currentStateSet.get());
96
97            // merge with node stateset
98            _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
99            _currentStateSet->merge(*ss);
100        }
101        }
102
103
104        void popStateSet(osg::StateSet* ss)
105        {
106            if (NULL!=ss) {
107            // restore the previous stateset
108            _currentStateSet = _stateSetStack.top();
109            _stateSetStack.pop();
110            }
111        }
112
113
114        void writeMaterials();
115
116
117
118        ///\todo Add support for 2nd texture, opacity_map, bump_map, specular_map, shininess_map, self_illum_map, reflection_map.
119        class Material {
120            public:
121                Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index=-1);
122
123                int index;            ///< Index in the 3DS file
124                osg::Vec4 diffuse, ambient, specular;
125                float shininess;
126                float transparency;
127                bool  double_sided;
128                std::string name;
129                osg::ref_ptr<osg::Image> image;
130                bool texture_transparency;
131                bool texture_no_tile;
132            protected:
133                Material() : index(-1) {}
134
135        };
136
137    protected:
138        struct CompareStateSet
139        {
140            bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
141            {
142                return *ss1 < *ss2;
143            }
144        };
145
146
147    private:
148        WriterNodeVisitor& operator = (const WriterNodeVisitor&) { return *this; }
149
150        /**
151        *  Fill the faces field of the mesh and call buildMesh().
152        *  \param geo is the geode who contain vertice and faces.
153        *  \param listTriangles contain all the meshs faces.
154        *  \param texcoords tell us if we have to treat texture coord.
155        */
156        void buildFaces(osg::Geode & geo, ListTriangle & listTriangles, bool texcoords);
157
158        /**
159        *  Calculate the number of vertices in the geode.
160        *  \return the number of vertices in the geode.
161        */
162        unsigned int 
163        calcVertices(osg::Geode & geo);
164
165        /**
166        *  Build a mesh
167        *  \param geo is the geode who contain vertice and faces
168        *  \param index_vert is the index used to build the new mesh
169        *  \param texcoords tell us if we have to treat texture coord
170        *  \param mesh is the mesh with faces filled
171        *  \return the place of the box in the vector.
172        *  \sa See cutScene() about the definition of the boxes for faces sorting.
173        */
174        void
175        buildMesh(osg::Geode        &    geo,
176                  MapIndices        &    index_vert,
177                  bool                   texcoords,       
178                  Lib3dsMesh             *mesh);
179
180        /**
181        *  Add a vertice to the index and link him with the Triangle index and the drawable.
182        *  \param index_vert is the map where the vertice are stored.
183        *  \param index is the indice of the vertice's position in the vec3.
184        *  \param drawable_n is the number of the drawable.
185        *  \return the position of the vertice in the final mesh.
186        */
187        unsigned int
188        getMeshIndexForGeometryIndex(MapIndices & index_vert,
189                                     unsigned int index,
190                                     unsigned int drawable_n);
191        /**
192        *  Create the list of faces from the geode.
193        *  \param geo is the geode to study.
194        *  \param listTriangles is the list to fill.
195        *  \param texcoords tell us if we have to treat texture coord.
196        *  \param drawable_n tell us which drawable we are building.
197        */ 
198        void createListTriangle(osg::Geometry       *    geo,
199                                ListTriangle        &    listTriangles,
200                                bool                &    texcoords,
201                                unsigned int        &    drawable_n);
202
203        int processStateSet(osg::StateSet* stateset);
204
205        std::string getUniqueName(const std::string& defaultvalue="", const std::string & defaultPrefix = "", bool nameIsPath = false);
206        std::string export3DSTexture(const osg::Image * image, const std::string & fileName);
207
208        typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
209        typedef std::map< osg::ref_ptr<osg::StateSet>, Material, CompareStateSet> MaterialMap;
210
211
212        bool                                _suceedLastApply;
213        std::string                         _directory;
214        std::string                         _srcDirectory;
215        Lib3dsFile *                        file3ds;
216        StateSetStack                       _stateSetStack;
217        osg::ref_ptr<osg::StateSet>         _currentStateSet;
218        std::map<std::string, unsigned int> _mapPrefix;
219        std::set<std::string>                _nameMap;
220        MaterialMap                         _materialMap;
221        unsigned int                        _lastGeneratedNumberedName;
222        unsigned int                        _lastMaterialIndex;
223        unsigned int                        _lastMeshIndex;
224        Lib3dsMeshInstanceNode *            _cur3dsNode;
225        const osgDB::ReaderWriter::Options* options;
226        unsigned int                        _imageCount;
227};
228
229#endif
Note: See TracBrowser for help on using the browser.