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

Revision 13041, 8.3 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1// -*-c++-*-
2
3/*
4* 3DS reader/writer for Open Scene Graph
5*
6* Copyright (C) ???
7*
8* Writing support added 2009 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#include <set>
45
46void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix);
47
48typedef std::map<std::pair<unsigned int, unsigned int>, unsigned int> MapIndices;
49typedef std::vector<std::pair<Triangle, int> > ListTriangle; //the int is the drawable of the triangle
50
51namespace plugin3ds
52{
53
54class WriterNodeVisitor: public osg::NodeVisitor
55{
56    public:
57        static const unsigned int MAX_VERTICES = 65000;
58        static const unsigned int MAX_FACES    = MAX_VERTICES;
59
60        WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & fileName,
61                        const osgDB::ReaderWriter::Options* options,
62                        const std::string & srcDirectory);
63
64        bool succeeded() const { return _succeeded; }
65        virtual void apply(osg::Geode &node);
66        virtual void apply(osg::Billboard &node);
67
68        virtual void apply(osg::Group &node);
69        virtual void apply(osg::MatrixTransform &node);
70
71        void traverse (osg::Node &node)
72        {
73            pushStateSet(node.getStateSet());
74            osg::NodeVisitor::traverse( node );
75            popStateSet(node.getStateSet());
76        }
77
78        void pushStateSet(osg::StateSet* ss)
79        {
80        if (NULL!=ss) {
81            // Save our current stateset
82            _stateSetStack.push(_currentStateSet.get());
83
84            // merge with node stateset
85            _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
86            _currentStateSet->merge(*ss);
87        }
88        }
89
90
91        void popStateSet(osg::StateSet* ss)
92        {
93            if (NULL!=ss) {
94            // restore the previous stateset
95            _currentStateSet = _stateSetStack.top();
96            _stateSetStack.pop();
97            }
98        }
99
100
101        void writeMaterials();
102
103
104
105        ///\todo Add support for 2nd texture, opacity_map, bump_map, specular_map, shininess_map, self_illum_map, reflection_map.
106        class Material {
107            public:
108                Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index=-1);
109
110                int index;            ///< Index in the 3DS file
111                osg::Vec4 diffuse, ambient, specular;
112                float shininess;
113                float transparency;
114                bool  double_sided;
115                std::string name;
116                osg::ref_ptr<osg::Image> image;
117                bool texture_transparency;
118                bool texture_no_tile;
119            protected:
120                Material() : index(-1) {}
121
122        };
123
124    protected:
125        struct CompareStateSet
126        {
127            bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
128            {
129                return *ss1 < *ss2;
130            }
131        };
132
133
134    private:
135        WriterNodeVisitor& operator = (const WriterNodeVisitor&) { return *this; }
136
137        /**
138        *  Fill the faces field of the mesh and call buildMesh().
139        *  \param geo is the geode who contain vertice and faces.
140        *  \param mat Local to world matrix applied to the geode
141        *  \param listTriangles contain all the meshs faces.
142        *  \param texcoords tell us if we have to treat texture coord.
143        */
144        void buildFaces(osg::Geode & geo, const osg::Matrix & mat, ListTriangle & listTriangles, bool texcoords);
145
146        /**
147        *  Calculate the number of vertices in the geode.
148        *  \return the number of vertices in the geode.
149        */
150        unsigned int calcVertices(osg::Geode & geo);
151
152        /**
153        *  Build a mesh
154        *  \param geo is the geode who contain vertice and faces
155        *  \param mat Local to world matrix applied to the geode
156        *  \param index_vert is the index used to build the new mesh
157        *  \param texcoords tell us if we have to treat texture coord
158        *  \param mesh is the mesh with faces filled
159        *  \sa See cutScene() about the definition of the boxes for faces sorting.
160        */
161        void
162        buildMesh(osg::Geode        &    geo,
163                  const osg::Matrix &    mat,
164                  MapIndices        &    index_vert,
165                  bool                   texcoords,
166                  Lib3dsMesh             *mesh);
167
168        /**
169        *  Add a vertice to the index and link him with the Triangle index and the drawable.
170        *  \param index_vert is the map where the vertice are stored.
171        *  \param index is the indice of the vertice's position in the vec3.
172        *  \param drawable_n is the number of the drawable.
173        *  \return the position of the vertice in the final mesh.
174        */
175        unsigned int
176        getMeshIndexForGeometryIndex(MapIndices & index_vert,
177                                     unsigned int index,
178                                     unsigned int drawable_n);
179        /**
180        *  Create the list of faces from the geode.
181        *  \param geo is the geode to study.
182        *  \param listTriangles is the list to fill.
183        *  \param texcoords tell us if we have to treat texture coord.
184        *  \param drawable_n tell us which drawable we are building.
185        */
186        void createListTriangle(osg::Geometry       *    geo,
187                                ListTriangle        &    listTriangles,
188                                bool                &    texcoords,
189                                unsigned int        &    drawable_n);
190
191        int processStateSet(osg::StateSet* stateset);
192
193        std::string getUniqueName(const std::string& defaultvalue, bool isNodeName, const std::string & defaultPrefix = "", int currentPrefixLen = -1);
194        std::string export3DSTexture(const osg::Image * image, const std::string & fileName);
195
196        typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
197        typedef std::map< osg::ref_ptr<osg::StateSet>, Material, CompareStateSet> MaterialMap;
198
199        void apply3DSMatrixNode(osg::Node &node, const osg::Matrix * m, const char * const prefix);
200
201        bool                                _succeeded;
202        std::string                         _directory;
203        std::string                         _srcDirectory;
204        Lib3dsFile *                        _file3ds;
205        StateSetStack                       _stateSetStack;
206        osg::ref_ptr<osg::StateSet>         _currentStateSet;
207        typedef std::map<std::string, unsigned int> PrefixMap;
208        PrefixMap                           _nodePrefixMap;            ///< List of next number to use in unique name generation, for each prefix
209        PrefixMap                           _imagePrefixMap;
210        typedef std::set<std::string> NameMap;
211        NameMap                             _nodeNameMap;
212        NameMap                             _imageNameMap;
213        MaterialMap                         _materialMap;
214        unsigned int                        _lastMaterialIndex;
215        unsigned int                        _lastMeshIndex;
216        Lib3dsMeshInstanceNode *            _cur3dsNode;
217        const osgDB::ReaderWriter::Options* _options;
218        unsigned int                        _imageCount;
219        bool                                _extendedFilePaths;
220        typedef std::map<osg::Image*, std::string> ImageSet;
221        ImageSet                            _imageSet;                 ///< Map used to avoid renaming and writing twice an image
222};
223
224// end namespace plugin3ds
225}
226
227#endif
Note: See TracBrowser for help on using the browser.