root/OpenSceneGraph/trunk/src/osgPlugins/OpenFlight/LightPointRecords.cpp @ 9382

Revision 9382, 17.0 kB (checked in by robert, 6 years ago)

Fixed warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[7748]1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
[5038]14//
15// OpenFlight® loader for OpenSceneGraph
16//
[7748]17//  Copyright (C) 2005-2007  Brede Johansen
[5038]18//
19
[6757]20#include <osgSim/MultiSwitch>
21#include <osgSim/LightPointSystem>
[5038]22#include <osgSim/LightPointNode>
[5168]23#include <osg/Texture2D>
[5038]24#include "Registry.h"
25#include "Document.h"
26#include "RecordInputStream.h"
27
28using namespace flt;
29
30/** LightPoint
31*/
32class LightPoint : public PrimaryRecord
33{
34    enum Directionality
35    {
36        OMNIDIRECTIONAL = 0,
37        UNIDIRECTIONAL = 1,
38        BIDIRECTIONAL = 2
39    };
40
41    // flags
[6757]42    enum Flags
43    {
44                                                // bit 0 = reserved
45        NO_BACK_COLOR    = 0x80000000u >> 1,        // bit 1 = no back color
46                                                // bit 2 = reserved
47        CALLIGRAPHIC    = 0x80000000u >> 3,        // bit 3 = calligraphic proximity occulting
48        REFLECTIVE        = 0x80000000u >> 4,        // bit 4 = reflective, non-emissive point
49                                                // bit 5-7 = randomize intensity
50                                                //   0 = never
51                                                //     1 = low
52                                                //   2 = medium
53                                                //   3 = high
54        PERSPECTIVE        = 0x80000000u >> 8,        // bit 8 = perspective mode
55        FLASHING        = 0x80000000u >> 9,        // bit 9 = flashing
56        ROTATING        = 0x80000000u >> 10,    // bit 10 = rotating
57        ROTATE_CC        = 0x80000000u >> 11,    // bit 11 = rotate counter clockwise
58                                                // bit 12 = reserved
59                                                // bit 13-14 = quality
60                                                //   0 = low
61                                                //     1 = medium
62                                                //   2 = high
63                                                //   3 = undefined
64        VISIBLE_DAY        = 0x80000000u >> 15,    // bit 15 = visible during day
65        VISIBLE_DUSK    = 0x80000000u >> 16,    // bit 16 = visible during dusk
66        VISIBLE_NIGHT    = 0x80000000u >> 17        // bit 17 = visible during night
67                                                // bit 18-31 = spare
68    };
[5038]69
[6757]70
[5038]71    int16   _material;
72    int16   _feature;
73    osg::Vec4f _backColor;
74    int32   _displayMode;
75    float32 _intensityFront;
76    float32 _intensityBack;
77    float32 _minDefocus;
78    float32 _maxDefocus;
79    int32   _fadeMode;
80    int32   _fogPunchMode;
81    int32   _directionalMode;
82    int32   _rangeMode;
83    float32 _minPixelSize;
84    float32 _maxPixelSize;
85    float32 _actualPixelSize;
86    float32 _transparentFalloff;
87    float32 _transparentFalloffExponent;
88    float32 _transparentFalloffScalar;
89    float32 _transparentFalloffClamp;
90    float32 _fog;
91    float32 _sizeDifferenceThreshold;
92    int32   _directionality;
93    float32 _lobeHorizontal;
94    float32 _lobeVertical;
95    float32 _lobeRoll;
96    float32 _falloff;
97    float32 _ambientIntensity;
98    float32 _animationPeriod;
99    float32 _animationPhaseDelay;
100    float32 _animationPeriodEnable;
101    float32 _significance;
102    int32   _drawOrder;
103    uint32  _flags;
104    osg::Vec3f _animationAxis;
105
106    osg::ref_ptr<osgSim::LightPointNode> _lpn;
107
108public:
109
110    LightPoint() {}
111
112    META_Record(LightPoint)
113
114    META_setID(_lpn)
115    META_setComment(_lpn)
[7756]116    META_dispose(_lpn)
[5038]117
118    // Add lightpoint, add two if bidirectional.
119    virtual void addVertex(Vertex& vertex)
120    {
121        osgSim::LightPoint lp;
122        lp._position = vertex._coord;
123        lp._radius = 0.5f * _actualPixelSize;
124        lp._intensity = _intensityFront;
125
126        // color
127        lp._color = (vertex.validColor()) ? vertex._color : osg::Vec4(1,1,1,1);
128
129        // sector
130        bool directional = (_directionality==UNIDIRECTIONAL) || (_directionality==BIDIRECTIONAL);
131        if (directional && vertex.validNormal())
132        {
133            lp._sector = new osgSim::DirectionalSector(
134                vertex._normal,
135                osg::DegreesToRadians(_lobeHorizontal),
136                osg::DegreesToRadians(_lobeVertical),
137                osg::DegreesToRadians(_lobeRoll));
138        }
139
[6757]140        // if the flashing or rotating bit is set in the flags, add a blink sequence
141        if ((_flags & FLASHING) || (_flags & ROTATING))
142        {
143            lp._blinkSequence = new osgSim::BlinkSequence();
144            if (lp._blinkSequence.valid())
145            {
[6759]146                lp._blinkSequence->setDataVariance(osg::Object::DYNAMIC);
[6757]147                lp._blinkSequence->setPhaseShift(_animationPhaseDelay);
148                lp._blinkSequence->addPulse(_animationPeriod - _animationPeriodEnable,
149                    osg::Vec4f(0.0f, 0.0f, 0.0f, 0.0f));
150                lp._blinkSequence->addPulse(_animationPeriodEnable, lp._color);
151            }
152        }
153
[5038]154        _lpn->addLightPoint(lp);
155
156        // Create a new lightpoint if bi-directional.
157        if ((_directionality==BIDIRECTIONAL) && vertex.validNormal())
158        {
159            // back intensity
160            lp._intensity = _intensityBack;
161
162            // back color
[6757]163            if (!(_flags & NO_BACK_COLOR))
[5038]164                lp._color = _backColor;
165
166            // back sector
167            lp._sector = new osgSim::DirectionalSector(
168                -vertex._normal,
169                osg::DegreesToRadians(_lobeHorizontal),
170                osg::DegreesToRadians(_lobeVertical),
171                osg::DegreesToRadians(_lobeRoll));
172
173            _lpn->addLightPoint(lp);
174        }
175    }
176
177protected:
178
179    virtual ~LightPoint() {}
180
[5337]181    virtual void readRecord(RecordInputStream& in, Document& document)
[5038]182    {
183        std::string id = in.readString(8);
184        _material = in.readInt16();
185        _feature = in.readInt16();
[5337]186
187        int32 backColorIndex = in.readInt32();
188       
189        _backColor = document.getColorPool() ?
190                            document.getColorPool()->getColor(backColorIndex) :
191                            osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
192                           
[5038]193        _displayMode = in.readInt32();
194        _intensityFront = in.readFloat32();
195        _intensityBack = in.readFloat32();
196        _minDefocus = in.readFloat32();
197        _maxDefocus = in.readFloat32();
198        _fadeMode = in.readInt32();
199        _fogPunchMode = in.readInt32();
200        _directionalMode = in.readInt32();
201        _rangeMode = in.readInt32();
202        _minPixelSize = in.readFloat32(); // * document.unitScale();
203        _maxPixelSize = in.readFloat32(); // * document.unitScale();
204        _actualPixelSize = in.readFloat32(); // * document.unitScale();
205        _transparentFalloff = in.readFloat32();
206        _transparentFalloffExponent = in.readFloat32();
207        _transparentFalloffScalar = in.readFloat32();
208        _transparentFalloffClamp = in.readFloat32();
209        _fog = in.readFloat32();
210        in.forward(4);
211        _sizeDifferenceThreshold = in.readFloat32();
212        _directionality = in.readInt32();
213        _lobeHorizontal = in.readFloat32();
214        _lobeVertical = in.readFloat32();
215        _lobeRoll = in.readFloat32();
216        _falloff = in.readFloat32();
217        _ambientIntensity = in.readFloat32();
218        _animationPeriod = in.readFloat32();
219        _animationPhaseDelay = in.readFloat32();
220        _animationPeriodEnable = in.readFloat32();
221        _significance = in.readFloat32();
222        _drawOrder = in.readInt32();
223        _flags = in.readUInt32(0);
224        _animationAxis = in.readVec3f();
225
226        _lpn = new osgSim::LightPointNode;
227        _lpn->setName(id);
228        _lpn->setMinPixelSize(_minPixelSize);
229        _lpn->setMaxPixelSize(_maxPixelSize);
230
231        // Add to parent
232        if (_parent.valid())
233            _parent->addChild(*_lpn);
234    }
235};
236
237RegisterRecordProxy<LightPoint> g_LightPoint(LIGHT_POINT_OP);
238
239
240/** IndexedLightPoint
241*/
242class IndexedLightPoint : public PrimaryRecord
243{
244    enum Directionality
245    {
246        OMNIDIRECTIONAL = 0,
247        UNIDIRECTIONAL = 1,
248        BIDIRECTIONAL = 2
249    };
250
251    // flags
252    static const unsigned int NO_BACK_COLOR_BIT = 0x80000000u >> 1;
253
254    osg::ref_ptr<osgSim::LightPointNode> _lpn;
255    osg::ref_ptr<LPAppearance> _appearance;
[6757]256    osg::ref_ptr<LPAnimation> _animation;
[5038]257
258public:
259
260    IndexedLightPoint() {}
261
262    META_Record(IndexedLightPoint)
263
264    META_setID(_lpn)
265    META_setComment(_lpn)
[7756]266    META_dispose(_lpn)
[5038]267
268    // Add lightpoint, add two if bidirectional.
269    virtual void addVertex(Vertex& vertex)
270    {
[6757]271        osgSim::LightPoint lp;
272
[5038]273        if (_appearance.valid())
274        {
275            lp._position = vertex._coord;
276            lp._radius = 0.5f * _appearance->actualPixelSize;
277            lp._intensity = _appearance->intensityFront;
278
279            // color
280            lp._color = (vertex.validColor()) ? vertex._color : osg::Vec4(1,1,1,1);
281
282            // sector
283            bool directional = (_appearance->directionality==UNIDIRECTIONAL) || (_appearance->directionality==BIDIRECTIONAL);
284            if (directional && vertex.validNormal())
285            {
286                lp._sector = new osgSim::DirectionalSector(
287                    vertex._normal,
288                    osg::DegreesToRadians(_appearance->horizontalLobeAngle),
289                    osg::DegreesToRadians(_appearance->verticalLobeAngle),
290                    osg::DegreesToRadians(_appearance->lobeRollAngle));
291            }
292
[6757]293            // Blink sequence
294            if (_animation.valid())
295            {
296                osgSim::BlinkSequence* blinkSequence = new osgSim::BlinkSequence;
297                blinkSequence->setName(_animation->name);
298
299                switch (_animation->animationType)
300                {
301                case LPAnimation::ROTATING:
302                case LPAnimation::STROBE:
303                    blinkSequence->setPhaseShift(_animation->animationPhaseDelay);
304                    blinkSequence->addPulse(_animation->animationPeriod-_animation->animationEnabledPeriod, osg::Vec4(0,0,0,0));
305                    blinkSequence->addPulse(_animation->animationEnabledPeriod, lp._color);
306                    break;
307
308                case LPAnimation::MORSE_CODE:
309                    // todo
310                    //blinkSequence->addPulse(double length,lp._color);
311                    break;
312
313                case LPAnimation::FLASHING_SEQUENCE:
314                    {
315                        blinkSequence->setPhaseShift(_animation->animationPhaseDelay);
316
317                        for (LPAnimation::PulseArray::iterator itr=_animation->sequence.begin();
318                            itr!=_animation->sequence.end();
319                            ++itr)
320                        {
321                            double duration = itr->duration;
322
323                            osg::Vec4 color;
324                            switch (itr->state)
325                            {
326                            case LPAnimation::ON:
327                                color = lp._color;
328                                break;
329                            case LPAnimation::OFF:
330                                color = osg::Vec4(0,0,0,0);
331                                break;
332                            case LPAnimation::COLOR_CHANGE:
333                                color = itr->color;
334                                break;
335                            }
336
337                            blinkSequence->addPulse(duration, color);
338                        }
339                    }
340                    break;
341                }
342
343                lp._blinkSequence = blinkSequence;
344            }
345
[5038]346            _lpn->addLightPoint(lp);
347
348            // Create a new lightpoint if bi-directional.
349            if ((_appearance->directionality==BIDIRECTIONAL) && vertex.validNormal())
350            {
351                // back intensity
352                lp._intensity = _appearance->intensityBack;
353
354                // back color
355                if (!(_appearance->flags & NO_BACK_COLOR_BIT))
356                    lp._color = _appearance->backColor;
357
358                // back sector
359                lp._sector = new osgSim::DirectionalSector(
360                    -vertex._normal,
361                    osg::DegreesToRadians(_appearance->horizontalLobeAngle),
362                    osg::DegreesToRadians(_appearance->verticalLobeAngle),
363                    osg::DegreesToRadians(_appearance->lobeRollAngle));
364
365                _lpn->addLightPoint(lp);
366            }
367        }
368    }
369
370
371protected:
372
373    virtual ~IndexedLightPoint() {}
374
375    virtual void readRecord(RecordInputStream& in, Document& document)
376    {
377        std::string id = in.readString(8);
378        int32 appearanceIndex = in.readInt32();
[6757]379        int32 animationIndex = in.readInt32();
[9382]380        /*int32 drawOrder =*/ in.readInt32();           // for calligraphic lights
[5038]381
[6757]382        LightPointAppearancePool* lpAppearancePool = document.getOrCreateLightPointAppearancePool();
383        _appearance = lpAppearancePool->get(appearanceIndex);
[5038]384
[6757]385        LightPointAnimationPool* lpAnimationPool = document.getOrCreateLightPointAnimationPool();
386        _animation = lpAnimationPool->get(animationIndex);
387
[5038]388        _lpn = new osgSim::LightPointNode;
389        _lpn->setName(id);
390
391        if (_appearance.valid())
392        {
393            _lpn->setMinPixelSize(_appearance->minPixelSize);
394            _lpn->setMaxPixelSize(_appearance->maxPixelSize);
[5168]395
396            if (_appearance->texturePatternIndex != -1)
397            {
398                // Use point sprites for light points.
399                _lpn->setPointSprite();
400
401                TexturePool* tp = document.getOrCreateTexturePool();
402                osg::StateSet* textureStateSet = tp->get(_appearance->texturePatternIndex);
403                if (textureStateSet)
404                {
405                    // Merge face stateset with texture stateset
406                    osg::StateSet* stateset = _lpn->getOrCreateStateSet();
407                    stateset->merge(*textureStateSet);
408                }
409            }
[5038]410        }
411
412        // Add to parent
413        if (_parent.valid())
414            _parent->addChild(*_lpn);
415
416    }
417};
418
419RegisterRecordProxy<IndexedLightPoint> g_IndexedLightPoint(INDEXED_LIGHT_POINT_OP);
420
421
422/** LightPointSystem
423*/
424class LightPointSystem : public PrimaryRecord
425{
[6757]426    float32 _intensity;
427    int32 _animationState;
428    int32  _flags;
429
430    osg::ref_ptr<osgSim::MultiSwitch> _switch;
431    osg::ref_ptr<osgSim::LightPointSystem> _lps;
432
[5038]433public:
434
[6757]435    LightPointSystem():
436        _intensity(1.0f),
437        _animationState(0),
438        _flags(0)
439    {}
[5038]440
441    META_Record(LightPointSystem)
[6757]442    META_addChild(_switch)
[5038]443
444protected:
445
446    virtual ~LightPointSystem() {}
447
[6757]448    virtual void readRecord(RecordInputStream& in, Document& document)
[5038]449    {
450        std::string id = in.readString(8);
451
[6757]452        _intensity = in.readFloat32();
453        _animationState = in.readInt32(0);
454        _flags = in.readInt32(0);
[5038]455
[6757]456        _switch = new osgSim::MultiSwitch;
457        _lps = new osgSim::LightPointSystem;
458
459        _switch->setName(id);
460        _lps->setName(id);
461        _lps->setIntensity(_intensity);
462
463        switch (_animationState)
464        {
465            // Note that OpenFlight 15.8 spec says 0 means on and 1 means off.
466            // However, if animation is set on in Creator, it stores a 1, and
467            // a zero is stored for off! So, for now, we ignore the spec...
468            case 0:
469                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_OFF );
470                break;
471            default:
472            case 1:
473                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_ON );
474                break;
475            case 2:
476                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_RANDOM );
477                break;
478        }
479
[5038]480        if (_parent.valid())
[6757]481            _parent->addChild(*((osg::Group*)_switch.get()));
[5038]482    }
[6757]483
[7756]484    virtual void dispose(Document& document)
[6757]485    {
[7756]486        if (!_switch.valid()) return;
487
488        // Insert transform(s)
489        if (_matrix.valid())
490        {
491            insertMatrixTransform(*_switch,*_matrix,_numberOfReplications);
492        }
493
[6757]494        // Set default sets: 0 for all off, 1 for all on
495        _switch->setAllChildrenOff( 0 );
496        _switch->setAllChildrenOn( 1 );
497
498        // set initial on/off state
499        unsigned int initialSet = ( (_flags & 0x80000000) != 0 ) ? 1 : 0;
500        _switch->setActiveSwitchSet( initialSet );
501
502        for (unsigned int i = 0; i < _switch->getNumChildren(); i++)
503        {
504            osg::Node* child = _switch->getChild(i);
505            if (osgSim::LightPointNode* lpn = dynamic_cast<osgSim::LightPointNode*>(child))
506                lpn->setLightPointSystem(_lps.get());
507        }
508    }
[5038]509};
510
511RegisterRecordProxy<LightPointSystem> g_LightPointSystem(LIGHT_POINT_SYSTEM_OP);
Note: See TracBrowser for help on using the browser.