📄 expprimaryrecords.cpp
字号:
/* * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or (at * your option) any later version. The full license is in the LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details.*///// Copyright(c) 2008 Skew Matrix Software LLC.//#include "FltExportVisitor.h"#include "ExportOptions.h"#include "VertexPaletteManager.h"#include "LightSourcePaletteManager.h"#include "DataOutputStream.h"#include "Opcodes.h"#include <osg/Group>#include <osg/Sequence>#include <osg/LightSource>#include <osg/LOD>#include <osg/ProxyNode>#include <osg/Switch>#include <osgSim/MultiSwitch>#include <osgSim/DOFTransform>#include <osgSim/LightPointNode>#include <osgSim/ObjectRecordData>// FIXME: This header was copied verbatim from the importer, with the only change// being that the symbols it defines are placed in namespace 'fltexp' instead// of 'flt'. Thus, this one-off copy has to be kept in sync with the// importer until the reader/writer are unified...#include "Pools.h"namespace flt{voidFltExportVisitor::writeHeader( const std::string& headerName ){ int16 length; int32 version; const int ver = _fltOpt->getFlightFileVersionNumber(); if (ver == ExportOptions::VERSION_15_7) { length = 304; version = 1570; } else if (ver == ExportOptions::VERSION_15_8) { length = 324; version = 1580; } else // ExportOptions::VERSION_16_1: { length = 324; version = 1610; } int8 units; switch( _fltOpt->getFlightUnits() ) { case ExportOptions::KILOMETERS: units = 1; break; case ExportOptions::FEET: units = 4; break; case ExportOptions::INCHES: units = 5; break; case ExportOptions::NAUTICAL_MILES: units = 8; break; default: case ExportOptions::METERS: units = 0; break; } static const unsigned int SAVE_VERTEX_NORMALS_BIT = 0x80000000u >> 0; static const unsigned int PACKED_COLOR_MODE_BIT = 0x80000000u >> 1; static const unsigned int CAD_VIEW_MODE_BIT = 0x80000000u >> 2; uint32 flags( SAVE_VERTEX_NORMALS_BIT ); IdHelper id(*this, headerName); id.dos_ = &_dos; _dos.writeInt16( (int16) HEADER_OP ); _dos.writeInt16( length ); _dos.writeID( id ); _dos.writeInt32( version ); _dos.writeInt32( 0 ); // edit revision // TBD need platform-independent method to generate date/time string _dos.writeString( std::string(" "), 32 ); // date and time string for last rev _dos.writeInt16( 0 ); // next group id _dos.writeInt16( 0 ); // next LOD id _dos.writeInt16( 0 ); // next object id _dos.writeInt16( 0 ); // next face id _dos.writeInt16( 1 ); // unit multiplier _dos.writeInt8( units ); // coordinate units _dos.writeInt8( 0 ); // if TRUE, texwhite on new faces _dos.writeUInt32( flags ); // flags _dos.writeFill( sizeof( int32 ) * 6 ); // reserved _dos.writeInt32( 0 ); // projection _dos.writeFill( sizeof( int32 ) * 7 ); // reserved _dos.writeInt16( 0 ); // next DOF id _dos.writeInt16( 1 ); // vertex storage type, should always be 1 _dos.writeInt32( 100 ); // DB origin, 100=OpenFlight _dos.writeFloat64( 0. ); // SW corner X _dos.writeFloat64( 0. ); // SW corner Y _dos.writeFloat64( 0. ); // delta X _dos.writeFloat64( 0. ); // delta Y _dos.writeInt16( 0 ); // next sound id _dos.writeInt16( 0 ); // next path id _dos.writeFill( sizeof( int32 ) * 2 ); // reserved _dos.writeInt16( 0 ); // next clip id _dos.writeInt16( 0 ); // next text id _dos.writeInt16( 0 ); // next BSP id _dos.writeInt16( 0 ); // next switch id _dos.writeInt32( 0 ); // reserved _dos.writeFloat64( 0. ); // SW corner lat _dos.writeFloat64( 0. ); // SW corner lon _dos.writeFloat64( 0. ); // NE corner lat _dos.writeFloat64( 0. ); // NE corner lon _dos.writeFloat64( 0. ); // origin lat _dos.writeFloat64( 0. ); // origin lon _dos.writeFloat64( 0. ); // lambert upper lat _dos.writeFloat64( 0. ); // lambert upper lon _dos.writeInt16( 0 ); // next light source id _dos.writeInt16( 0 ); // next light point id _dos.writeInt16( 0 ); // next road id _dos.writeInt16( 0 ); // next CAT id _dos.writeFill( sizeof( int16 ) * 4 ); // reserved _dos.writeInt32( 0 ); // ellipsoid model, 0=WGS84 _dos.writeInt16( 0 ); // next adaptive id _dos.writeInt16( 0 ); // next curve id _dos.writeInt16( 0 ); // utm zone _dos.writeFill( 6 ); // reserved _dos.writeFloat64( 0. ); // delta z _dos.writeFloat64( 0. ); // radius _dos.writeInt16( 0 ); // next mesh id _dos.writeInt16( 0 ); // next light system id if (version >= 1580) { _dos.writeInt32( 0 ); // reserved _dos.writeFloat64( 0. ); // earth major axis for user defined ellipsoid _dos.writeFloat64( 0. ); // earth minor axis for user defined ellipsoid }}// Group flagsstatic const unsigned int FORWARD_ANIM = 0x80000000u >> 1;static const unsigned int SWING_ANIM = 0x80000000u >> 2;static const unsigned int BOUND_BOX_FOLLOW = 0x80000000u >> 3;static const unsigned int FREEZE_BOUND_BOX = 0x80000000u >> 4;static const unsigned int DEFAULT_PARENT = 0x80000000u >> 5;static const unsigned int BACKWARD_ANIM = 0x80000000u >> 6;//// Convenience routine for writing Group nodes that aren't animated//voidFltExportVisitor::writeGroup( const osg::Group& group ){ int32 flags = 0, loopCount = 0; float32 loopDuration = 0.0f, lastFrameDuration = 0.0f; writeGroup(group, flags, loopCount, loopDuration, lastFrameDuration);}voidFltExportVisitor::writeGroup( const osg::Group& group, int32 flags, int32 loopCount, float32 loopDuration, float32 lastFrameDuration) // <-- placeholder: ignored{ int16 length( 44 ); IdHelper id(*this, group.getName() ); _records->writeInt16( (int16) GROUP_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt16( 0 ); // Relative priority _records->writeInt16( 0 ); // Reserved _records->writeUInt32( flags ); _records->writeInt16( 0 ); // Special effect ID1 _records->writeInt16( 0 ); // Special effect ID2 _records->writeInt16( 0 ); // Significance _records->writeInt8( 0 ); // Layer code _records->writeInt8( 0 ); // Reserved _records->writeInt32( 0 ); // Reserved _records->writeInt32( loopCount ); _records->writeFloat32( loopDuration ); _records->writeFloat32( lastFrameDuration );}// // Since OpenFlight doesn't have 'Sequence' records---just Group records that// may, optionally, be animated---this routine sets the animation-related// parameters for a Group record and simply forwards to writeGroup()//voidFltExportVisitor::writeSequence( const osg::Sequence& sequence ){ int32 flags = 0, loopCount = 0; float32 loopDuration = 0.0f, lastFrameDuration = 0.0f; osg::Sequence::LoopMode mode; int firstChildDisplayed, lastChildDisplayed; sequence.getInterval(mode, firstChildDisplayed, lastChildDisplayed); if (firstChildDisplayed == 0) { flags |= FORWARD_ANIM; } else { flags &= ~FORWARD_ANIM; } if (mode == osg::Sequence::SWING) { flags |= SWING_ANIM; } else { flags &= ~SWING_ANIM; } // Do we loop infinitely, or only a certain number of times? float speedUp; int numReps; sequence.getDuration(speedUp, numReps); if (numReps != -1) { loopCount = numReps; } else { loopCount = 0; // == loop continuously } // Sum individual frame durations to get the total loopDuration for (unsigned int i = 0; i < sequence.getNumChildren(); ++i) { loopDuration += sequence.getTime(i); } lastFrameDuration = sequence.getLastFrameTime(); writeGroup(sequence, flags, loopCount, loopDuration, lastFrameDuration);}voidFltExportVisitor::writeObject( const osg::Group& group, osgSim::ObjectRecordData* ord ){ uint16 length( 28 ); IdHelper id(*this, group.getName() ); if (!ord) { std::string warning( "fltexp: writeObject has invalid ObjectRecordData." ); osg::notify( osg::WARN ) << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; } _records->writeInt16( (int16) OBJECT_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( ord->_flags ); _records->writeInt16( ord->_relativePriority ); _records->writeUInt16( ord->_transparency ); _records->writeUInt16( ord->_effectID1 ); _records->writeUInt16( ord->_effectID2 ); _records->writeUInt16( ord->_significance ); _records->writeUInt16( 0 ); // reserved}voidFltExportVisitor::writeDegreeOfFreedom( const osgSim::DOFTransform* dof ){ const osg::Matrix& invPut = dof->getInversePutMatrix(); // Origin of DOF coord sys osg::Vec3d origin( invPut.getTrans() ); osg::Vec3 xAxis( invPut(0,0), invPut(0,1), invPut(0,2) ); osg::Vec3 yAxis( invPut(1,0), invPut(1,1), invPut(1,2) ); // Reference point along DOF coord sys's X axis osg::Vec3d pointOnXAxis = origin + xAxis; // Reference point in DOF coord sys's X-Y plane osg::Vec3d pointInXYPlane = origin + yAxis; // Translations osg::Vec3d minTranslate( dof->getMinTranslate() ); osg::Vec3d maxTranslate( dof->getMaxTranslate() ); osg::Vec3d currTranslate( dof->getCurrentTranslate() ); osg::Vec3d incrTranslate( dof->getIncrementTranslate() ); // Rotations osg::Vec3d minHPR( dof->getMinHPR() ); osg::Vec3d maxHPR( dof->getMaxHPR() ); osg::Vec3d currHPR( dof->getCurrentHPR() ); osg::Vec3d incrHPR( dof->getIncrementHPR() ); // Scaling osg::Vec3d minScale( dof->getMinScale() ); osg::Vec3d maxScale( dof->getMaxScale() ); osg::Vec3d currScale( dof->getCurrentScale() ); osg::Vec3d incrScale( dof->getIncrementScale() ); uint16 length( 384 ); IdHelper id(*this, dof->getName() ); _records->writeInt16( (int16) DOF_OP ); _records->writeInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // 'Reserved' (unused) _records->writeVec3d( origin ); _records->writeVec3d( pointOnXAxis ); _records->writeVec3d( pointInXYPlane ); // Translations _records->writeFloat64( minTranslate.z() ); _records->writeFloat64( maxTranslate.z() ); _records->writeFloat64( currTranslate.z() ); _records->writeFloat64( incrTranslate.z() ); _records->writeFloat64( minTranslate.y() ); _records->writeFloat64( maxTranslate.y() ); _records->writeFloat64( currTranslate.y() ); _records->writeFloat64( incrTranslate.y() ); _records->writeFloat64( minTranslate.x() ); _records->writeFloat64( maxTranslate.x() ); _records->writeFloat64( currTranslate.x() ); _records->writeFloat64( incrTranslate.x() ); // Rotations: 0 = Yaw, 1 = Pitch, 2 = Roll _records->writeFloat64( osg::RadiansToDegrees(minHPR[1]) ); _records->writeFloat64( osg::RadiansToDegrees(maxHPR[1]) ); _records->writeFloat64( osg::RadiansToDegrees(currHPR[1]) ); _records->writeFloat64( osg::RadiansToDegrees(incrHPR[1]) ); _records->writeFloat64( osg::RadiansToDegrees(minHPR[2]) ); _records->writeFloat64( osg::RadiansToDegrees(maxHPR[2]) ); _records->writeFloat64( osg::RadiansToDegrees(currHPR[2]) ); _records->writeFloat64( osg::RadiansToDegrees(incrHPR[2]) ); _records->writeFloat64( osg::RadiansToDegrees(minHPR[0]) ); _records->writeFloat64( osg::RadiansToDegrees(maxHPR[0]) ); _records->writeFloat64( osg::RadiansToDegrees(currHPR[0]) ); _records->writeFloat64( osg::RadiansToDegrees(incrHPR[0]) ); // Scaling _records->writeFloat64( minScale.z() ); _records->writeFloat64( maxScale.z() ); _records->writeFloat64( currScale.z() ); _records->writeFloat64( incrScale.z() ); _records->writeFloat64( minScale.y() ); _records->writeFloat64( maxScale.y() ); _records->writeFloat64( currScale.y() ); _records->writeFloat64( incrScale.y() ); _records->writeFloat64( minScale.x() ); _records->writeFloat64( maxScale.x() ); _records->writeFloat64( currScale.x() ); _records->writeFloat64( incrScale.y() ); _records->writeInt32( dof->getLimitationFlags() ); // Constraint flags _records->writeInt32( 0 ); // 'Reserved' (unused)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -