📄 expprimaryrecords.cpp
字号:
}// Parent pool override flagsstatic const unsigned long COLOR_PALETTE_OVERRIDE = 0x80000000u >> 0;static const unsigned long MATERIAL_PALETTE_OVERRIDE = 0x80000000u >> 1;static const unsigned long TEXTURE_PALETTE_OVERRIDE = 0x80000000u >> 2;static const unsigned long LINE_STYLE_PALETTE_OVERRIDE = 0x80000000u >> 3;static const unsigned long SOUND_PALETTE_OVERRIDE = 0x80000000u >> 4;static const unsigned long LIGHT_SOURCE_PALETTE_OVERRIDE = 0x80000000u >> 5;static const unsigned long LIGHT_POINT_PALETTE_OVERRIDE = 0x80000000u >> 6;static const unsigned long SHADER_PALETTE_OVERRIDE = 0x80000000u >> 7;voidFltExportVisitor::writeExternalReference( const osg::ProxyNode& proxy ){ uint16 length( 216 ); // Set sane defaults for the override flags unsigned long flags = COLOR_PALETTE_OVERRIDE | MATERIAL_PALETTE_OVERRIDE | TEXTURE_PALETTE_OVERRIDE | LIGHT_POINT_PALETTE_OVERRIDE | SHADER_PALETTE_OVERRIDE ; // Selectively turn off overrides for resources we don't need const ParentPools* pp = dynamic_cast<const ParentPools*>(proxy.getUserData() ); if (pp && pp->getColorPool() ) flags &= ~COLOR_PALETTE_OVERRIDE; if (pp && pp->getMaterialPool() ) flags &= ~MATERIAL_PALETTE_OVERRIDE; if (pp && pp->getTexturePool() ) flags &= ~TEXTURE_PALETTE_OVERRIDE; if (pp && pp->getLightSourcePool() ) flags &= ~LIGHT_SOURCE_PALETTE_OVERRIDE; if (pp && pp->getLPAppearancePool() ) flags &= ~LIGHT_POINT_PALETTE_OVERRIDE; if (pp && pp->getShaderPool() ) flags &= ~SHADER_PALETTE_OVERRIDE; _records->writeInt16( (int16) EXTERNAL_REFERENCE_OP ); _records->writeInt16( length ); _records->writeString(proxy.getFileName(0), 200); _records->writeInt32(0); // Reserved _records->writeInt32(flags); _records->writeInt16(0); // ViewAsBoundingBox flag _records->writeInt16(0); // Reserved}voidFltExportVisitor::writeLevelOfDetail( const osg::LOD& lod, osg::Vec3d const& center, double switchInDist, double switchOutDist){ uint16 length( 80 ); IdHelper id(*this, lod.getName() ); _records->writeInt16( (int16) LOD_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // 'Reserved' field _records->writeFloat64( switchInDist ); _records->writeFloat64( switchOutDist ); // Switch-out distance _records->writeInt16( 0 ); // Special Effect ID1 _records->writeInt16( 0 ); // Special Effect ID2 _records->writeInt32( 0 ); // Flags _records->writeFloat64( center.x() ); _records->writeFloat64( center.y() ); _records->writeFloat64( center.z() ); _records->writeFloat64( 0 ); // Transition range _records->writeFloat64( 0 ); // Significant size}voidFltExportVisitor::writeLightSource( const osg::LightSource& node ){ static const unsigned int ENABLED = 0x80000000u >> 0; static const unsigned int GLOBAL = 0x80000000u >> 1; osg::Light const* light = node.getLight(); int index = _lightSourcePalette->add(light); osg::Vec4d const& lightPos = light->getPosition(); osg::Vec3f const& lightDir = light->getDirection(); uint32 flags = 0; osg::StateSet const* ss = getCurrentStateSet(); if (ss->getMode(GL_LIGHT0 + light->getLightNum() ) & osg::StateAttribute::ON) { flags |= ENABLED; } // If this light is enabled for the node at the top of our StateSet stack, // assume it is 'global' for OpenFlight's purposes ss = _stateSetStack.front().get(); if (ss->getMode(GL_LIGHT0 + light->getLightNum() ) & osg::StateAttribute::ON) { flags |= GLOBAL; } uint16 length( 64 ); IdHelper id(*this, node.getName() ); _records->writeInt16( (int16) LIGHT_SOURCE_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // Reserved _records->writeInt32( index ); // Index into light source palette _records->writeInt32( 0 ); // Reserved _records->writeUInt32( flags ); // Flags _records->writeInt32( 0 ); // Reserved _records->writeVec3d( osg::Vec3d( lightPos.x() , lightPos.y() , lightPos.z() ) ); // TODO: Verify that indices 0 and 1 correspond to yaw and pitch _records->writeFloat32( lightDir[0] ); // Yaw _records->writeFloat32( lightDir[1] ); // Pitch}voidFltExportVisitor::writeSwitch( const osgSim::MultiSwitch* ms ){ int32 currMask = ms->getActiveSwitchSet(); int32 numMasks = ms->getSwitchSetList().size(); int32 numWordsPerMask = ms->getNumChildren() / 32; if (ms->getNumChildren() % 32 != 0) ++numWordsPerMask; uint16 length( 28 + numMasks * numWordsPerMask * sizeof(int32) ); IdHelper id(*this, ms->getName() ); _records->writeInt16( (int16) SWITCH_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // <-- 'Reserved' (unused) _records->writeInt32( currMask ); _records->writeInt32( numMasks ); _records->writeInt32( numWordsPerMask ); // For each mask... for (int i = 0; i < numMasks; ++i) { // ... write out the set of 32-bit words comprising the mask uint32 maskWord = 0; const osgSim::MultiSwitch::ValueList& maskBits = ms->getValueList(i); for (size_t j = 0; j < maskBits.size(); ++j) { // If this bit is set, set the corresponding mask word if (maskBits[j]) maskWord |= 1 << (j % 32); // If we just set the 31st (last) bit of the current word, need // to write it out and reset prior to continuing the loop if ( (j + 1) % 32 == 0 ) { _records->writeUInt32(maskWord); maskWord = 0; } } // If the mask size wasn't a multiple of 32, need to write out // the final word containing the 'remainder' bits if (maskBits.size() % 32 != 0) { _records->writeUInt32(maskWord); } }}voidFltExportVisitor::writeSwitch( const osg::Switch* sw ){ // An osg::Switch is just a special case of an osgSim::MultiSwitch // that only has a single mask int32 currMask = 0; int32 numMasks = 1; int32 numWordsPerMask = sw->getNumChildren() / 32; if (sw->getNumChildren() % 32 != 0) ++numWordsPerMask; uint16 length( 28 + numMasks * numWordsPerMask * sizeof(int32) ); IdHelper id(*this, sw->getName() ); _records->writeInt16( (int16) SWITCH_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // <-- 'Reserved' (unused) _records->writeInt32( currMask ); _records->writeInt32( numMasks ); _records->writeInt32( numWordsPerMask ); // Bust the mask up into as many 32-bit words as are necessary to hold it uint32 maskWord = 0; const osg::Switch::ValueList& maskBits = sw->getValueList(); for (size_t i = 0; i < maskBits.size(); ++i) { // If this bit is set, set the corresponding mask word if (maskBits[i]) maskWord |= 1 << (i % 32); // If we just set the 31st (last) bit of the current word, need // to write it out and reset prior to continuing the loop if ( (i + 1) % 32 == 0 ) { _records->writeUInt32(maskWord); maskWord = 0; } } // If the mask size wasn't a multiple of 32, need to write out // the final word containing the 'remainder' bits if (maskBits.size() % 32 != 0) { _records->writeUInt32(maskWord); }}voidFltExportVisitor::writeLightPoint( const osgSim::LightPointNode* lpn ){ enum Directionality { OMNIDIRECTIONAL = 0, UNIDIRECTIONAL = 1, BIDIRECTIONAL = 2 }; enum DisplayMode { RASTER = 0, CALLIG = 1, EITHER = 2 }; enum Modes { ENABLE = 0, DISABLE = 1 }; enum Flags { NO_BACK_COLOR = 0x80000000u >> 1, CALLIGRAPHIC = 0x80000000u >> 3, REFLECTIVE = 0x80000000u >> 4, PERSPECTIVE = 0x80000000u >> 8, FLASHING = 0x80000000u >> 9, ROTATING = 0x80000000u >> 10, ROTATE_CC = 0x80000000u >> 11, VISIBLE_DAY = 0x80000000u >> 15, VISIBLE_DUSK = 0x80000000u >> 16, VISIBLE_NIGHT = 0x80000000u >> 17 }; int32 flags( NO_BACK_COLOR ); if (lpn->getNumLightPoints() == 0) return; // In OSG, each LightPoint within a LightPointNode can have different appearance // parameters, but in OpenFlight, a Light Point Record contains a list of homogeneous // vertices. To be correct, we'd have to look at all LightPoints in the LightPointNode // and spew out multiple FLT records for each group that shared common appearance // parameters. Instead, we cheat: We take the first LightPoint and use its appearance // parameters for all LightPoints in the LightPointNode. const osgSim::LightPoint& lp0 = lpn->getLightPoint( 0 ); // No really good mapping between OSG and FLT light point animations. float32 animPeriod( 0.f ); float32 animEnabled( 0.f ); float32 animPhaseDelay( 0.f ); if (lp0._blinkSequence != NULL) { flags |= FLASHING; animPeriod = 4.f; animEnabled = 2.f; animPhaseDelay = lp0._blinkSequence->getPhaseShift(); } // Note that true bidirectional light points are currently unsupported (they are unavailable // in OSG, so we never write them out to FLT as BIDIRECTIONAL. int32 directionality( OMNIDIRECTIONAL ); float32 horizLobe( 360.f ); float32 vertLobe( 360.f ); float32 lobeRoll( 0.f ); const osgSim::DirectionalSector* ds = dynamic_cast< osgSim::DirectionalSector* >( lp0._sector.get() ); if (ds) { directionality = UNIDIRECTIONAL; horizLobe = osg::RadiansToDegrees( ds->getHorizLobeAngle() ); vertLobe = osg::RadiansToDegrees( ds->getVertLobeAngle() ); lobeRoll = osg::RadiansToDegrees( ds->getLobeRollAngle() ); } { // Braces req'd to invoke idHelper destructor (and potentially // write LongID record) before Push Record. const uint16 length( 156 ); IdHelper id( *this, lpn->getName() ); _records->writeInt16( (int16) LIGHT_POINT_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt16( 0 ); // Surface material code _records->writeInt16( 0 ); // Feature ID _records->writeUInt32( -1 ); // Back color for bidirectional _records->writeInt32( EITHER ); // Display mode _records->writeFloat32( lp0._intensity ); // Intensity _records->writeFloat32( 0.f ); // Back intensity TBD _records->writeFloat32( 0.f ); // min defocus _records->writeFloat32( 0.f ); // max defocus _records->writeInt32( DISABLE ); // Fading mode _records->writeInt32( DISABLE ); // Fog punch mode _records->writeInt32( DISABLE ); // Directional mode _records->writeInt32( 0 ); // Range mode _records->writeFloat32( lpn->getMinPixelSize() ); // min pixel size _records->writeFloat32( lpn->getMaxPixelSize() ); // max pixel size _records->writeFloat32( lp0._radius * 2.f ); // Actual size _records->writeFloat32( 1.f ); // transparent falloff pixel size _records->writeFloat32( 1.f ); // Transparent falloff exponent _records->writeFloat32( 1.f ); // Transparent falloff scalar _records->writeFloat32( 0.f ); // Transparent falloff clamp _records->writeFloat32( 1.f ); // Fog scalar _records->writeFloat32( 0.f ); // Reserved _records->writeFloat32( 0.f ); // Size difference threshold _records->writeInt32( directionality ); // Directionality _records->writeFloat32( horizLobe ); // Horizontal lobe angle _records->writeFloat32( vertLobe ); // Vertical lobe angle _records->writeFloat32( lobeRoll ); // Lobe roll angle _records->writeFloat32( 0.f ); // Directional falloff exponent _records->writeFloat32( 0.f ); // Directional ambient intensity _records->writeFloat32( animPeriod ); // Animation period in seconds _records->writeFloat32( animPhaseDelay ); // Animation phase delay in seconds _records->writeFloat32( animEnabled ); // Animation enabled period in seconds _records->writeFloat32( 1.f ); // Significance _records->writeInt32( 0 ); // Calligraphic draw order _records->writeInt32( flags ); // Flags _records->writeVec3f( osg::Vec3f( 0.f, 0.f, 0.f ) ); // Axis of rotation } { osg::ref_ptr< osg::Vec3dArray > v = new osg::Vec3dArray( lpn->getNumLightPoints() ); osg::ref_ptr< osg::Vec4Array > c = new osg::Vec4Array( lpn->getNumLightPoints() ); osg::ref_ptr< osg::Vec3Array > n = new osg::Vec3Array( lpn->getNumLightPoints() ); osg::Vec3f normal( 0.f, 0.f, 1.f ); unsigned int idx; for( idx=0; idx<lpn->getNumLightPoints(); idx++) { const osgSim::LightPoint& lp = lpn->getLightPoint( idx ); (*v)[ idx ] = lp._position; (*c)[ idx ] = lp._color; const osgSim::DirectionalSector* ds = dynamic_cast< osgSim::DirectionalSector* >( lp._sector.get() ); if (ds) normal = ds->getDirection(); (*n)[ idx ] = normal; } _vertexPalette->add( (const osg::Array*)NULL, v.get(), c.get(), n.get(), NULL, true, true, false ); } writeMatrix( lpn->getUserData() ); writeComment( *lpn ); writePush(); writeVertexList( 0, lpn->getNumLightPoints() ); writePop();}voidFltExportVisitor::writeColorPalette(){ // FLT exporter doesn't use a color palette but writes // a bogus one to satisfy loaders that require it. uint16 length( 4228 ); _dos.writeInt16( (int16) COLOR_PALETTE_OP ); _dos.writeInt16( length ); _dos.writeFill( 128 ); // Reserved int idx; for( idx=0; idx<1024; idx++) _dos.writeUInt32( 0xffffffff ); // Color n}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -