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

Revision 11056, 7.6 kB (checked in by robert, 4 years ago)

From Sukender, "- Added support for extended filenames (=not 8.3) for images: reads without crashing, optionnally write extended filenames (correctly truncate names if option is OFF). Write option is OFF by default.
- Improved identifiers generation in duplicate name handling (was limited to 1000 name collisions, which can be very short for some usages).
- Set all read/write operations use a custom log function that will redirect lib3DS log to osg::notify() (was only used for streams)
- Removed custom code (now uses osgDB::getFilePath())
- Added missing supportsOption() calls
- Cleaned a few minor things"

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"
[11056]44#include <set>
[10945]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
51class WriterNodeVisitor: public osg::NodeVisitor
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,
[11056]59                        const std::string & srcDirectory);
[10945]60
61        bool        suceedLastApply() const;
62        void        failedApply();
63        virtual void apply(osg::Geode &node);
64
65        virtual void apply(osg::Group &node);
66        virtual void apply(osg::MatrixTransform &node);
67
68        void traverse (osg::Node &node)
69        {
70            pushStateSet(node.getStateSet());
71            osg::NodeVisitor::traverse( node );
72            popStateSet(node.getStateSet());
73        }
74
75        void pushStateSet(osg::StateSet* ss)
76        {
77        if (NULL!=ss) {
78            // Save our current stateset
79            _stateSetStack.push(_currentStateSet.get());
80
81            // merge with node stateset
82            _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
83            _currentStateSet->merge(*ss);
84        }
85        }
86
87
88        void popStateSet(osg::StateSet* ss)
89        {
90            if (NULL!=ss) {
91            // restore the previous stateset
92            _currentStateSet = _stateSetStack.top();
93            _stateSetStack.pop();
94            }
95        }
96
97
98        void writeMaterials();
99
100
101
102        ///\todo Add support for 2nd texture, opacity_map, bump_map, specular_map, shininess_map, self_illum_map, reflection_map.
103        class Material {
104            public:
105                Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index=-1);
106
107                int index;            ///< Index in the 3DS file
108                osg::Vec4 diffuse, ambient, specular;
109                float shininess;
110                float transparency;
111                bool  double_sided;
112                std::string name;
113                osg::ref_ptr<osg::Image> image;
114                bool texture_transparency;
115                bool texture_no_tile;
116            protected:
117                Material() : index(-1) {}
118
119        };
120
121    protected:
122        struct CompareStateSet
123        {
124            bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
125            {
126                return *ss1 < *ss2;
127            }
128        };
129
130
131    private:
132        WriterNodeVisitor& operator = (const WriterNodeVisitor&) { return *this; }
133
134        /**
135        *  Fill the faces field of the mesh and call buildMesh().
136        *  \param geo is the geode who contain vertice and faces.
137        *  \param listTriangles contain all the meshs faces.
138        *  \param texcoords tell us if we have to treat texture coord.
139        */
140        void buildFaces(osg::Geode & geo, ListTriangle & listTriangles, bool texcoords);
141
142        /**
143        *  Calculate the number of vertices in the geode.
144        *  \return the number of vertices in the geode.
145        */
146        unsigned int 
147        calcVertices(osg::Geode & geo);
148
149        /**
150        *  Build a mesh
151        *  \param geo is the geode who contain vertice and faces
152        *  \param index_vert is the index used to build the new mesh
153        *  \param texcoords tell us if we have to treat texture coord
154        *  \param mesh is the mesh with faces filled
155        *  \return the place of the box in the vector.
156        *  \sa See cutScene() about the definition of the boxes for faces sorting.
157        */
158        void
159        buildMesh(osg::Geode        &    geo,
160                  MapIndices        &    index_vert,
161                  bool                   texcoords,       
162                  Lib3dsMesh             *mesh);
163
164        /**
165        *  Add a vertice to the index and link him with the Triangle index and the drawable.
166        *  \param index_vert is the map where the vertice are stored.
167        *  \param index is the indice of the vertice's position in the vec3.
168        *  \param drawable_n is the number of the drawable.
169        *  \return the position of the vertice in the final mesh.
170        */
171        unsigned int
172        getMeshIndexForGeometryIndex(MapIndices & index_vert,
173                                     unsigned int index,
174                                     unsigned int drawable_n);
175        /**
176        *  Create the list of faces from the geode.
177        *  \param geo is the geode to study.
178        *  \param listTriangles is the list to fill.
179        *  \param texcoords tell us if we have to treat texture coord.
180        *  \param drawable_n tell us which drawable we are building.
181        */ 
182        void createListTriangle(osg::Geometry       *    geo,
183                                ListTriangle        &    listTriangles,
184                                bool                &    texcoords,
185                                unsigned int        &    drawable_n);
186
187        int processStateSet(osg::StateSet* stateset);
188
189        std::string getUniqueName(const std::string& defaultvalue="", const std::string & defaultPrefix = "", bool nameIsPath = false);
190        std::string export3DSTexture(const osg::Image * image, const std::string & fileName);
191
192        typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
193        typedef std::map< osg::ref_ptr<osg::StateSet>, Material, CompareStateSet> MaterialMap;
194
195
196        bool                                _suceedLastApply;
197        std::string                         _directory;
198        std::string                         _srcDirectory;
199        Lib3dsFile *                        file3ds;
200        StateSetStack                       _stateSetStack;
201        osg::ref_ptr<osg::StateSet>         _currentStateSet;
[11056]202        std::map<std::string, unsigned int> _mapPrefix;            ///< List of next number to use in unique name generation, for each prefix
[10945]203        std::set<std::string>                _nameMap;
204        MaterialMap                         _materialMap;
205        unsigned int                        _lastMaterialIndex;
206        unsigned int                        _lastMeshIndex;
207        Lib3dsMeshInstanceNode *            _cur3dsNode;
208        const osgDB::ReaderWriter::Options* options;
209        unsigned int                        _imageCount;
[11056]210        bool                                _extendedFilePaths;
211        std::set<osg::Image *>              _imageSet;
[10945]212};
213
214#endif
Note: See TracBrowser for help on using the browser.