📄 expgeometryrecords.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 "DataOutputStream.h"#include "Opcodes.h"#include "MaterialPaletteManager.h"#include "TexturePaletteManager.h"#include "VertexPaletteManager.h"#include <osg/CullFace>#include <osg/BlendFunc>#include <osg/Geometry>#include <osg/Geode>#include <osg/Billboard>#include <osg/io_utils>#include <osg/Material>#include <osg/Texture2D>#include <sstream>namespace flt{// Bit flags for multitexturingstatic unsigned int LAYER_1( 0x80000000 >> 0 );static unsigned int LAYER_2( 0x80000000 >> 1 );static unsigned int LAYER_3( 0x80000000 >> 2 );static unsigned int LAYER_4( 0x80000000 >> 3 );static unsigned int LAYER_5( 0x80000000 >> 4 );static unsigned int LAYER_6( 0x80000000 >> 5 );static unsigned int LAYER_7( 0x80000000 >> 6 );boolFltExportVisitor::isLit( const osg::Geometry& geom ) const{ const osg::StateSet* ss = getCurrentStateSet(); if ( ss->getMode( GL_LIGHTING ) & osg::StateAttribute::ON ) return true; else return false; //( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX );}boolFltExportVisitor::isTextured( int unit, const osg::Geometry& geom ) const{ const osg::StateSet* ss = getCurrentStateSet(); bool texOn( ss->getTextureMode( unit, GL_TEXTURE_2D ) & osg::StateAttribute::ON ); bool hasCoords( geom.getTexCoordArray( unit ) != NULL ); return( texOn && hasCoords );}boolFltExportVisitor::isMesh( const GLenum mode ) const{ return( (mode == GL_TRIANGLE_STRIP) || (mode == GL_TRIANGLE_FAN) || (mode == GL_QUAD_STRIP) );}boolFltExportVisitor::atLeastOneFace( const osg::Geometry& geom ) const{ // Return true if at least one PrimitiveSet mode will use a Face record. unsigned int jdx; for (jdx=0; jdx < geom.getNumPrimitiveSets(); jdx++) { const osg::PrimitiveSet* prim = geom.getPrimitiveSet( jdx ); if( !isMesh( prim->getMode() ) ) return true; } // All PrimitiveSet modes will use Mesh records. return false;}boolFltExportVisitor::atLeastOneMesh( const osg::Geometry& geom ) const{ // Return true if at least one PrimitiveSet mode will use a Mesh record. unsigned int jdx; for (jdx=0; jdx < geom.getNumPrimitiveSets(); jdx++) { const osg::PrimitiveSet* prim = geom.getPrimitiveSet( jdx ); if( isMesh( prim->getMode() ) ) return true; } // All PrimitiveSet modes will use Face records. return false;}voidFltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode ){ enum DrawMode { SOLID_BACKFACE = 0, SOLID_NO_BACKFACE = 1, WIREFRAME_CLOSED = 2, WIREFRAME_NOT_CLOSED = 3, SURROUND_ALTERNATE_COLOR = 4, OMNIDIRECTIONAL_LIGHT = 8, UNIDIRECTIONAL_LIGHT = 9, BIDIRECTIONAL_LIGHT = 10 }; enum TemplateMode { FIXED_NO_ALPHA_BLENDING = 0, FIXED_ALPHA_BLENDING = 1, AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2, POINT_ROTATE_WITH_ALPHA_BLENDING = 4 }; const unsigned int TERRAIN_BIT = 0x80000000u >> 0; const unsigned int NO_COLOR_BIT = 0x80000000u >> 1; const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2; const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3; const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout const unsigned int HIDDEN_BIT = 0x80000000u >> 5; const unsigned int ROOFLINE_BIT = 0x80000000u >> 6; uint32 flags( PACKED_COLOR_BIT ); if (geode.getNodeMask() == 0) flags |= HIDDEN_BIT; osg::StateSet const* ss = getCurrentStateSet(); enum LightMode { FACE_COLOR = 0, VERTEX_COLOR = 1, FACE_COLOR_LIGHTING = 2, VERTEX_COLOR_LIGHTING = 3 }; int8 lightMode; osg::Vec4 packedColorRaw( 1., 1., 1., 1. ); uint16 transparency( 0 ); if (geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) { if( isLit( geom ) ) lightMode = VERTEX_COLOR_LIGHTING; else lightMode = VERTEX_COLOR; } else { const osg::Vec4Array* c = dynamic_cast<const osg::Vec4Array*>( geom.getColorArray() ); if (c && (c->size() > 0)) { packedColorRaw = (*c)[0]; transparency = flt::uint16((1. - packedColorRaw[3]) * (double)0xffff); } if ( isLit( geom ) ) lightMode = FACE_COLOR_LIGHTING; else lightMode = FACE_COLOR; } uint32 packedColor; packedColor = (int)(packedColorRaw[3]*255) << 24 | (int)(packedColorRaw[2]*255) << 16 | (int)(packedColorRaw[1]*255) << 8 | (int)(packedColorRaw[0]*255); int8 drawType; switch( mode ) { case GL_POINTS: { std::string warning( "fltexp: GL_POINTS not supported in FLT export." ); osg::notify( osg::WARN ) << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; break; } case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: case GL_QUAD_STRIP: { std::string warning( "fltexp: Wrong mode in Face record." ); osg::notify( osg::WARN ) << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); return; break; } case GL_LINES: case GL_LINE_STRIP: drawType = WIREFRAME_NOT_CLOSED; break; case GL_LINE_LOOP: drawType = WIREFRAME_CLOSED; break; case GL_TRIANGLES: case GL_QUADS: case GL_POLYGON: { // Default to no facet culling drawType = SOLID_NO_BACKFACE; // If facet-culling isn't *dis*abled, check whether the CullFace mode is BACK if (ss->getMode(GL_CULL_FACE) & osg::StateAttribute::ON) { osg::CullFace const* cullFace = static_cast<osg::CullFace const*>( ss->getAttribute(osg::StateAttribute::CULLFACE) ); if( cullFace->getMode() == osg::CullFace::BACK ) drawType = SOLID_BACKFACE; // Note: OpenFlt can't handle FRONT or FRONT_AND_BACK settings, so ignore these(??) } break; } } // Determine the material properties for the face int16 materialIndex( -1 ); if (isLit( geom )) { osg::Material const* currMaterial = static_cast<osg::Material const*>( ss->getAttribute(osg::StateAttribute::MATERIAL) ); materialIndex = _materialPalette->add(currMaterial); } // Get base texture int16 textureIndex( -1 ); if (isTextured( 0, geom )) { const osg::Texture2D* texture = static_cast<const osg::Texture2D*>( ss->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ) ); if (texture != NULL) textureIndex = _texturePalette->add( 0, texture ); else { std::string warning( "fltexp: Face is textured, but Texture2D StateAttribute is NULL." ); osg::notify( osg::WARN ) << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); } } // Set the appropriate template mode based // on blending or Billboarding. TemplateMode templateMode( FIXED_NO_ALPHA_BLENDING ); const osg::Billboard* bb = dynamic_cast< const osg::Billboard* >( &geode ); if (bb != NULL) { if( bb->getMode() == osg::Billboard::AXIAL_ROT ) templateMode = AXIAL_ROTATE_WITH_ALPHA_BLENDING; else templateMode = POINT_ROTATE_WITH_ALPHA_BLENDING; } else if ( ss->getMode( GL_BLEND ) & osg::StateAttribute::ON ) { const osg::BlendFunc* bf = static_cast<const osg::BlendFunc*>( ss->getAttribute(osg::StateAttribute::BLENDFUNC) ); if( (bf->getSource() == osg::BlendFunc::SRC_ALPHA) && (bf->getDestination() == osg::BlendFunc::ONE_MINUS_SRC_ALPHA) ) templateMode = FIXED_ALPHA_BLENDING; } uint16 length( 80 ); IdHelper id( *this, geode.getName() ); _records->writeInt16( (int16) FACE_OP ); _records->writeUInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // IR color code _records->writeInt16( 0 ); // Relative priority _records->writeInt8( drawType ); // Draw type _records->writeInt8( 0 ); // Texture white _records->writeInt16( -1 ); // Color name index _records->writeInt16( -1 ); // Alternate color name index _records->writeInt8( 0 ); // Reserved _records->writeInt8( templateMode ); // Template (billboard) _records->writeInt16( -1 ); // Detail texture pattern index _records->writeInt16( textureIndex ); // Texture pattern index _records->writeInt16( materialIndex ); // Material index _records->writeInt16( 0 ); // Surface material code _records->writeInt16( 0 ); // Feature ID _records->writeInt32( 0 ); // IR material code _records->writeUInt16( transparency ); // Transparency _records->writeInt8( 0 ); // LOD generation control _records->writeInt8( 0 ); // Line style index _records->writeUInt32( flags ); // Flags _records->writeInt8( lightMode ); // Light mode _records->writeFill( 7 ); // Reserved _records->writeUInt32( packedColor ); // Packed color, primary _records->writeUInt32( 0x00ffffff ); // Packed color, alternate _records->writeInt16( -1 ); // Texture mapping index _records->writeInt16( 0 ); // Reserved _records->writeInt32( -1 ); // Primary color index _records->writeInt32( -1 ); // Alternate color index // Next four bytes: // 15.8: two 2-byte "reserved" fields // 15.9: one 4-byte "reserved" field _records->writeInt16( 0 ); // Reserved _records->writeInt16( -1 ); // Shader index}voidFltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom ){ enum DrawMode { SOLID_BACKFACE = 0, SOLID_NO_BACKFACE = 1, WIREFRAME_CLOSED = 2, WIREFRAME_NOT_CLOSED = 3, SURROUND_ALTERNATE_COLOR = 4, OMNIDIRECTIONAL_LIGHT = 8, UNIDIRECTIONAL_LIGHT = 9, BIDIRECTIONAL_LIGHT = 10 }; enum TemplateMode { FIXED_NO_ALPHA_BLENDING = 0, FIXED_ALPHA_BLENDING = 1, AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2, POINT_ROTATE_WITH_ALPHA_BLENDING = 4 }; const unsigned int TERRAIN_BIT = 0x80000000u >> 0; const unsigned int NO_COLOR_BIT = 0x80000000u >> 1; const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2; const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3; const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout const unsigned int HIDDEN_BIT = 0x80000000u >> 5; const unsigned int ROOFLINE_BIT = 0x80000000u >> 6; uint32 flags( PACKED_COLOR_BIT ); if (geode.getNodeMask() == 0) flags |= HIDDEN_BIT; enum LightMode { FACE_COLOR = 0, VERTEX_COLOR = 1, FACE_COLOR_LIGHTING = 2, VERTEX_COLOR_LIGHTING = 3 }; int8 lightMode; osg::Vec4 packedColorRaw( 1., 1., 1., 1. ); uint16 transparency( 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -