📄 vertexpalettemanager.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 "VertexPaletteManager.h"#include "DataOutputStream.h"#include "Opcodes.h"#include "Utils.h"#include <osg/Notify>#include <osg/Geometry>#include <map>namespace flt{VertexPaletteManager::VertexPaletteManager( const ExportOptions& fltOpt ) : _fltOpt( fltOpt ), _currentSizeBytes( 8 ), _current( NULL ), _vertices( NULL ){}VertexPaletteManager::~VertexPaletteManager(){ if (!_verticesTempName.empty()) { // Delete our temp file. if (_verticesStr.is_open()) { osg::notify( osg::WARN ) << "fltexp: VertexPaletteManager destructor has an open temp file." << std::endl; // This should not happen. FltExportVisitor::complete should close // this file before we get to this destructor. return; } osg::notify( osg::INFO ) << "fltexp: Deleting temp file " << _verticesTempName << std::endl; FLTEXP_DELETEFILE( _verticesTempName.c_str() ); }}voidVertexPaletteManager::add( const osg::Geometry& geom ){ const osg::Array* v = geom.getVertexArray(); if (!v) { osg::notify( osg::WARN ) << "fltexp: Attempting to add NULL vertex array in VertexPaletteManager." << std::endl; return; } const osg::Array* c = geom.getColorArray(); const osg::Array* n = geom.getNormalArray(); const osg::Array* t = geom.getTexCoordArray( 0 ); const unsigned int size = v->getNumElements(); osg::ref_ptr< const osg::Vec3dArray > v3 = asVec3dArray( v, size ); osg::ref_ptr< const osg::Vec4Array > c4 = asVec4Array( c, size ); osg::ref_ptr< const osg::Vec3Array > n3 = asVec3Array( n, size ); osg::ref_ptr< const osg::Vec2Array > t2 = asVec2Array( t, size ); if (v && !v3) return; if (c && !c4) return; if (n && !n3) return; if (t && !t2) return; const bool cpv =( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX ); const bool npv =( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX ); add( v, v3.get(), c4.get(), n3.get(), t2.get(), cpv, npv );}voidVertexPaletteManager::add( const osg::Array* key, const osg::Vec3dArray* v, const osg::Vec4Array* c, const osg::Vec3Array* n, const osg::Vec2Array* t, bool colorPerVertex, bool normalPerVertex, bool allowSharing ){ bool needsInit( true ); if (allowSharing) { ArrayMap::iterator it = _arrayMap.find( key ); if (it != _arrayMap.end()) needsInit = false; _current = &( _arrayMap[ key ] ); } else { _current = &( _nonShared ); } if (needsInit) { _current->_byteStart = _currentSizeBytes; _current->_idxCount = v->size(); _current->_idxSizeBytes = recordSize( recordType( v, c, n, t ) ); _currentSizeBytes += ( _current->_idxSizeBytes * _current->_idxCount ); // Next we'll write the vertex palette record data. But, // if we don't have a DataOutputStream yet, open the temp file. if (!_vertices) { _verticesTempName = _fltOpt.getTempDir() + "/ofw_temp_vertices"; _verticesStr.open( _verticesTempName.c_str(), std::ios::out | std::ios::binary ); _vertices = new DataOutputStream( _verticesStr.rdbuf(), _fltOpt.getValidateOnly() ); } writeRecords( v, c, n, t, colorPerVertex, normalPerVertex ); }}unsigned intVertexPaletteManager::byteOffset( unsigned int idx ) const{ if (!_current) { osg::notify( osg::WARN ) << "fltexp: No current vertex array in VertexPaletteManager." << std::endl; return 4; } if (idx >= _current->_idxCount) { osg::notify( osg::WARN ) << "fltexp: Index out of range in VertexPaletteManager." << std::endl; return 4; } return( _current->_byteStart + (_current->_idxSizeBytes * idx) );}voidVertexPaletteManager::write( DataOutputStream& dos ) const{ if (_currentSizeBytes == 8) // Empty palette. Don't write anything. return; dos.writeInt16( (int16) VERTEX_PALETTE_OP ); dos.writeUInt16( 8 ); dos.writeInt32( _currentSizeBytes ); // Close the temp file. We're done writing new data to it. _verticesStr.close(); // Open that temp file again, this time for reading. // Then copy to dos. char buf; osgDB::ifstream vertIn; vertIn.open( _verticesTempName.c_str(), std::ios::in | std::ios::binary ); while (!vertIn.eof() ) { vertIn.read( &buf, 1 ); if (vertIn.good()) dos << buf; } vertIn.close();}VertexPaletteManager::PaletteRecordTypeVertexPaletteManager::recordType( const osg::Array* v, const osg::Array* c, const osg::Array* n, const osg::Array* t ){ if (t) { // Texture coordinates if (n) return VERTEX_CNT; else return VERTEX_CT; } else { // No texture coordinates if (n) return VERTEX_CN; else return VERTEX_C; }}unsigned intVertexPaletteManager::recordSize( PaletteRecordType recType ){ switch (recType) { case VERTEX_C: return 40; break; case VERTEX_CN: return (_fltOpt.getFlightFileVersionNumber() > ExportOptions::VERSION_15_7) ? 56 : 52; break; case VERTEX_CT: return 48; break; case VERTEX_CNT: return 64; break; default: return 0; }}voidVertexPaletteManager::writeRecords( const osg::Vec3dArray* v, const osg::Vec4Array* c, const osg::Vec3Array* n, const osg::Vec2Array* t, bool colorPerVertex, bool normalPerVertex ){ const PaletteRecordType recType = recordType( v, c, n, t ); const int16 sizeBytes = recordSize( recType ); int16 opcode; switch( recType ) { case VERTEX_C: opcode = VERTEX_C_OP; break; case VERTEX_CN: opcode = VERTEX_CN_OP; if (!n) osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no normal array." << std::endl; break; case VERTEX_CNT: opcode = VERTEX_CNT_OP; if (!n) osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no normal array." << std::endl; if (!t) osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; break; case VERTEX_CT: opcode = VERTEX_CT_OP; if (!t) osg::notify( osg::WARN ) << "fltexp: VPM::writeRecords: no tex coord array." << std::endl; break; } enum FlagBits { START_HARD_EDGE = (0x8000 >> 0), NORMAL_FROZEN = (0x8000 >> 1), NO_COLOR = (0x8000 >> 2), PACKED_COLOR = (0x8000 >> 3) }; uint32 flags( NO_COLOR ); if (colorPerVertex) flags = PACKED_COLOR; size_t idx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -