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

Revision 13041, 16.9 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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
14//
15// OpenFlight® loader for OpenSceneGraph
16//
17//  Copyright (C) 2005-2007  Brede Johansen
18//
19
20#include <osgSim/MultiSwitch>
21#include <osgSim/LightPointSystem>
22#include <osgSim/LightPointNode>
23#include <osg/Texture2D>
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
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    };
69
70
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)
116    META_dispose(_lpn)
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
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            {
146                lp._blinkSequence->setDataVariance(osg::Object::DYNAMIC);
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
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
163            if (!(_flags & NO_BACK_COLOR))
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
181    virtual void readRecord(RecordInputStream& in, Document& document)
182    {
183        std::string id = in.readString(8);
184        _material = in.readInt16();
185        _feature = in.readInt16();
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
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
237REGISTER_FLTRECORD(LightPoint, LIGHT_POINT_OP)
238
239
240
241/** IndexedLightPoint
242*/
243class IndexedLightPoint : public PrimaryRecord
244{
245    enum Directionality
246    {
247        OMNIDIRECTIONAL = 0,
248        UNIDIRECTIONAL = 1,
249        BIDIRECTIONAL = 2
250    };
251
252    // flags
253    static const unsigned int NO_BACK_COLOR_BIT = 0x80000000u >> 1;
254
255    osg::ref_ptr<osgSim::LightPointNode> _lpn;
256    osg::ref_ptr<LPAppearance> _appearance;
257    osg::ref_ptr<LPAnimation> _animation;
258
259public:
260
261    IndexedLightPoint() {}
262
263    META_Record(IndexedLightPoint)
264
265    META_setID(_lpn)
266    META_setComment(_lpn)
267    META_dispose(_lpn)
268
269    // Add lightpoint, add two if bidirectional.
270    virtual void addVertex(Vertex& vertex)
271    {
272        osgSim::LightPoint lp;
273
274        if (_appearance.valid())
275        {
276            lp._position = vertex._coord;
277            lp._radius = 0.5f * _appearance->actualPixelSize;
278            lp._intensity = _appearance->intensityFront;
279
280            // color
281            lp._color = (vertex.validColor()) ? vertex._color : osg::Vec4(1,1,1,1);
282
283            // sector
284            bool directional = (_appearance->directionality==UNIDIRECTIONAL) || (_appearance->directionality==BIDIRECTIONAL);
285            if (directional && vertex.validNormal())
286            {
287                lp._sector = new osgSim::DirectionalSector(
288                    vertex._normal,
289                    osg::DegreesToRadians(_appearance->horizontalLobeAngle),
290                    osg::DegreesToRadians(_appearance->verticalLobeAngle),
291                    osg::DegreesToRadians(_appearance->lobeRollAngle));
292            }
293
294            // Blink sequence
295            if (_animation.valid())
296            {
297                osgSim::BlinkSequence* blinkSequence = new osgSim::BlinkSequence;
298                blinkSequence->setName(_animation->name);
299
300                switch (_animation->animationType)
301                {
302                case LPAnimation::ROTATING:
303                case LPAnimation::STROBE:
304                    blinkSequence->setPhaseShift(_animation->animationPhaseDelay);
305                    blinkSequence->addPulse(_animation->animationPeriod-_animation->animationEnabledPeriod, osg::Vec4(0,0,0,0));
306                    blinkSequence->addPulse(_animation->animationEnabledPeriod, lp._color);
307                    break;
308
309                case LPAnimation::MORSE_CODE:
310                    // todo
311                    //blinkSequence->addPulse(double length,lp._color);
312                    break;
313
314                case LPAnimation::FLASHING_SEQUENCE:
315                    {
316                        blinkSequence->setPhaseShift(_animation->animationPhaseDelay);
317
318                        for (LPAnimation::PulseArray::iterator itr=_animation->sequence.begin();
319                            itr!=_animation->sequence.end();
320                            ++itr)
321                        {
322                            double duration = itr->duration;
323
324                            osg::Vec4 color;
325                            switch (itr->state)
326                            {
327                            case LPAnimation::ON:
328                                color = lp._color;
329                                break;
330                            case LPAnimation::OFF:
331                                color = osg::Vec4(0,0,0,0);
332                                break;
333                            case LPAnimation::COLOR_CHANGE:
334                                color = itr->color;
335                                break;
336                            }
337
338                            blinkSequence->addPulse(duration, color);
339                        }
340                    }
341                    break;
342                }
343
344                lp._blinkSequence = blinkSequence;
345            }
346
347            _lpn->addLightPoint(lp);
348
349            // Create a new lightpoint if bi-directional.
350            if ((_appearance->directionality==BIDIRECTIONAL) && vertex.validNormal())
351            {
352                // back intensity
353                lp._intensity = _appearance->intensityBack;
354
355                // back color
356                if (!(_appearance->flags & NO_BACK_COLOR_BIT))
357                    lp._color = _appearance->backColor;
358
359                // back sector
360                lp._sector = new osgSim::DirectionalSector(
361                    -vertex._normal,
362                    osg::DegreesToRadians(_appearance->horizontalLobeAngle),
363                    osg::DegreesToRadians(_appearance->verticalLobeAngle),
364                    osg::DegreesToRadians(_appearance->lobeRollAngle));
365
366                _lpn->addLightPoint(lp);
367            }
368        }
369    }
370
371
372protected:
373
374    virtual ~IndexedLightPoint() {}
375
376    virtual void readRecord(RecordInputStream& in, Document& document)
377    {
378        std::string id = in.readString(8);
379        int32 appearanceIndex = in.readInt32();
380        int32 animationIndex = in.readInt32();
381        /*int32 drawOrder =*/ in.readInt32();           // for calligraphic lights
382
383        LightPointAppearancePool* lpAppearancePool = document.getOrCreateLightPointAppearancePool();
384        _appearance = lpAppearancePool->get(appearanceIndex);
385
386        LightPointAnimationPool* lpAnimationPool = document.getOrCreateLightPointAnimationPool();
387        _animation = lpAnimationPool->get(animationIndex);
388
389        _lpn = new osgSim::LightPointNode;
390        _lpn->setName(id);
391
392        if (_appearance.valid())
393        {
394            _lpn->setMinPixelSize(_appearance->minPixelSize);
395            _lpn->setMaxPixelSize(_appearance->maxPixelSize);
396
397            if (_appearance->texturePatternIndex != -1)
398            {
399                // Use point sprites for light points.
400                _lpn->setPointSprite();
401
402                TexturePool* tp = document.getOrCreateTexturePool();
403                osg::StateSet* textureStateSet = tp->get(_appearance->texturePatternIndex);
404                if (textureStateSet)
405                {
406                    // Merge face stateset with texture stateset
407                    osg::StateSet* stateset = _lpn->getOrCreateStateSet();
408                    stateset->merge(*textureStateSet);
409                }
410            }
411        }
412
413        // Add to parent
414        if (_parent.valid())
415            _parent->addChild(*_lpn);
416
417    }
418};
419
420REGISTER_FLTRECORD(IndexedLightPoint, INDEXED_LIGHT_POINT_OP)
421
422
423
424/** LightPointSystem
425*/
426class LightPointSystem : public PrimaryRecord
427{
428    float32 _intensity;
429    int32 _animationState;
430    int32  _flags;
431
432    osg::ref_ptr<osgSim::MultiSwitch> _switch;
433    osg::ref_ptr<osgSim::LightPointSystem> _lps;
434
435public:
436
437    LightPointSystem():
438        _intensity(1.0f),
439        _animationState(0),
440        _flags(0)
441    {}
442
443    META_Record(LightPointSystem)
444    META_addChild(_switch)
445
446protected:
447
448    virtual ~LightPointSystem() {}
449
450    virtual void readRecord(RecordInputStream& in, Document& document)
451    {
452        std::string id = in.readString(8);
453
454        _intensity = in.readFloat32();
455        _animationState = in.readInt32(0);
456        _flags = in.readInt32(0);
457
458        _switch = new osgSim::MultiSwitch;
459        _lps = new osgSim::LightPointSystem;
460
461        _switch->setName(id);
462        _lps->setName(id);
463        _lps->setIntensity(_intensity);
464
465        switch (_animationState)
466        {
467            // Note that OpenFlight 15.8 spec says 0 means on and 1 means off.
468            // However, if animation is set on in Creator, it stores a 1, and
469            // a zero is stored for off! So, for now, we ignore the spec...
470            case 0:
471                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_OFF );
472                break;
473            default:
474            case 1:
475                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_ON );
476                break;
477            case 2:
478                _lps->setAnimationState( osgSim::LightPointSystem::ANIMATION_RANDOM );
479                break;
480        }
481
482        if (_parent.valid())
483            _parent->addChild(*((osg::Group*)_switch.get()));
484    }
485
486    virtual void dispose(Document& document)
487    {
488        if (!_switch.valid()) return;
489
490        // Insert transform(s)
491        if (_matrix.valid())
492        {
493            insertMatrixTransform(*_switch,*_matrix,_numberOfReplications);
494        }
495
496        // Set default sets: 0 for all off, 1 for all on
497        _switch->setAllChildrenOff( 0 );
498        _switch->setAllChildrenOn( 1 );
499
500        // set initial on/off state
501        unsigned int initialSet = ( (_flags & 0x80000000) != 0 ) ? 1 : 0;
502        _switch->setActiveSwitchSet( initialSet );
503
504        for (unsigned int i = 0; i < _switch->getNumChildren(); i++)
505        {
506            osg::Node* child = _switch->getChild(i);
507            if (osgSim::LightPointNode* lpn = dynamic_cast<osgSim::LightPointNode*>(child))
508                lpn->setLightPointSystem(_lps.get());
509        }
510    }
511};
512
513REGISTER_FLTRECORD(LightPointSystem, LIGHT_POINT_SYSTEM_OP)
514
Note: See TracBrowser for help on using the browser.