root/OpenSceneGraph/trunk/src/osgPlugins/OpenFlight/FltExportVisitor.h @ 9890

Revision 9459, 8.4 kB (checked in by robert, 9 years ago)

Fixed warnings

Line 
1/*
2 * This library is open source and may be redistributed and/or modified under
3 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or (at
4 * your option) any later version. The full license is in the LICENSE file
5 * included with this distribution, and on the openscenegraph.org website.
6 *
7 * This library is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * OpenSceneGraph Public License for more details.
11*/
12
13//
14// Copyright(c) 2008 Skew Matrix Software LLC.
15//
16
17#ifndef __FLTEXP_FLT_EXPORT_VISITOR_H__
18#define __FLTEXP_FLT_EXPORT_VISITOR_H__ 1
19
20#include <osg/NodeVisitor>
21#include "ExportOptions.h"
22#include "Types.h"
23#include <osgDB/fstream>
24#include <set>
25#include <memory>
26
27namespace osg {
28    class DrawArrays;
29    class DrawArrayLengths;
30    class DrawElements;
31    class Geometry;
32    class StateSet;
33    class Switch;
34    class Material;
35    class Texture2D;
36}
37namespace osgSim {
38    class DOFTransform;
39    class MultiSwitch;
40    class LightPointNode;
41    class ObjectRecordData;
42}
43
44namespace flt
45{
46
47
48class ExportOptions;
49class DataOutputStream;
50class MaterialPaletteManager;
51class TexturePaletteManager;
52class VertexPaletteManager;
53class LightSourcePaletteManager;
54
55
56
57/*!
58   The main NodeVisitor for walking the scene graph during export.
59   A collection of apply() methods is in FltExportVisitor.cpp.
60   The apply() methods call several other methods for writing
61   specific FLT record types, most of which are in exp*.cpp.
62 */
63class FltExportVisitor : public osg::NodeVisitor
64{
65public:
66    FltExportVisitor( DataOutputStream* dos, ExportOptions* fltOpt );
67    ~FltExportVisitor(  );
68
69    bool complete( const osg::Node& node );
70
71    virtual void apply( osg::Group& node );
72    virtual void apply( osg::Sequence& node );
73    virtual void apply( osg::Switch& node );
74    virtual void apply( osg::LOD& node );
75    virtual void apply( osg::MatrixTransform& node );
76    virtual void apply( osg::PositionAttitudeTransform& node );
77    virtual void apply( osg::Transform& node );
78    virtual void apply( osg::LightSource& node );
79    virtual void apply( osg::Geode& node );
80    virtual void apply( osg::Node& node );
81    virtual void apply( osg::ProxyNode& node );
82
83
84
85    // Primary records
86    void writeHeader( const std::string& headerName );
87    void writeGroup( const osg::Group& node );
88    void writeGroup( const osg::Group& group,
89                     int32 flags,
90                     int32 loopCount,
91                     float32 loopDuration,
92                     float32 lastFrameDuration);
93    void writeSequence( const osg::Sequence& node );
94    void writeObject( const osg::Group& node, osgSim::ObjectRecordData* ord );
95    void writeDegreeOfFreedom( const osgSim::DOFTransform* dof );
96    void writeExternalReference( const osg::ProxyNode& node );
97    void writeLevelOfDetail( const osg::LOD& lod, const osg::Vec3d& center,
98                             double switchInDist, double switchOutDist);
99    void writeLightSource( const osg::LightSource& ls );
100    void writeSwitch( const osgSim::MultiSwitch* ms );
101    void writeSwitch( const osg::Switch* ms );
102    void writeLightPoint( const osgSim::LightPointNode* lpn );
103
104    // Ancillary records
105    void writeComment( const osg::Node& node, DataOutputStream* dos=NULL );
106    void writeLongID( const std::string& id, DataOutputStream* dos=NULL );
107    void writeMatrix( const osg::Referenced* ref );
108    void writeContinuationRecord( const unsigned short length );
109
110    // Control records
111    void writePush();
112    void writePop();
113    void writePushSubface();
114    void writePopSubface();
115
116    // Helper routine for traversing a pushed subtree
117    void writePushTraverseWritePop(osg::Node& node)
118    {
119        writePush();
120        traverse(node);
121        writePop();
122    }
123
124    void writePushTraverseChildWritePop(osg::Node& node)
125    {
126        writePush();
127        node.accept(*this);
128        writePop();
129    }
130
131    // Geometry records
132    void writeFace( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode );
133    void writeMesh( const osg::Geode& geode, const osg::Geometry& geom );
134    int writeVertexList( int first, unsigned int count );
135    int writeVertexList( const std::vector<unsigned int>& indices, unsigned int count );
136    void writeMeshPrimitive( const std::vector<unsigned int>& indices, GLenum mode );
137    void writeLocalVertexPool( const osg::Geometry& geom );
138    void writeMultitexture( const osg::Geometry& geom );
139    void writeUVList( int numVerts, const osg::Geometry& geom );
140
141    // Light Point records
142    void writeLightPoint();
143
144    // Exporter doesn't currently support color palette; write a dummy in its place to
145    // support loaders that require it.
146    void writeColorPalette();
147
148    // StateSet stack support
149    void pushStateSet( const osg::StateSet* rhs );
150    void popStateSet();
151    const osg::StateSet* getCurrentStateSet() const;
152    void clearStateSetStack();
153
154    // Write a .attr file if none exists in the data file path.
155    void writeATTRFile( int unit, const osg::Texture2D* texture ) const;
156
157
158private:
159    // Methods for handling different primitive set types.
160    //   These are defined in expGeometryRecords.cpp.
161    void handleDrawArrays( const osg::DrawArrays* da, const osg::Geometry& geom, const osg::Geode& geode );
162    void handleDrawArrayLengths( const osg::DrawArrayLengths* dal, const osg::Geometry& geom, const osg::Geode& geode );
163    void handleDrawElements( const osg::DrawElements* de, const osg::Geometry& geom, const osg::Geode& geode );
164
165    bool isLit( const osg::Geometry& geom ) const;
166    bool isTextured( int unit, const osg::Geometry& geom ) const;
167    bool isMesh( const GLenum mode ) const;
168    bool atLeastOneFace( const osg::Geometry& geom ) const;
169    bool atLeastOneMesh( const osg::Geometry& geom ) const;
170
171    osg::ref_ptr< ExportOptions > _fltOpt;
172
173    // _dos is the primary output stream, produces the actual .flt file.
174    DataOutputStream& _dos;
175
176    // _records is a temp file for most records. After the Header and palette
177    // records are written to _dos, _records is copied onto _dos.
178    osgDB::ofstream _recordsStr;
179    DataOutputStream* _records;
180    std::string _recordsTempName;
181
182    // Track state changes during a scene graph walk.
183    typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetStack;
184    StateSetStack _stateSetStack;
185
186    std::auto_ptr<MaterialPaletteManager>     _materialPalette;
187    std::auto_ptr<TexturePaletteManager>      _texturePalette;
188    std::auto_ptr<LightSourcePaletteManager>  _lightSourcePalette;
189    std::auto_ptr<VertexPaletteManager>       _vertexPalette;
190
191    // Used to avoid duplicate Header/Group records at top of output FLT file.
192    bool _firstNode;
193};
194
195/*!
196   Helper class to ensure symmetrical state push/pop behavior.
197 */
198class ScopedStatePushPop
199{
200    public:
201        ScopedStatePushPop ( FltExportVisitor * fnv, const osg::StateSet *ss ) :
202            fnv_( fnv )
203        {
204            fnv_->pushStateSet( ss );
205        }
206        virtual ~ScopedStatePushPop ()
207        {
208            fnv_->popStateSet();
209        }
210
211    private:
212        FltExportVisitor * fnv_;
213};
214
215
216/*!
217   Automatically handles writing the LongID ancillary record.
218 */
219struct IdHelper
220{
221    IdHelper(flt::FltExportVisitor& v, const std::string& id)
222      : v_(v), id_(id), dos_(NULL)
223    { }
224
225    // Write an ancillary ID record upon destruction if name is too long
226    ~IdHelper()
227    {
228        if (id_.length() > 8)
229            v_.writeLongID(id_,dos_);
230    }
231
232    // Allow implicit conversion to the abbreviated name string
233    operator const std::string() const
234    {
235        return( (id_.length() > 8) ? id_.substr(0, 8) : id_ );
236    }
237
238    flt::FltExportVisitor&  v_;
239    const std::string        id_;
240    DataOutputStream* dos_;
241
242protected:
243
244    IdHelper& operator = (const IdHelper&) { return *this; }
245
246};
247
248
249/*!
250   Supports wrapping subfaces with push/pop records.
251 */
252struct SubfaceHelper
253{
254    SubfaceHelper(flt::FltExportVisitor& v, const osg::StateSet* ss )
255      : v_(v)
256    {
257        _polygonOffsetOn = ( ss->getMode( GL_POLYGON_OFFSET_FILL ) == osg::StateAttribute::ON );
258        if (_polygonOffsetOn)
259            v_.writePushSubface();
260    }
261
262    ~SubfaceHelper()
263    {
264        if (_polygonOffsetOn)
265            v_.writePopSubface();
266    }
267
268    flt::FltExportVisitor&  v_;
269    bool _polygonOffsetOn;
270
271protected:
272
273    SubfaceHelper& operator = (const SubfaceHelper&) { return *this; }
274};
275
276}
277
278#endif
Note: See TracBrowser for help on using the browser.