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

Revision 11194, 7.9 kB (checked in by robert, 5 years ago)

From Sukender, "I've fixed positions for 3DS writer. Points in 3DS must be in world coordinates and I added what was missing.
And by refactoring a bit of code, I may have fixed some StateSets? related bugs (was ignoring StateSets? for osg::Groups).
I also added support for Billboard's points, so now "osgconv lz.osg lz.3ds" has an acceptable output. However, there is no rotation depending on billboards' axis, hence the notice "Warning: 3DS writer is incomplete for Billboards (rotation not implemented).". You may want to remove this notice (or lower the notify severity) if you feel 3DS doesn't have to handle such rotations.
The attached archive contains 3 files from 3DS plugin, against rev. 11162.

Please note there is still the textures issue for cow.osg. I guess it's because it's not a "flat, dummy and standard" texture in slot 0... That is to say the only thing the writer can handle at the moment. I guess I won't address this soon.
"
and

"I've detected and fixed another bug in 3DS writer: support for automatic splitting of meshes having >65k faces/points was buggy (was deleting faces).
Here is my four 3DS modified files (in a ZIP), against rev. 11193, including previous fixes AND Stephan's fix about relative filenames."

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