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

Revision 13041, 8.5 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
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, const std::vector<unsigned int>& indices );
140    void writeUVList( int numVerts, const osg::Geometry& geom, unsigned int first=0);
141
142    // Light Point records
143    void writeLightPoint();
144
145    // Exporter doesn't currently support color palette; write a dummy in its place to
146    // support loaders that require it.
147    void writeColorPalette();
148
149    // StateSet stack support
150    void pushStateSet( const osg::StateSet* rhs );
151    void popStateSet();
152    const osg::StateSet* getCurrentStateSet() const;
153    void clearStateSetStack();
154
155    // Write a .attr file if none exists in the data file path.
156    void writeATTRFile( int unit, const osg::Texture2D* texture ) const;
157
158
159private:
160    // Methods for handling different primitive set types.
161    //   These are defined in expGeometryRecords.cpp.
162    void handleDrawArrays( const osg::DrawArrays* da, const osg::Geometry& geom, const osg::Geode& geode );
163    void handleDrawArrayLengths( const osg::DrawArrayLengths* dal, const osg::Geometry& geom, const osg::Geode& geode );
164    void handleDrawElements( const osg::DrawElements* de, const osg::Geometry& geom, const osg::Geode& geode );
165
166    bool isLit( const osg::Geometry& geom ) const;
167    bool isTextured( int unit, const osg::Geometry& geom ) const;
168    bool isMesh( const GLenum mode ) const;
169    bool atLeastOneFace( const osg::Geometry& geom ) const;
170    bool atLeastOneMesh( const osg::Geometry& geom ) const;
171
172    osg::ref_ptr< ExportOptions > _fltOpt;
173
174    // _dos is the primary output stream, produces the actual .flt file.
175    DataOutputStream& _dos;
176
177    // _records is a temp file for most records. After the Header and palette
178    // records are written to _dos, _records is copied onto _dos.
179    osgDB::ofstream _recordsStr;
180    DataOutputStream* _records;
181    std::string _recordsTempName;
182
183    // Track state changes during a scene graph walk.
184    typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetStack;
185    StateSetStack _stateSetStack;
186
187    std::auto_ptr<MaterialPaletteManager>     _materialPalette;
188    std::auto_ptr<TexturePaletteManager>      _texturePalette;
189    std::auto_ptr<LightSourcePaletteManager>  _lightSourcePalette;
190    std::auto_ptr<VertexPaletteManager>       _vertexPalette;
191
192    // Used to avoid duplicate Header/Group records at top of output FLT file.
193    bool _firstNode;
194};
195
196/*!
197   Helper class to ensure symmetrical state push/pop behavior.
198 */
199class ScopedStatePushPop
200{
201    public:
202        ScopedStatePushPop ( FltExportVisitor * fnv, const osg::StateSet *ss ) :
203            fnv_( fnv )
204        {
205            fnv_->pushStateSet( ss );
206        }
207        virtual ~ScopedStatePushPop ()
208        {
209            fnv_->popStateSet();
210        }
211
212    private:
213        FltExportVisitor * fnv_;
214};
215
216
217/*!
218   Automatically handles writing the LongID ancillary record.
219 */
220struct IdHelper
221{
222    IdHelper(flt::FltExportVisitor& v, const std::string& id)
223      : v_(v), id_(id), dos_(NULL)
224    { }
225
226    // Write an ancillary ID record upon destruction if name is too long
227    ~IdHelper()
228    {
229        if (id_.length() > 8)
230            v_.writeLongID(id_,dos_);
231    }
232
233    // Allow implicit conversion to the abbreviated name string
234    operator const std::string() const
235    {
236        return( (id_.length() > 8) ? id_.substr(0, 8) : id_ );
237    }
238
239    flt::FltExportVisitor&  v_;
240    const std::string        id_;
241    DataOutputStream* dos_;
242
243protected:
244
245    IdHelper& operator = (const IdHelper&) { return *this; }
246
247};
248
249
250/*!
251   Supports wrapping subfaces with push/pop records.
252 */
253struct SubfaceHelper
254{
255    SubfaceHelper(flt::FltExportVisitor& v, const osg::StateSet* ss )
256      : v_(v)
257    {
258        _polygonOffsetOn = ( ss->getMode( GL_POLYGON_OFFSET_FILL ) == osg::StateAttribute::ON );
259        if (_polygonOffsetOn)
260            v_.writePushSubface();
261    }
262
263    ~SubfaceHelper()
264    {
265        if (_polygonOffsetOn)
266            v_.writePopSubface();
267    }
268
269    flt::FltExportVisitor&  v_;
270    bool _polygonOffsetOn;
271
272protected:
273
274    SubfaceHelper& operator = (const SubfaceHelper&) { return *this; }
275};
276
277}
278
279#endif
Note: See TracBrowser for help on using the browser.