From aa725e899aa695adff16329382b6c5956f4183b3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 1 Nov 2001 16:35:26 +0000 Subject: [PATCH] Updates to the flt loader from Brede Johansen. --- src/osgPlugins/flt/ColorPaletteRecord.cpp | 13 +- src/osgPlugins/flt/DofRecord.h | 2 +- src/osgPlugins/flt/ExtensionRecord.h | 2 +- src/osgPlugins/flt/FaceRecord.cpp | 2 +- src/osgPlugins/flt/FaceRecord.h | 8 +- src/osgPlugins/flt/FltFile.cpp | 152 +-- src/osgPlugins/flt/FltFile.h | 63 +- src/osgPlugins/flt/GeoSetBuilder.cpp | 884 ++++++++---------- src/osgPlugins/flt/GeoSetBuilder.h | 288 ++---- src/osgPlugins/flt/GroupRecord.h | 2 +- src/osgPlugins/flt/HeaderRecord.cpp | 2 + src/osgPlugins/flt/HeaderRecord.h | 2 +- src/osgPlugins/flt/Input.cpp | 4 +- src/osgPlugins/flt/LodRecord.h | 4 +- src/osgPlugins/flt/MaterialPaletteRecord.h | 2 +- src/osgPlugins/flt/ObjectRecord.h | 40 +- src/osgPlugins/flt/OldMaterialPaletteRecord.h | 2 +- src/osgPlugins/flt/OldVertexRecords.h | 6 +- src/osgPlugins/flt/Pool.cpp | 73 +- src/osgPlugins/flt/Pool.h | 115 +-- src/osgPlugins/flt/ReaderWriterFLT.cpp | 10 +- src/osgPlugins/flt/Record.h | 14 +- src/osgPlugins/flt/Registry.cpp | 142 +-- src/osgPlugins/flt/Registry.h | 51 +- src/osgPlugins/flt/SwitchRecord.h | 2 +- .../flt/TextureMappingPaletteRecord.h | 2 +- src/osgPlugins/flt/TexturePaletteRecord.h | 2 +- src/osgPlugins/flt/TransformationRecords.h | 18 +- src/osgPlugins/flt/VertexPoolRecords.h | 10 +- src/osgPlugins/flt/flt.h | 2 +- src/osgPlugins/flt/flt2osg.cpp | 407 ++++---- src/osgPlugins/flt/flt2osg.h | 94 +- 32 files changed, 1061 insertions(+), 1359 deletions(-) diff --git a/src/osgPlugins/flt/ColorPaletteRecord.cpp b/src/osgPlugins/flt/ColorPaletteRecord.cpp index 425660cab..c4210440d 100644 --- a/src/osgPlugins/flt/ColorPaletteRecord.cpp +++ b/src/osgPlugins/flt/ColorPaletteRecord.cpp @@ -29,17 +29,10 @@ ColorPaletteRecord::~ColorPaletteRecord() // virtual void ColorPaletteRecord::endian() { - // note, sizeof returns unsigned int, while getSize() etc returns - // int, this correctly generates a warning when comparisons are made - // under Linux. This really needs to be fixed so getSize() returns - // an unsigned int. I won't do it now as it may well break code - // which I don't fully understand. I've made the hacky use of an - // (int) cast to fix the warning, I don't think this will cause an - // problems. RO August 2001. - if (getSize() > (int) sizeof(SOldColorPalette)) + if (getSize() > sizeof(SOldColorPalette)) { SColorPalette* pSColor = (SColorPalette*)getData(); - int nOffset = sizeof(SColorPalette); + size_t nOffset = sizeof(SColorPalette); if (nOffset < getSize()) { @@ -58,7 +51,7 @@ void ColorPaletteRecord::endian() else // version 11, 12 & 13 { SOldColorPalette* pSColor = (SOldColorPalette*)getData(); - unsigned int i; + size_t i; for (i=0; i < sizeof(pSColor->Colors)/sizeof(pSColor->Colors[0]); i++) { ENDIAN( pSColor->Colors[i]._red ); diff --git a/src/osgPlugins/flt/DofRecord.h b/src/osgPlugins/flt/DofRecord.h index 605012724..d876f5b07 100644 --- a/src/osgPlugins/flt/DofRecord.h +++ b/src/osgPlugins/flt/DofRecord.h @@ -63,7 +63,7 @@ class DofRecord : public PrimNodeRecord virtual Record* clone() const { return new DofRecord(); } virtual const char* className() const { return "DofRecord"; } virtual int classOpcode() const { return DOF_OP; } - virtual int sizeofData() const { return sizeof(SDegreeOfFreedom); } + virtual size_t sizeofData() const { return sizeof(SDegreeOfFreedom); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/ExtensionRecord.h b/src/osgPlugins/flt/ExtensionRecord.h index ed07b7352..84c92fa3b 100644 --- a/src/osgPlugins/flt/ExtensionRecord.h +++ b/src/osgPlugins/flt/ExtensionRecord.h @@ -43,7 +43,7 @@ class ExtensionRecord : public PrimNodeRecord virtual Record* clone() const { return new ExtensionRecord(); } virtual const char* className() const { return "ExtensionRecord"; } virtual int classOpcode() const { return EXTENSION_OP; } - virtual int sizeofData() const { return sizeof(SExtension); } + virtual size_t sizeofData() const { return sizeof(SExtension); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/FaceRecord.cpp b/src/osgPlugins/flt/FaceRecord.cpp index be1dc9db2..91f554144 100644 --- a/src/osgPlugins/flt/FaceRecord.cpp +++ b/src/osgPlugins/flt/FaceRecord.cpp @@ -69,7 +69,7 @@ void FaceRecord::endian() ENDIAN( pSFace->wTransparency ); // Added after version 13 - if (getSize() >= sizeof(SFace)) + if (Registry::instance()->getVersion() > 13) { ENDIAN( pSFace->dwFlags ); // ENDIAN( pSFace->PrimaryPackedColor ); diff --git a/src/osgPlugins/flt/FaceRecord.h b/src/osgPlugins/flt/FaceRecord.h index 68f74d15e..cb00d23db 100644 --- a/src/osgPlugins/flt/FaceRecord.h +++ b/src/osgPlugins/flt/FaceRecord.h @@ -117,7 +117,7 @@ class FaceRecord : public PrimNodeRecord virtual Record* clone() const { return new FaceRecord(); } virtual const char* className() const { return "FaceRecord"; } virtual int classOpcode() const { return FACE_OP; } - virtual int sizeofData() const { return sizeof(SFace); } + virtual size_t sizeofData() const { return sizeof(SFace); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -162,7 +162,7 @@ class VertexListRecord : public PrimNodeRecord virtual Record* clone() const { return new VertexListRecord(); } virtual const char* className() const { return "VertexListRecord"; } virtual int classOpcode() const { return VERTEX_LIST_OP; } - virtual int sizeofData() const { return sizeof(SSingleVertexList); } + virtual size_t sizeofData() const { return sizeof(SSingleVertexList); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -200,7 +200,7 @@ class MorphVertexListRecord : public PrimNodeRecord virtual Record* clone() const { return new MorphVertexListRecord(); } virtual const char* className() const { return "MorphVertexListRecord"; } virtual int classOpcode() const { return MORPH_VERTEX_LIST_OP; } - virtual int sizeofData() const { return sizeof(SMorphVertexList); } + virtual size_t sizeofData() const { return sizeof(SMorphVertexList); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -240,7 +240,7 @@ class VectorRecord : public AncillaryRecord virtual Record* clone() const { return new VectorRecord(); } virtual const char* className() const { return "VectorRecord"; } virtual int classOpcode() const { return VECTOR_OP; } - virtual int sizeofData() const { return sizeof(SVector); } + virtual size_t sizeofData() const { return sizeof(SVector); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/FltFile.cpp b/src/osgPlugins/flt/FltFile.cpp index 8b8eab8bd..e9c7adcca 100644 --- a/src/osgPlugins/flt/FltFile.cpp +++ b/src/osgPlugins/flt/FltFile.cpp @@ -1,11 +1,3 @@ -// FltFile.cpp - -#include -#include -#include - -#include - #include "FltFile.h" #include "Registry.h" #include "Record.h" @@ -14,32 +6,63 @@ #include "flt2osg.h" // ConvertFromFLT #include "Input.h" +#include +#include +#include + +#include + +#include + + using namespace flt; -FltFile::FltFile( -ColorPool* pColorPool, -TexturePool* pTexturePool, -MaterialPool* pMaterialPool) +FltFile::FltFile( + ColorPool* pColorPool, + TexturePool* pTexturePool, + MaterialPool* pMaterialPool) { - _pColorPool = pColorPool; + _pHeaderRecord = NULL; + + if (pColorPool) + { + // use external color palette, ignore internal + _useColorPalette = false; + setColorPool( pColorPool ); + } + else + { + // use internal color palette + _useColorPalette = true; + setColorPool( new ColorPool ); + } if (pTexturePool) - _pTexturePool = pTexturePool; + { + // use external texture palette, ignore internal + _useTexturePalette = false; + setTexturePool( pTexturePool ); + } else - _pTexturePool = &_texturePool; + { + // use internal texture palette + _useTexturePalette = true; + setTexturePool( new TexturePool ); + } if (pMaterialPool) - _pMaterialPool = pMaterialPool; + { + // use external material palette, ignore internal + _useMaterialPalette = false; + setMaterialPool( pMaterialPool ); + } else - _pMaterialPool = &_materialPool; - - _pHeaderRecord = NULL; -} - - -FltFile::~FltFile() -{ + { + // use internal material palette + _useMaterialPalette = true; + setMaterialPool( new MaterialPool ); + } } @@ -116,62 +139,63 @@ Record* FltFile::readFile(const std::string& fileName) } -class ReadExternal : public RecordVisitor -{ -public: - ReadExternal(FltFile* fltFile) - { - _fltFile = fltFile; - setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN); - } - #define REGISTER_FLT 1 - virtual void apply(ExternalRecord& rec) - { - SExternalReference* pSExternal = (SExternalReference*)rec.getData(); - - if (pSExternal) +class ReadExternal : public RecordVisitor +{ + public: + ReadExternal(FltFile* fltFile) { - FltFile* flt = NULL; - ColorPool* pColorPool = NULL; - TexturePool* pTexturePool = NULL; - MaterialPool* pMaterialPool = NULL; - std::string filename(pSExternal->szPath); + _parentFltFile = fltFile; + setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN); + } - osg::notify(osg::INFO) << "External=" << filename << endl; + virtual void apply(ExternalRecord& rec) + { + SExternalReference* pSExternal = (SExternalReference*)rec.getData(); - if (_fltFile && _fltFile->getFlightVersion() > 13) + if (pSExternal) { - if (pSExternal->diFlags & BIT0) - pColorPool = _fltFile->getColorPool(); + FltFile* flt = NULL; + ColorPool* pColorPool = NULL; + TexturePool* pTexturePool = NULL; + MaterialPool* pMaterialPool = NULL; + std::string filename(pSExternal->szPath); - if (pSExternal->diFlags & BIT2) - pTexturePool = _fltFile->getTexturePool(); + osg::notify(osg::INFO) << "External=" << filename << endl; - if (pSExternal->diFlags & BIT1) - pMaterialPool = _fltFile->getMaterialPool(); - } + if (_parentFltFile && (_parentFltFile->getFlightVersion() > 13)) + { + if (pSExternal->diFlags & BIT0) + pColorPool = _parentFltFile->getColorPool(); + + if (pSExternal->diFlags & BIT2) + pTexturePool = _parentFltFile->getTexturePool(); + + if (pSExternal->diFlags & BIT1) + pMaterialPool = _parentFltFile->getMaterialPool(); + } #if REGISTER_FLT - flt = Registry::instance()->getFltFile(filename); - if (flt == NULL) - { + flt = Registry::instance()->getFltFile(filename); + if (flt == NULL) + { + flt = new FltFile(pColorPool, pTexturePool, pMaterialPool); + flt->readModel(filename); + } + Registry::instance()->addFltFile(filename, flt); +#else flt = new FltFile(pColorPool, pTexturePool, pMaterialPool); flt->readModel(filename); - } - Registry::instance()->addFltFile(filename, flt); -#else - flt = new FltFile(pColorPool, pTexturePool, pMaterialPool); - flt->readModel(filename); #endif - rec.setExternal(flt); + rec.setExternal(flt); + } } - } -public: - FltFile* _fltFile; + public: + + FltFile* _parentFltFile; }; diff --git a/src/osgPlugins/flt/FltFile.h b/src/osgPlugins/flt/FltFile.h index c02ef401b..4202324e9 100644 --- a/src/osgPlugins/flt/FltFile.h +++ b/src/osgPlugins/flt/FltFile.h @@ -20,45 +20,50 @@ class Record; class FltFile : public osg::Referenced { -public: - FltFile( - ColorPool* pColorPool = NULL, - TexturePool* pTexturePool = NULL, - MaterialPool* pMaterialPool = NULL); - virtual ~FltFile(); + public: + FltFile( + ColorPool* pColorPool = NULL, + TexturePool* pTexturePool = NULL, + MaterialPool* pMaterialPool = NULL); - virtual osg::Object* readObject(const std::string& fileName); - virtual osg::Node* readNode(const std::string& fileName); - osg::Node* convert(); - Record* getHeaderRecord() { return _pHeaderRecord; } - Record* readModel(const std::string& fileName); + virtual osg::Object* readObject(const std::string& fileName); + virtual osg::Node* readNode(const std::string& fileName); + osg::Node* convert(); + Record* getHeaderRecord() { return _pHeaderRecord; } + Record* readModel(const std::string& fileName); - ColorPool* getColorPool() { return _pColorPool; } - TexturePool* getTexturePool() { return _pTexturePool; } - MaterialPool* getMaterialPool() { return _pMaterialPool; } + ColorPool* getColorPool() { return _colorPool.get(); } + TexturePool* getTexturePool() { return _texturePool.get(); } + MaterialPool* getMaterialPool() { return _materialPool.get(); } - void useLocalColorPool() { _pColorPool = &_colorPool; } - void useLocalTexturePool() { _pTexturePool = &_texturePool; } - void useLocalMaterialPool() { _pMaterialPool = &_materialPool; } + void setColorPool(ColorPool* colorPool) { _colorPool = colorPool; } + void setTexturePool(TexturePool* texturePool) { _texturePool = texturePool; } + void setMaterialPool(MaterialPool* materialPool){ _materialPool = materialPool; } - int getFlightVersion(); + inline const bool useColorPalette() const { return _useColorPalette; } + inline const bool useTexturePalette() const { return _useTexturePalette; } + inline const bool useMaterialPalette() const { return _useMaterialPalette; } -protected: + int getFlightVersion(); - Record* readFile(const std::string& fileName); - void readExternals(Record* pRec); + protected: -private: + virtual ~FltFile() {} - Record* _pHeaderRecord; + Record* readFile(const std::string& fileName); + void readExternals(Record* pRec); - ColorPool _colorPool; - TexturePool _texturePool; - MaterialPool _materialPool; + private: - ColorPool* _pColorPool; - TexturePool* _pTexturePool; - MaterialPool* _pMaterialPool; + Record* _pHeaderRecord; + + bool _useColorPalette; + bool _useTexturePalette; + bool _useMaterialPalette; + + osg::ref_ptr _colorPool; + osg::ref_ptr _texturePool; + osg::ref_ptr _materialPool; }; diff --git a/src/osgPlugins/flt/GeoSetBuilder.cpp b/src/osgPlugins/flt/GeoSetBuilder.cpp index cb66448eb..061a87ab9 100644 --- a/src/osgPlugins/flt/GeoSetBuilder.cpp +++ b/src/osgPlugins/flt/GeoSetBuilder.cpp @@ -16,8 +16,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -31,6 +32,328 @@ using namespace flt; + +//////////////////////////////////////////////////////////////////// +// +// TmpGeoSet +// +//////////////////////////////////////////////////////////////////// + +// GeoSet with dynamic vertex size. + +TmpGeoSet::TmpGeoSet(FltFile* pFltFile) +{ + _geoSet = new osg::GeoSet; + _geoSet->setStateSet( new osg::StateSet ); + + _colorPool = pFltFile->getColorPool(); + _texturePool = pFltFile->getTexturePool(); + _materialPool = pFltFile->getMaterialPool(); +} + + +osg::GeoSet* TmpGeoSet::createOsgGeoSet() +{ + int prims = _primLenList.size(); + int indices = _vertexRecList.size(); + + if (prims==0 || indices==0) + return NULL; + + osg::GeoSet* gset = getGeoSet(); + + gset->setNumPrims(prims); + + // prim lengths + switch( gset->getPrimType() ) + { + case osg::GeoSet::QUAD_STRIP : + case osg::GeoSet::FLAT_TRIANGLE_FAN : + case osg::GeoSet::TRIANGLE_FAN : + case osg::GeoSet::LINE_LOOP : + case osg::GeoSet::LINE_STRIP : + case osg::GeoSet::FLAT_LINE_STRIP : + case osg::GeoSet::TRIANGLE_STRIP : + case osg::GeoSet::FLAT_TRIANGLE_STRIP : + case osg::GeoSet::POLYGON : + { + int *lens = new int[prims]; + gset->setPrimLengths( lens ); + for (int n=0; n < prims; n++) + lens[n] = _primLenList[n]; + } + break; + } + + // create osg compatible buffers + gset->setCoords(new osg::Vec3[indices]); + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + gset->setColors(new osg::Vec4[indices]); + + if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + gset->setNormals(new osg::Vec3[indices]); + + if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + gset->setTextureCoords(new osg::Vec2[indices]); + + // Copy vertices across + { + int index; + VertexRecList::iterator itr; + for(index=0, itr=_vertexRecList.begin(); + itr!=_vertexRecList.end(); + ++index, ++itr) + { + setVertex(gset, index, itr->get()); + } + } + + return gset; +} + + +void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex) +{ + osg::Vec3* coords = gset->getCoords(); + osg::Vec4* colors = gset->getColors(); + osg::Vec3* normals = gset->getNormals(); + osg::Vec2* texuv = gset->getTextureCoords(); + + switch(vertex->getOpcode()) + { + case VERTEX_C_OP: + { + SVertex* pVert = (SVertex*)vertex->getData(); + + coords[index].set( + (float)pVert->Coord.x(), + (float)pVert->Coord.y(), + (float)pVert->Coord.z()); + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + if (pVert->swFlags & V_NO_COLOR_BIT) + colors[index] = osg::Vec4(1,1,1,1); + else + { + if (pVert->swFlags & V_PACKED_COLOR_BIT) + colors[index] = pVert->PackedColor.get(); + else + { + ColorPool* pColorPool = _colorPool.get(); + colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); + } + } + } + } + break; + + case VERTEX_CN_OP: + { + SNormalVertex* pVert = (SNormalVertex*)vertex->getData(); + + coords[index].set( + (float)pVert->Coord.x(), + (float)pVert->Coord.y(), + (float)pVert->Coord.z()); + + if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + { + normals[index].set( + (float)pVert->Normal.x(), + (float)pVert->Normal.y(), + (float)pVert->Normal.z()); + normals[index].normalize(); + } + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + if (pVert->swFlags & V_NO_COLOR_BIT) + colors[index] = osg::Vec4(1,1,1,1); + else + { + if (pVert->swFlags & V_PACKED_COLOR_BIT) + colors[index] = pVert->PackedColor.get(); + else + { + ColorPool* pColorPool = _colorPool.get(); + colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); + } + } + } + } + break; + + case VERTEX_CNT_OP: + { + SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData(); + + coords[index].set( + (float)pVert->Coord.x(), + (float)pVert->Coord.y(), + (float)pVert->Coord.z()); + + if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + { + normals[index].set( + (float)pVert->Normal.x(), + (float)pVert->Normal.y(), + (float)pVert->Normal.z()); + normals[index].normalize(); + } + + if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + { + texuv[index].set( + (float)pVert->Texture.x(), + (float)pVert->Texture.y()); + } + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + if (pVert->swFlags & V_NO_COLOR_BIT) + colors[index] = osg::Vec4(1,1,1,1); + else + { + if (pVert->swFlags & V_PACKED_COLOR_BIT) + colors[index] = pVert->PackedColor.get(); + else + { + ColorPool* pColorPool = _colorPool.get(); + colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); + } + } + } + } + break; + + case VERTEX_CT_OP: + { + STextureVertex* pVert = (STextureVertex*)vertex->getData(); + + coords[index].set( + (float)pVert->Coord.x(), + (float)pVert->Coord.y(), + (float)pVert->Coord.z()); + + if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + { + texuv[index].set( + (float)pVert->Texture.x(), + (float)pVert->Texture.y()); + } + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + osg::Vec4* colors = gset->getColors(); + + if (pVert->swFlags & V_NO_COLOR_BIT) + colors[index] = osg::Vec4(1,1,1,1); + else + { + if (pVert->swFlags & V_PACKED_COLOR_BIT) + colors[index] = pVert->PackedColor.get(); + else + { + ColorPool* pColorPool = _colorPool.get(); + colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); + } + } + } + } + break; + + case OLD_VERTEX_OP: + { + SOldVertex* pVert = (SOldVertex*)vertex->getData(); + + coords[index].set( + (float)pVert->v[0], + (float)pVert->v[1], + (float)pVert->v[2]); + + if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (vertex->getSize() >= sizeof(SOldVertex))) + { + texuv[index].set( + (float)pVert->t[0], + (float)pVert->t[1]); + } + } + break; + + case OLD_VERTEX_COLOR_OP: + { + SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData(); + + coords[index].set( + (float)pVert->v[0], + (float)pVert->v[1], + (float)pVert->v[2]); + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + osg::Vec4* colors = gset->getColors(); + ColorPool* pColorPool = _colorPool.get(); + if (pColorPool) + colors[index] = pColorPool->getColor(pVert->color_index); + else + colors[index] = osg::Vec4(1,1,1,1); + } + + if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (vertex->getSize() >= sizeof(SOldVertexColor))) + { + texuv[index].set( + (float)pVert->t[0], + (float)pVert->t[1]); + } + } + break; + + case OLD_VERTEX_COLOR_NORMAL_OP: + { + SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData(); + + coords[index].set( + (float)pVert->v[0], + (float)pVert->v[1], + (float)pVert->v[2]); + + if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + { + normals[index].set( + (float)pVert->n[0] / (1<<30), // =pow(2,30) + (float)pVert->n[1] / (1<<30), + (float)pVert->n[2] / (1<<30)); + normals[index].normalize(); + } + + if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + { + osg::Vec4* colors = gset->getColors(); + ColorPool* pColorPool = _colorPool.get(); + if (pColorPool) + colors[index] = pColorPool->getColor(pVert->color_index); + else + colors[index] = osg::Vec4(1,1,1,1); + } + + if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (vertex->getSize() >= sizeof(SOldVertexColorNormal))) + { + texuv[index].set( + (float)pVert->t[0], + (float)pVert->t[1]); + } + } + break; + } +} + + + //////////////////////////////////////////////////////////////////// // // GeoSetBuilder @@ -47,22 +370,10 @@ GeoSetBuilder::GeoSetBuilder(FltFile* pFltFile) } -// virtual -GeoSetBuilder::~GeoSetBuilder() -{ - for(GeoSetList::iterator itr=_aGeoSet.begin(); - itr!=_aGeoSet.end(); - ++itr) - { - delete *itr; - } -} - void GeoSetBuilder::initPrimData() { - _appearance.init(); - _aVertex.clear(); + _tmpGeoSet = new TmpGeoSet(_pFltFile.get()); } @@ -80,8 +391,8 @@ osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode) bInternalGeodeAllocation = true; } - for(GeoSetList::iterator itr=_aGeoSet.begin(); - itr!=_aGeoSet.end(); + for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin(); + itr!=_tmpGeoSetList.end(); ++itr) { osg::GeoSet* gset = (*itr)->createOsgGeoSet(); @@ -99,88 +410,70 @@ osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode) } -void GeoSetBuilder::addVertex(Record* vertex) -{ - _aVertex.push_back(vertex); - _appearance.setVertexOp(vertex->getOpcode()); -} - - bool GeoSetBuilder::addPrimitive() { - int nVertices = _aVertex.size(); + osg::GeoSet* geoset = getGeoSet(); - if (nVertices == 0) return false; + if (geoset->getPrimType() == osg::GeoSet::NO_TYPE) + geoset->setPrimType(findPrimType(numberOfVertices())); - if (_appearance.getPrimType() == osg::GeoSet::NO_TYPE) - _appearance.setPrimType(findPrimType(nVertices)); + // Still no primitive type? + if (geoset->getPrimType() == osg::GeoSet::NO_TYPE) + return false; - TmpGeoSet* gset = findMatchingGeoSet(); - if (gset) - { - addTo(gset); - if (_appearance.getMaterial()) - { - _appearance.getMaterial()->unref(); - _appearance.setMaterial(NULL); - } - } + TmpGeoSet* match = findMatchingGeoSet(); + if (match) + // append vertices and prim length to match + match->addVertices( _tmpGeoSet.get() ); else - addToNew(); + // add new GeoSet+StateSet compination + _tmpGeoSetList.push_back(_tmpGeoSet.get()); - initPrimData(); + initPrimData(); // initialize _tmpGeoSet return true; } -//////////////////////// protected ///////////////////////////////// - TmpGeoSet* GeoSetBuilder::findMatchingGeoSet() { + osg::GeoSet* geoSet = getGeoSet(); + osg::StateSet* stateSet = geoSet->getStateSet(); - for(std::vector::iterator itr=_aGeoSet.begin(); - itr!=_aGeoSet.end(); + for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin(); + itr!=_tmpGeoSetList.end(); ++itr) { - if (_appearance == (*itr)->_appearance) - return *itr; + TmpGeoSet* tmpgeoset = itr->get(); + osg::GeoSet* gset = tmpgeoset->getGeoSet(); + osg::StateSet* sset = gset->getStateSet(); + + // Do we have a match? + if ((geoSet->getPrimType() == gset->getPrimType()) + && (geoSet->getColorBinding() == gset->getColorBinding()) + && (geoSet->getNormalBinding() == gset->getNormalBinding()) + && (geoSet->getTextureBinding() == gset->getTextureBinding()) + && (stateSet->compare(*sset, true) == 0)) + { + if (geoSet->getColorBinding() == osg::GeoSet::BIND_OVERALL) + { + osg::Vec4* col1 = geoSet->getColors(); + osg::Vec4* col2 = gset->getColors(); + if (*col1 != *col2) + return NULL; + } + + return tmpgeoset; + } } return NULL; } -void GeoSetBuilder::addTo(TmpGeoSet* gset) +osg::GeoSet::PrimitiveType GeoSetBuilder::findPrimType(const int nVertices) { - int nVertices = _aVertex.size(); - gset->addPrimLen(nVertices); - - for(std::vector::iterator itr=_aVertex.begin(); - itr!=_aVertex.end(); - ++itr) - { - gset->addVertex(*itr); - } -} - - -void GeoSetBuilder::addToNew() -{ - TmpGeoSet* gset = new TmpGeoSet(_pFltFile); - if (gset == NULL) return; - - // Transfer data to TmpGeoSet - gset->_appearance = _appearance; - addTo(gset); - - _aGeoSet.push_back(gset); -} - - -PrimitiveType GeoSetBuilder::findPrimType( int nVertices) -{ - PrimitiveType primtype = osg::GeoSet::NO_TYPE; + osg::GeoSet::PrimitiveType primtype = osg::GeoSet::NO_TYPE; switch (nVertices) { @@ -205,446 +498,3 @@ PrimitiveType GeoSetBuilder::findPrimType( int nVertices) } -//////////////////////////////////////////////////////////////////// -// -// TmpGeoSet -// -//////////////////////////////////////////////////////////////////// - -// GeoSet with dynamic size. Used by GeoSetBuilder as a temp. buffer. - -TmpGeoSet::TmpGeoSet(FltFile* pFltFile) -{ - _pFltFile = pFltFile; -} - - -TmpGeoSet::~TmpGeoSet() -{ -} - - -void TmpGeoSet::addVertex(Record* vertex) -{ - _appearance.setVertexOp(vertex->getOpcode()); - _aVertex.push_back(vertex); -} - - -void TmpGeoSet::addPrimLen(int len) -{ - _aPrimLen.push_back(len); -} - - -osg::GeoSet* TmpGeoSet::createOsgGeoSet() -{ - int prims = _aPrimLen.size(); - int indices = _aVertex.size(); - - if (prims==0 || indices==0) - return NULL; - - osg::GeoSet* gset = new osg::GeoSet; - - gset->setNumPrims(prims); - gset->setPrimType(_appearance.getPrimType()); - - osg::StateSet* gstate = new osg::StateSet; - gset->setStateSet(gstate); - - // Material - osg::Material* osgMaterial = _appearance.getMaterial(); - if (osgMaterial) - gstate->setAttribute(osgMaterial); - - // Color - switch(_appearance.getColorBinding()) - { - case osg::GeoSet::BIND_OVERALL: - { - osg::Vec4* color = new osg::Vec4[1]; - *color = _appearance.getFaceColor(); - gset->setColorBinding(osg::GeoSet::BIND_OVERALL); - gset->setColors(color); - } - break; - - case osg::GeoSet::BIND_PERVERTEX: - { - gset->setColorBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setColors(new osg::Vec4[indices]); - } - break; - } - - // Transparency - if (_appearance.getTransparency()) - { - gstate->setMode(GL_BLEND,osg::StateAttribute::ON); - gstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - } - - // Cull face - if (_appearance.getCullface()) - { - osg::CullFace* cullface = new osg::CullFace; - if (cullface) - { - cullface->setMode(osg::CullFace::BACK); - gstate->setAttributeAndModes(cullface, osg::StateAttribute::ON); - } - } - else - { - gstate->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); - } - - // Texture - if (_appearance.getTexture()) - { - gstate->setAttributeAndModes( _appearance.getTexture(), osg::StateAttribute::ON ); - gstate->setAttribute( new osg::TexEnv ); - } - - // Lighting - if (_appearance.getLighting()) - gstate->setMode( GL_LIGHTING, osg::StateAttribute::ON ); - else - gstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - - // Subface - if (_appearance.getSubface() > 0) - { - osg::PolygonOffset* polyoffset = new osg::PolygonOffset; - if (polyoffset) - { - int level = _appearance.getSubface(); - polyoffset->setFactor(-1*level); - polyoffset->setUnits(-20*level); - gstate->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); - } - } - - // Point - if (_appearance.getPrimType() == osg::GeoSet::POINTS) - { - osg::Point* point = new osg::Point; - if (point) - { - point->setSize(8); - gstate->setAttributeAndModes(point,osg::StateAttribute::ON); - } - } - - // PrimLengths - - int nPrimLenSize = 1; - if (_appearance.getPrimType() == osg::GeoSet::POLYGON) - nPrimLenSize = prims; - int *lens = new int[nPrimLenSize]; - gset->setPrimLengths( lens ); - for (int n=0; n < nPrimLenSize; n++) - lens[n] = _aPrimLen[n]; - - // Vertices - switch(_appearance.getVertexOp()) - { - case VERTEX_C_OP: - gset->setCoords(new osg::Vec3[indices]); - break; - case VERTEX_CN_OP: - gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setCoords(new osg::Vec3[indices]); - gset->setNormals(new osg::Vec3[indices]); - break; - case VERTEX_CT_OP: - gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setCoords(new osg::Vec3[indices]); - gset->setTextureCoords(new osg::Vec2[indices]); - break; - case VERTEX_CNT_OP: - gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setCoords(new osg::Vec3[indices]); - gset->setNormals(new osg::Vec3[indices]); - gset->setTextureCoords(new osg::Vec2[indices]); - break; - case OLD_VERTEX_OP: - gset->setCoords(new osg::Vec3[indices]); - if (_appearance.getTexture()) - { - gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setTextureCoords(new osg::Vec2[indices]); - } - break; - case OLD_VERTEX_COLOR_OP: - gset->setCoords(new osg::Vec3[indices]); - if (_appearance.getTexture()) - { - gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setTextureCoords(new osg::Vec2[indices]); - } - break; - case OLD_VERTEX_COLOR_NORMAL_OP: - gset->setCoords(new osg::Vec3[indices]); - gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setNormals(new osg::Vec3[indices]); - if (_appearance.getTexture()) - { - gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); - gset->setTextureCoords(new osg::Vec2[indices]); - } - break; - - } - - // Copy vertices - { - int index; - std::vector::iterator itr; - for(index=0, itr=_aVertex.begin(); - itr!=_aVertex.end(); - ++index, ++itr) - { - setVertex(gset, index, *itr); - } - } - - return gset; -} - - -///////////////////////// private ////////////////////////////////// - -void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex) -{ - bool bColorBindPerVertex = _appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX; - - switch(_appearance.getVertexOp()) - { - case VERTEX_C_OP: - { - SVertex* pVert = (SVertex*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - - coords[index].set( - (float)pVert->Coord.x(), - (float)pVert->Coord.y(), - (float)pVert->Coord.z()); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - - if (pVert->swFlags & V_NO_COLOR_BIT) - colors[index] = _appearance.getFaceColor(); - else - { - if (pVert->swFlags & V_PACKED_COLOR_BIT) - colors[index] = pVert->PackedColor.get(); - else - { - ColorPool* pColorPool = _pFltFile->getColorPool(); - colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); - } - } - } - } - break; - - case VERTEX_CN_OP: - { - SNormalVertex* pVert = (SNormalVertex*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec3* normals = gset->getNormals(); - - coords[index].set( - (float)pVert->Coord.x(), - (float)pVert->Coord.y(), - (float)pVert->Coord.z()); - normals[index].set( - (float)pVert->Normal.x(), - (float)pVert->Normal.y(), - (float)pVert->Normal.z()); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - - if (pVert->swFlags & V_NO_COLOR_BIT) - colors[index] = _appearance.getFaceColor(); - else - { - if (pVert->swFlags & V_PACKED_COLOR_BIT) - colors[index] = pVert->PackedColor.get(); - else - { - ColorPool* pColorPool = _pFltFile->getColorPool(); - colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); - } - } - } - } - break; - - case VERTEX_CNT_OP: - { - SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec3* normals = gset->getNormals(); - osg::Vec2* texuv = gset->getTextureCoords(); - - coords[index].set( - (float)pVert->Coord.x(), - (float)pVert->Coord.y(), - (float)pVert->Coord.z()); - normals[index].set( - (float)pVert->Normal.x(), - (float)pVert->Normal.y(), - (float)pVert->Normal.z()); - texuv[index].set( - (float)pVert->Texture.x(), - (float)pVert->Texture.y()); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - - if (pVert->swFlags & V_NO_COLOR_BIT) - colors[index] = _appearance.getFaceColor(); - else - { - if (pVert->swFlags & V_PACKED_COLOR_BIT) - colors[index] = pVert->PackedColor.get(); - else - { - ColorPool* pColorPool = _pFltFile->getColorPool(); - colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); - } - } - } - } - break; - - case VERTEX_CT_OP: - { - STextureVertex* pVert = (STextureVertex*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec2* texuv = gset->getTextureCoords(); - - coords[index].set( - (float)pVert->Coord.x(), - (float)pVert->Coord.y(), - (float)pVert->Coord.z()); - texuv[index].set( - (float)pVert->Texture.x(), - (float)pVert->Texture.y()); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - - if (pVert->swFlags & V_NO_COLOR_BIT) - colors[index] = _appearance.getFaceColor(); - else - { - if (pVert->swFlags & V_PACKED_COLOR_BIT) - colors[index] = pVert->PackedColor.get(); - else - { - ColorPool* pColorPool = _pFltFile->getColorPool(); - colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex); - } - } - } - } - break; - - case OLD_VERTEX_OP: - { - SOldVertex* pVert = (SOldVertex*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec2* texuv = gset->getTextureCoords(); - - coords[index].set( - (float)pVert->v[0], - (float)pVert->v[1], - (float)pVert->v[2]); - - if (texuv && vertex->getSize() >= sizeof(SOldVertex)) - { - texuv[index].set( - (float)pVert->t[0], - (float)pVert->t[1]); - } - } - break; - - case OLD_VERTEX_COLOR_OP: - { - SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec2* texuv = gset->getTextureCoords(); - - coords[index].set( - (float)pVert->v[0], - (float)pVert->v[1], - (float)pVert->v[2]); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - ColorPool* pColorPool = _pFltFile->getColorPool(); - if (pColorPool) - colors[index] = pColorPool->getColor(pVert->color_index); - else - colors[index] = _appearance.getFaceColor(); - } - - if (texuv && vertex->getSize() >= sizeof(SOldVertexColor)) - { - texuv[index].set( - (float)pVert->t[0], - (float)pVert->t[1]); - } - } - break; - - case OLD_VERTEX_COLOR_NORMAL_OP: - { - SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData(); - osg::Vec3* coords = gset->getCoords(); - osg::Vec3* normals = gset->getNormals(); - osg::Vec2* texuv = gset->getTextureCoords(); - - coords[index].set( - (float)pVert->v[0], - (float)pVert->v[1], - (float)pVert->v[2]); - normals[index].set( - (float)pVert->n[0] / (1<<30), // =pow(2,30) - (float)pVert->n[1] / (1<<30), - (float)pVert->n[2] / (1<<30)); - - if (bColorBindPerVertex) - { - osg::Vec4* colors = gset->getColors(); - ColorPool* pColorPool = _pFltFile->getColorPool(); - if (pColorPool) - colors[index] = pColorPool->getColor(pVert->color_index); - else - colors[index] = _appearance.getFaceColor(); - } - - if (texuv && vertex->getSize() >= sizeof(SOldVertexColorNormal)) - { - texuv[index].set( - (float)pVert->t[0], - (float)pVert->t[1]); - } - } - break; - } -} - diff --git a/src/osgPlugins/flt/GeoSetBuilder.h b/src/osgPlugins/flt/GeoSetBuilder.h index 5b999913f..830b0295c 100644 --- a/src/osgPlugins/flt/GeoSetBuilder.h +++ b/src/osgPlugins/flt/GeoSetBuilder.h @@ -1,25 +1,17 @@ -// GeoSetBuilder.h +#ifndef __FLT_GEOSETBUILDER_H +#define __FLT_GEOSETBUILDER_H -#ifndef __FLT_GEOSETS_H -#define __FLT_GEOSETS_H - -#include -#include - -#include -#include +#include +#include #include #include #include +#include +#include +#include - -namespace osg { -class Node; -class LOD; -class Geode; -class GeoState; -class Texture; -} +#include +#include namespace flt { @@ -27,171 +19,6 @@ namespace flt { class Record; class TmpGeoSet; -typedef osg::GeoSet::PrimitiveType PrimitiveType; -typedef std::vector CoordList; -typedef std::vector NormalList; -typedef std::vector TexUVList; -typedef std::vector ColorList; -typedef std::vector VertexList; -typedef std::vector PrimLenList; - - - -class Appearance -{ -public: - - typedef osg::GeoSet::BindingType BindingType; - - Appearance() { init(); } - - void init() - { - _nVertexOp = 0; - _primtype = osg::GeoSet::NO_TYPE; - _material = NULL; - _texture = NULL; - _face_color = osg::Vec4(1,1,1,1); - _color_binding = osg::GeoSet::BIND_OFF; - _cullface = false; - _transparency = false; - _lighting = false; - _subface = 0; - } - - void setVertexOp(int op) { _nVertexOp = op; } - int getVertexOp() { return _nVertexOp; } - - void setPrimType(PrimitiveType pt) { _primtype = pt; } - PrimitiveType getPrimType() { return _primtype; } - - void setFaceColor(osg::Vec4 color) { _face_color = color; } - osg::Vec4& getFaceColor() { return _face_color; } - - inline void setColorBinding( BindingType binding ) { _color_binding = binding; } - inline const BindingType getColorBinding() const { return _color_binding; } - - void setMaterial(osg::Material *material) { _material = material; } - osg::Material* getMaterial() { return _material; } - - void setTexture(osg::Texture *texture) { _texture = texture; } - osg::Texture* getTexture() { return _texture; } - - void setCullface(bool cullface) { _cullface = cullface; } - bool getCullface() { return _cullface; } - - void setTransparency(bool transp) { _transparency = transp; } - bool getTransparency() { return _transparency; } - - void setLighting(bool light) { _lighting = light; } - bool getLighting() { return _lighting; } - - void setSubface(int level) { _subface = level; } - int getSubface() { return _subface; } - - bool mat_equal(const void *m) const - { - if (_material && m) - return !memcmp(_material, m, sizeof(osg::Material)); - return (!_material && !m); - } - - bool col_equal(const BindingType b, const osg::Vec4 c) const - { - if (_color_binding != b) - return false; - if (_color_binding == osg::GeoSet::BIND_OVERALL) - return (_face_color == c); - return true; - } - - /*inline*/ bool operator == (const Appearance& a) const - { - return ((_nVertexOp == a._nVertexOp) - && (_primtype == a._primtype) - && mat_equal(a._material) - && col_equal(a._color_binding, a._face_color) - && (_texture == a._texture) - && (_cullface == a._cullface) - && (_transparency == a._transparency) - && (_lighting == a._lighting) - && (_subface == a._subface)); - } - -private: - - int _nVertexOp; - PrimitiveType _primtype; - osg::Material* _material; - osg::Texture* _texture; - osg::Vec4 _face_color; - BindingType _color_binding; - bool _cullface; - bool _transparency; - bool _lighting; - int _subface; -}; - - - -//////////////////////////////////////////////////////////////////// -// -// GeoSetBuilder -// -//////////////////////////////////////////////////////////////////// - -class GeoSetBuilder -{ -public: - - typedef osg::GeoSet::BindingType BindingType; - - GeoSetBuilder(FltFile* pFltFile); - virtual ~GeoSetBuilder(); - - void addVertex(Record* vertex); - void setPrimType(PrimitiveType pt) { _appearance.setPrimType(pt); } - void setFaceColor(osg::Vec4 color) { _appearance.setFaceColor(color); } - void setColorBinding(const BindingType binding) { _appearance.setColorBinding(binding); } - void setMaterial(osg::Material *material) { _appearance.setMaterial(material); } - void setTexture(osg::Texture *texture) { _appearance.setTexture(texture); } - void setCullface(bool cullface) { _appearance.setCullface(cullface); } - void setTransparency(bool transp) { _appearance.setTransparency(transp); } - void setLighting(bool light) { _appearance.setLighting(light); } - void setSubface(int level) { _appearance.setSubface(level); } - - PrimitiveType getPrimType() { return _appearance.getPrimType(); } - osg::Vec4& getFaceColor() { return _appearance.getFaceColor(); } - BindingType getColorBinding() { return _appearance.getColorBinding(); } - osg::Material* getMaterial() { return _appearance.getMaterial(); } - osg::Texture* getTexture() { return _appearance.getTexture(); } - bool getCullface() { return _appearance.getCullface(); } - bool getTransparency() { return _appearance.getTransparency(); } - bool getLighting() { return _appearance.getLighting(); } - int getSubface() { return _appearance.getSubface(); } - - bool addPrimitive(); - osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL); - -protected: - - void initPrimData(); - TmpGeoSet* findMatchingGeoSet(); - void addTo(TmpGeoSet* gset); - void addToNew(); - PrimitiveType findPrimType( int nVertices); - -private: - - VertexList _aVertex; - Appearance _appearance; - - typedef std::vector GeoSetList; - GeoSetList _aGeoSet; - - FltFile* _pFltFile; -}; - //////////////////////////////////////////////////////////////////// // @@ -200,34 +27,101 @@ private: //////////////////////////////////////////////////////////////////// -class TmpGeoSet +/** TmpGeoSet - Temporary GeoSet with dynamic vertex array. + * Problem: osg::GeoSet use C arrays (static size) for coordinates, + * normals, colors and texture coordinates. + */ +class TmpGeoSet : public osg::Referenced { -public: + public: - TmpGeoSet(FltFile* pFltFile); - virtual ~TmpGeoSet(); + TmpGeoSet(FltFile* pFltFile); + virtual ~TmpGeoSet() {}; - void addVertex(Record* vertex); - void addPrimLen(int len); - osg::GeoSet* createOsgGeoSet(); + void addVertex(Record* vertexRec) { _vertexRecList.push_back(vertexRec); } + void addPrimLen(int len) { _primLenList.push_back(len); } - Appearance _appearance; + // Append vertices from other TmpGeoSet + void addVertices(TmpGeoSet* source) + { + _vertexRecList.insert(_vertexRecList.end(), + source->_vertexRecList.begin(), source->_vertexRecList.end()); + _primLenList.insert(_primLenList.end(), + source->_primLenList.begin(), source->_primLenList.end()); + } -private: + inline const int numberOfVertices() const { return _vertexRecList.size(); } + inline osg::GeoSet* getGeoSet() { return _geoSet.get(); } + inline const osg::GeoSet* getGeoSet() const { return _geoSet.get(); } - void setVertex(osg::GeoSet* gset, int index, Record* vertex); + // Create complete osg::GeoSet. + osg::GeoSet* createOsgGeoSet(); - PrimLenList _aPrimLen; - VertexList _aVertex; + private: + + typedef std::vector > VertexRecList; + typedef std::vector PrimLenList; + + void setVertex(osg::GeoSet* gset, int index, Record* vertex); + + osg::ref_ptr _geoSet; + PrimLenList _primLenList; + VertexRecList _vertexRecList; + + osg::ref_ptr _colorPool; + osg::ref_ptr _texturePool; + osg::ref_ptr _materialPool; - FltFile* _pFltFile; }; -} // end of namespace flt + +//////////////////////////////////////////////////////////////////// +// +// GeoSetBuilder +// +//////////////////////////////////////////////////////////////////// + +/** GeoSetBuilder - Contains a list of TmpGeoSets to be converted to osg::Geode. + * + */ + +class GeoSetBuilder +{ + public: + + GeoSetBuilder(FltFile* pFltFile); + virtual ~GeoSetBuilder() {} + + void addVertex(Record* vertex) { _tmpGeoSet.get()->addVertex(vertex); } + void addPrimLen(int len) { _tmpGeoSet.get()->addPrimLen(len); } + + bool addPrimitive(); + osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL); + + inline osg::GeoSet* getGeoSet() { return _tmpGeoSet.get()->getGeoSet(); } + inline const osg::GeoSet* getGeoSet() const { return _tmpGeoSet.get()->getGeoSet(); } + const int numberOfVertices() const { return _tmpGeoSet.get()->numberOfVertices(); } + + protected: + + void initPrimData(); + TmpGeoSet* findMatchingGeoSet(); + osg::GeoSet::PrimitiveType findPrimType(const int nVertices); + + private: + + osg::ref_ptr _pFltFile; + osg::ref_ptr _tmpGeoSet; + + typedef std::vector > TmpGeoSetList; + TmpGeoSetList _tmpGeoSetList; +}; +}; // end of namespace flt -#endif // __FLT_GEOSETS_H + +#endif diff --git a/src/osgPlugins/flt/GroupRecord.h b/src/osgPlugins/flt/GroupRecord.h index b5038806b..63151d7ce 100644 --- a/src/osgPlugins/flt/GroupRecord.h +++ b/src/osgPlugins/flt/GroupRecord.h @@ -41,7 +41,7 @@ class GroupRecord : public PrimNodeRecord virtual Record* clone() const { return new GroupRecord(); } virtual const char* className() const { return "GroupRecord"; } virtual int classOpcode() const { return GROUP_OP; } - virtual int sizeofData() const { return sizeof(SGroup); } + virtual size_t sizeofData() const { return sizeof(SGroup); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/HeaderRecord.cpp b/src/osgPlugins/flt/HeaderRecord.cpp index dd94c12be..abed1b5c6 100644 --- a/src/osgPlugins/flt/HeaderRecord.cpp +++ b/src/osgPlugins/flt/HeaderRecord.cpp @@ -117,6 +117,8 @@ void HeaderRecord::endian() ENDIAN( pHeader->dfLambertUpperLat ); ENDIAN( pHeader->dfLambertLowerLat ); ENDIAN( pHeader->iNextLightSource ); + + Registry::instance()->setVersion(pHeader->diFormatRevLev); } diff --git a/src/osgPlugins/flt/HeaderRecord.h b/src/osgPlugins/flt/HeaderRecord.h index 29a8189c4..4509ab378 100644 --- a/src/osgPlugins/flt/HeaderRecord.h +++ b/src/osgPlugins/flt/HeaderRecord.h @@ -93,7 +93,7 @@ class HeaderRecord : public PrimNodeRecord virtual Record* clone() const { return new HeaderRecord(); } virtual const char* className() const { return "HeaderRecord"; } virtual int classOpcode() const { return HEADER_OP; } - virtual int sizeofData() const { return sizeof(SHeader); } + virtual size_t sizeofData() const { return sizeof(SHeader); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } SHeader* getData() const { return (SHeader*)_pData; } diff --git a/src/osgPlugins/flt/Input.cpp b/src/osgPlugins/flt/Input.cpp index 4b70490b2..bbd545ee3 100644 --- a/src/osgPlugins/flt/Input.cpp +++ b/src/osgPlugins/flt/Input.cpp @@ -172,10 +172,10 @@ Record* Input::readCreateRecord() if (pData == NULL) return NULL; // find matching record prototype class - Record* pProto = Registry::instance()->getRecordProto(pData->opcode()); + Record* pProto = Registry::instance()->getPrototype(pData->opcode()); if (pProto == NULL) - pProto = Registry::instance()->getRecordProto(0); + pProto = Registry::instance()->getPrototype(0); if (pProto == NULL) { diff --git a/src/osgPlugins/flt/LodRecord.h b/src/osgPlugins/flt/LodRecord.h index e28480362..ff5e0bf95 100644 --- a/src/osgPlugins/flt/LodRecord.h +++ b/src/osgPlugins/flt/LodRecord.h @@ -45,7 +45,7 @@ class LodRecord : public PrimNodeRecord virtual Record* clone() const { return new LodRecord(); } virtual const char* className() const { return "LodRecord"; } virtual int classOpcode() const { return LOD_OP; } - virtual int sizeofData() const { return sizeof(SLevelOfDetail); } + virtual size_t sizeofData() const { return sizeof(SLevelOfDetail); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -94,7 +94,7 @@ class OldLodRecord : public PrimNodeRecord virtual Record* clone() const { return new OldLodRecord(); } virtual const char* className() const { return "OldLodRecord"; } virtual int classOpcode() const { return OLD_LOD_OP; } - virtual int sizeofData() const { return sizeof(SOldLOD); } + virtual size_t sizeofData() const { return sizeof(SOldLOD); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/MaterialPaletteRecord.h b/src/osgPlugins/flt/MaterialPaletteRecord.h index 91ac7155a..8f4af94cd 100644 --- a/src/osgPlugins/flt/MaterialPaletteRecord.h +++ b/src/osgPlugins/flt/MaterialPaletteRecord.h @@ -38,7 +38,7 @@ class MaterialPaletteRecord : public AncillaryRecord virtual Record* clone() const { return new MaterialPaletteRecord(); } virtual const char* className() const { return "MaterialPaletteRecord"; } virtual int classOpcode() const { return MATERIAL_PALETTE_OP; } - virtual int sizeofData() const { return sizeof(SMaterial); } + virtual size_t sizeofData() const { return sizeof(SMaterial); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/ObjectRecord.h b/src/osgPlugins/flt/ObjectRecord.h index 8c8f58c78..256580feb 100644 --- a/src/osgPlugins/flt/ObjectRecord.h +++ b/src/osgPlugins/flt/ObjectRecord.h @@ -12,27 +12,27 @@ namespace flt { -typedef struct ObjectTag +struct SObject { - SRecHeader RecHeader; - char szIdent[8]; // 7 char ASCII ID; 0 terminates - uint32 dwFlags; // Flags (bits from to right) - // 0 = Don't display in daylight - // 1 = Don't display at dusk - // 2 = Don't display at night - // 3 = Don't illuminate - // 4 = Flat shaded - // 5 = Group's shadow object - // 6-31 Spare - int16 iObjectRelPriority; // Object relative priority - uint16 wTransparency; // Transparency factor - // = 0 opaque - // = 65535 for totally clear - int16 iSpecialId_1; // Special effects ID 1 - defined by real time - int16 iSpecialId_2; // Special effects ID 2 - defined by real time - int16 iSignificance; // Significance - int16 iSpare; // Spare -} SObject; + SRecHeader RecHeader; + char szIdent[8]; // 7 char ASCII ID; 0 terminates + uint32 dwFlags; // Flags (bits from to right) + // 0 = Don't display in daylight + // 1 = Don't display at dusk + // 2 = Don't display at night + // 3 = Don't illuminate + // 4 = Flat shaded + // 5 = Group's shadow object + // 6-31 Spare + int16 iObjectRelPriority; // Object relative priority + uint16 wTransparency; // Transparency factor + // = 0 opaque + // = 65535 for totally clear + int16 iSpecialId_1; // Special effects ID 1 - defined by real time + int16 iSpecialId_2; // Special effects ID 2 - defined by real time + int16 iSignificance; // Significance + int16 iSpare; // Spare +}; diff --git a/src/osgPlugins/flt/OldMaterialPaletteRecord.h b/src/osgPlugins/flt/OldMaterialPaletteRecord.h index baf4938f0..7f522b06d 100644 --- a/src/osgPlugins/flt/OldMaterialPaletteRecord.h +++ b/src/osgPlugins/flt/OldMaterialPaletteRecord.h @@ -39,7 +39,7 @@ class OldMaterialPaletteRecord : public AncillaryRecord virtual Record* clone() const { return new OldMaterialPaletteRecord(); } virtual const char* className() const { return "OldMaterialPaletteRecord"; } virtual int classOpcode() const { return OLD_MATERIAL_PALETTE_OP; } - virtual int sizeofData() const { return sizeof(SOldMaterial); } + virtual size_t sizeofData() const { return sizeof(SOldMaterial); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/OldVertexRecords.h b/src/osgPlugins/flt/OldVertexRecords.h index e67297c11..313d1eb74 100644 --- a/src/osgPlugins/flt/OldVertexRecords.h +++ b/src/osgPlugins/flt/OldVertexRecords.h @@ -42,7 +42,7 @@ class OldVertexRecord : public PrimNodeRecord virtual Record* clone() const { return new OldVertexRecord(); } virtual const char* className() const { return "OldVertexRecord"; } virtual int classOpcode() const { return OLD_VERTEX_OP; } - virtual int sizeofData() const { return sizeof(SOldVertex); } + virtual size_t sizeofData() const { return sizeof(SOldVertex); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SOldVertex* getData() const { return (SOldVertex*)_pData; } @@ -83,7 +83,7 @@ class OldVertexColorRecord : public PrimNodeRecord virtual Record* clone() const { return new OldVertexColorRecord(); } virtual const char* className() const { return "OldVertexColorRecord"; } virtual int classOpcode() const { return OLD_VERTEX_COLOR_OP; } - virtual int sizeofData() const { return sizeof(SOldVertexColor); } + virtual size_t sizeofData() const { return sizeof(SOldVertexColor); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SOldVertexColor* getData() const { return (SOldVertexColor*)_pData; } @@ -124,7 +124,7 @@ class OldVertexColorNormalRecord : public PrimNodeRecord virtual Record* clone() const { return new OldVertexColorNormalRecord(); } virtual const char* className() const { return "OldVertexColorNormalRecord"; } virtual int classOpcode() const { return OLD_VERTEX_COLOR_NORMAL_OP; } - virtual int sizeofData() const { return sizeof(SOldVertexColorNormal); } + virtual size_t sizeofData() const { return sizeof(SOldVertexColorNormal); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SOldVertexColorNormal* getData() const { return (SOldVertexColorNormal*)_pData; } diff --git a/src/osgPlugins/flt/Pool.cpp b/src/osgPlugins/flt/Pool.cpp index b64170656..3da478075 100644 --- a/src/osgPlugins/flt/Pool.cpp +++ b/src/osgPlugins/flt/Pool.cpp @@ -13,17 +13,6 @@ using namespace flt; -ColorPool::ColorPool() -{ -} - - -// virtual -ColorPool::~ColorPool() -{ - eraseAll(); -} - osg::Vec4 ColorPool::getColor(int nColorIndex) { @@ -63,45 +52,20 @@ ColorPool::ColorName* ColorPool::getColorName(int nIndex) { ColorNameMap::iterator itr = _colorNameMap.find(nIndex); if (itr != _colorNameMap.end()) - return (*itr).second; + return (*itr).second.get(); return NULL; } -void ColorPool::eraseAll() -{ - for(ColorNameMap::iterator itr=_colorNameMap.begin(); - itr!=_colorNameMap.end(); - ++itr) - { - ColorName* colorname = (*itr).second; - if (colorname) - delete colorname; - } - _colorNameMap.clear(); -} - - //////////////////////////////////////////////////////////////////// -TexturePool::TexturePool() -{ -} - - -// virtual -TexturePool::~TexturePool() -{ - eraseAll(); -} - osg::Texture* TexturePool::getTexture(int nIndex) { TexturePaletteMap::iterator fitr = _textureMap.find(nIndex); if (fitr != _textureMap.end()) - return (*fitr).second; + return (*fitr).second.get(); else return NULL; } @@ -113,32 +77,15 @@ void TexturePool::addTexture(int nIndex, osg::Texture* osgTexture) } -void TexturePool::eraseAll() -{ - _textureMap.clear(); -} - - //////////////////////////////////////////////////////////////////// -MaterialPool::MaterialPool() -{ -} - -// virtual -MaterialPool::~MaterialPool() -{ - eraseAll(); -} - - -PoolMaterial* MaterialPool::getMaterial(int nIndex) +MaterialPool::PoolMaterial* MaterialPool::getMaterial(int nIndex) { if (nIndex < 0) return NULL; MaterialMap::iterator fitr = _MaterialMap.find(nIndex); if (fitr != _MaterialMap.end()) - return (*fitr).second; + return (*fitr).second.get(); return NULL; } @@ -150,15 +97,3 @@ void MaterialPool::addMaterial(int nIndex, PoolMaterial* material) } -void MaterialPool::eraseAll() -{ - for(MaterialMap::iterator itr=_MaterialMap.begin(); - itr!=_MaterialMap.end(); - ++itr) - { - PoolMaterial* material = (*itr).second; - if (material) - delete material; - } - _MaterialMap.clear(); -} diff --git a/src/osgPlugins/flt/Pool.h b/src/osgPlugins/flt/Pool.h index cc819b0c5..df8f06b76 100644 --- a/src/osgPlugins/flt/Pool.h +++ b/src/osgPlugins/flt/Pool.h @@ -1,12 +1,13 @@ -// Pool.cpp - #ifndef __FLT_POOL_H #define __FLT_POOL_H #include "flt.h" +#include +#include #include #include +#include #include #include @@ -17,87 +18,89 @@ namespace flt { -class ColorPool +class ColorPool : public osg::Referenced { + public : -public: - ColorPool(); - virtual ~ColorPool(); + ColorPool() {} - osg::Vec4 getColor(int nColorIndex); - void addColor(int nIndex, const osg::Vec4& color); + osg::Vec4 getColor(int nColorIndex); + void addColor(int nIndex, const osg::Vec4& color); -private: + protected : - class ColorName - { - public: - void setName( const std::string& name ) { _name = name; } - const std::string& getName( void ) { return _name; } - void setColor(const osg::Vec4& color ) { _color = color; } - osg::Vec4& getColor() { return _color; } + virtual ~ColorPool() {} - private: - osg::Vec4 _color; - std::string _name; - }; + private : - void eraseAll(); - ColorName* getColorName(int nIndex); + class ColorName : public osg::Referenced + { + public: + void setName( const std::string& name ) { _name = name; } + const std::string& getName( void ) { return _name; } + void setColor(const osg::Vec4& color ) { _color = color; } + osg::Vec4 getColor() { return _color; } - typedef std::mapColorNameMap; - ColorNameMap _colorNameMap; + private: + osg::Vec4 _color; + std::string _name; + }; + + ColorName* getColorName(int nIndex); + + typedef std::map > ColorNameMap; + ColorNameMap _colorNameMap; }; -class TexturePool +class TexturePool : public osg::Referenced { -public: + public : - TexturePool(); - virtual ~TexturePool(); + TexturePool() {} - osg::Texture* getTexture(int nIndex); - void addTexture(int nIndex, osg::Texture* osgTexture); + osg::Texture* getTexture(int nIndex); + void addTexture(int nIndex, osg::Texture* osgTexture); -private: + protected : - void eraseAll(); + virtual ~TexturePool() {} - typedef std::map TexturePaletteMap; - TexturePaletteMap _textureMap; + private : + + typedef std::map > TexturePaletteMap; + TexturePaletteMap _textureMap; }; -struct PoolMaterial + +class MaterialPool : public osg::Referenced { - float32x3 Ambient; // Ambient component of material - float32x3 Diffuse; // Diffuse component of material - float32x3 Specular; // Specular component of material - float32x3 Emissive; // Emissive component of material - float32 sfShininess; // Shininess. [0.0-128.0] - float32 sfAlpha; // Alpha. [0.0-1.0], where 1.0 is opaque -}; + public: -struct SMaterial; -struct SOldMaterial; + struct PoolMaterial : public osg::Referenced + { + float32x3 Ambient; // Ambient component of material + float32x3 Diffuse; // Diffuse component of material + float32x3 Specular; // Specular component of material + float32x3 Emissive; // Emissive component of material + float32 sfShininess; // Shininess. [0.0-128.0] + float32 sfAlpha; // Alpha. [0.0-1.0], where 1.0 is opaque + }; + + MaterialPool() {} -class MaterialPool -{ -public: + PoolMaterial* getMaterial(int nIndex); + void addMaterial(int nIndex, PoolMaterial* material); - MaterialPool(); - virtual ~MaterialPool(); + protected : - PoolMaterial* getMaterial(int nIndex); - void addMaterial(int nIndex, PoolMaterial* material); + virtual ~MaterialPool() {} -private: + private: - void eraseAll(); - - typedef std::map MaterialMap; - MaterialMap _MaterialMap; + typedef std::map > MaterialMap; + MaterialMap _MaterialMap; }; diff --git a/src/osgPlugins/flt/ReaderWriterFLT.cpp b/src/osgPlugins/flt/ReaderWriterFLT.cpp index b39c0455d..53900ad5e 100644 --- a/src/osgPlugins/flt/ReaderWriterFLT.cpp +++ b/src/osgPlugins/flt/ReaderWriterFLT.cpp @@ -16,9 +16,9 @@ using namespace flt; osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*) { - FltFile read; + osg::ref_ptr read = new FltFile; - osg::Object* obj=read.readObject(fileName); + osg::Object* obj = read.get()->readObject(fileName); if (obj) return obj; else return ReadResult::FILE_NOT_HANDLED; } @@ -26,10 +26,10 @@ osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readObject(const std::string& f osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) { - FltFile read; + osg::ref_ptr read = new FltFile; - osg::Node* obj=read.readNode(fileName); - if (obj) return obj; + osg::Node* node = read.get()->readNode(fileName); + if (node) return node; else return ReadResult::FILE_NOT_HANDLED; } diff --git a/src/osgPlugins/flt/Record.h b/src/osgPlugins/flt/Record.h index 47103d027..25d4907ba 100644 --- a/src/osgPlugins/flt/Record.h +++ b/src/osgPlugins/flt/Record.h @@ -44,7 +44,7 @@ class Record : public osg::Referenced virtual const char* className() const { return "Record"; } //const = 0; virtual int classOpcode() const { return 0; } //const = 0; - virtual int sizeofData() const { return 0; } //const = 0; + virtual size_t sizeofData() const { return 0; } //const = 0; virtual void accept(RecordVisitor& rv); virtual void traverse(RecordVisitor&) {} @@ -60,9 +60,9 @@ class Record : public osg::Referenced SRecHeader* getData() const; void* getBody() const; int getOpcode() const; - int getSize() const; - int getHeaderLength() const; - int getBodyLength() const; + size_t getSize() const; + size_t getHeaderLength() const; + size_t getBodyLength() const; bool isOfType(int op) const; Record* getParent() const { return _pParent; } @@ -115,19 +115,19 @@ int Record::getOpcode() const } inline -int Record::getSize() const +size_t Record::getSize() const { return (_pData) ? _pData->length() : 0; } inline -int Record::getHeaderLength() const +size_t Record::getHeaderLength() const { return sizeof(SRecHeader); } inline -int Record::getBodyLength() const +size_t Record::getBodyLength() const { return getSize() - getHeaderLength(); } diff --git a/src/osgPlugins/flt/Registry.cpp b/src/osgPlugins/flt/Registry.cpp index 1a20d9ad3..d0f22e477 100644 --- a/src/osgPlugins/flt/Registry.cpp +++ b/src/osgPlugins/flt/Registry.cpp @@ -1,7 +1,6 @@ #include #include -//#include #include #include @@ -11,35 +10,20 @@ #include "Input.h" #include "FltFile.h" #include "Registry.h" - +/* #ifdef OSG_USE_IO_DOT_H //#include #else #include using namespace std; #endif - -#include +*/ +//#include using namespace flt; -// definition of the Registry -Registry::Registry() -{ - osg::notify(osg::INFO) << "Constructing flt record flt::Registry\n"; -} - - -Registry::~Registry() -{ - - osg::notify(osg::INFO) << "Destructing flt flt::Registry"<< endl; - - // note, do not need to unrefence records as the combination of - // std::vector and ref_ptr will do it automatical on destruction. -} - +// static Registry* Registry::instance() { static Registry s_nodeFactory; @@ -52,112 +36,45 @@ void Registry::addPrototype(Record* rec) if (rec==0L) return; osg::notify(osg::INFO) << "flt::Registry::addPrototype("<< rec->className()<<")\n"; - - RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec); - if (pitr==_recordProtoList.end()) - { - _recordProtoList.push_back(rec); - } - else - { - osg::notify(osg::INFO) << " failed - flt::Registry::addPrototype() - prototype already exists"<<")\n"; - } - - rec->ref(); + int op = rec->classOpcode(); + _recordProtoMap[op] = rec; } -void Registry::removePrototype(Record* rec) +Record* Registry::getPrototype(const int opcode) { - if (rec==0L) return; + RecordProtoMap::iterator itr = _recordProtoMap.find(opcode); + if (itr != _recordProtoMap.end()) + return (*itr).second.get(); - osg::notify(osg::INFO) << "flt::Registry::removePrototype("<className()<<")\n"; + return NULL; - RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec); - if (pitr!=_recordProtoList.end()) - { - _recordProtoList.erase(pitr); - } - -} - - -Registry::RecordProtoList::iterator Registry::getRecordProtoItr(const int opcode) -{ - for(RecordProtoList::iterator itr=_recordProtoList.begin(); - itr!=_recordProtoList.end(); - ++itr) - { - if ((*itr)->classOpcode() == opcode) - return itr; - } - - return _recordProtoList.end(); -} - - -Record* Registry::getRecordProto(const int opcode) -{ - RecordProtoList::iterator itr = getRecordProtoItr(opcode); - if (itr==_recordProtoList.end()) - return NULL; - - return itr->get(); } /////////////////////////////////////////////////////////////////// -void Registry::addTexture(osg::Texture* texture) +void Registry::addTexture(const std::string& name, osg::Texture* texture) { - if (texture==0L) return; - - osg::notify(osg::INFO) << "flt::Registry::addTexture("<< texture->className()<<")\n"; - - TextureList::iterator pitr = std::find(_textureList.begin(),_textureList.end(),texture); - if (pitr==_textureList.end()) - _textureList.push_back(texture); - else - osg::notify(osg::INFO) << "failed - flt::Registry::addTexture() - texture already exists"<<")\n"; -} - - -void Registry::removeTexture(osg::Texture* texture) -{ - if (texture==0L) return; - - osg::notify(osg::INFO) << "flt::Registry::removeTexture("<< texture->className()<<")\n"; - - TextureList::iterator itr = std::find(_textureList.begin(),_textureList.end(),texture); - if (itr!=_textureList.end()) - { - _textureList.erase(itr); - } -} - - -Registry::TextureList::iterator Registry::getTextureItr(const std::string name) -{ - for(TextureList::iterator itr=_textureList.begin(); - itr!=_textureList.end(); - ++itr) - { - osg::Image* image = (*itr)->getImage(); - if (image && name == image->getFileName()) - return itr; - } - - return _textureList.end(); + if (texture == NULL) return; + _textureMap[name] = texture; } osg::Texture* Registry::getTexture(const std::string name) { - TextureList::iterator itr = getTextureItr(name); - if (itr==_textureList.end()) - return NULL; + TextureMap::iterator itr = _textureMap.find(name); + if (itr != _textureMap.end()) + return (*itr).second.get(); - return *itr; + return NULL; +} + + +void Registry::addFltFile(const std::string& name, FltFile* file) +{ + if (file == NULL) return; + _fltFileMap[name] = file; } @@ -166,12 +83,7 @@ FltFile* Registry::getFltFile(const std::string& name) FltFileMap::iterator itr = _fltFileMap.find(name); if (itr != _fltFileMap.end()) return (*itr).second.get(); - else - return NULL; -} - -void Registry::addFltFile(const std::string& name, FltFile* file) -{ - _fltFileMap[name] = file; + + return NULL; } diff --git a/src/osgPlugins/flt/Registry.h b/src/osgPlugins/flt/Registry.h index 31ae56e4c..c46f019d5 100644 --- a/src/osgPlugins/flt/Registry.h +++ b/src/osgPlugins/flt/Registry.h @@ -40,38 +40,38 @@ class Registry { public: - ~Registry(); + ~Registry() {} static Registry* instance(); void addPrototype(Record* rec); - void removePrototype(Record* rec); - Record* getRecordProto(const int opcode); + Record* getPrototype(const int opcode); - void addTexture(osg::Texture* texture); - void removeTexture(osg::Texture* texture); + void addTexture(const std::string& name, osg::Texture* texture); osg::Texture* getTexture(const std::string name); void addFltFile(const std::string& name, FltFile* file); FltFile* getFltFile(const std::string& name); + inline void setVersion(int ver) { _fltFileVersion = ver; } + inline int getVersion() const { return _fltFileVersion; } + private: - typedef std::vector > RecordProtoList; - typedef std::vector TextureList; - typedef std::map > FltFileMap; + typedef std::map > RecordProtoMap; + typedef std::map > TextureMap; + typedef std::map > FltFileMap; /** constructor is private, as its a singleton, preventing construction other than via the instance() method and therefore ensuring only one copy is ever constructed*/ - Registry(); + Registry() {} - RecordProtoList::iterator getRecordProtoItr(const int opcode); - TextureList::iterator getTextureItr(const std::string name); + RecordProtoMap _recordProtoMap; + TextureMap _textureMap; + FltFileMap _fltFileMap; + int _fltFileVersion; - RecordProtoList _recordProtoList; - TextureList _textureList; - FltFileMap _fltFileMap; }; @@ -81,22 +81,22 @@ template class RegisterRecordProxy { public: + RegisterRecordProxy() { - _obj = new T; - _obj->ref(); - Registry::instance()->addPrototype(_obj); - } - ~RegisterRecordProxy() - { - //commented out to prevent seg fault under Linux - //due to the registry being previously destructed. - //Registry::instance()->removePrototype(_obj); - _obj->unref(); + if (Registry::instance()) + { + _obj = new T; + Registry::instance()->addPrototype(_obj.get()); + } } + + ~RegisterRecordProxy() {} protected: - T* _obj; + + osg::ref_ptr _obj; + }; @@ -104,3 +104,4 @@ class RegisterRecordProxy }; // end namespace flt #endif // __FLT_REGISTRY_H + diff --git a/src/osgPlugins/flt/SwitchRecord.h b/src/osgPlugins/flt/SwitchRecord.h index fb1ed5248..d7bdb3951 100644 --- a/src/osgPlugins/flt/SwitchRecord.h +++ b/src/osgPlugins/flt/SwitchRecord.h @@ -33,7 +33,7 @@ class SwitchRecord : public PrimNodeRecord virtual Record* clone() const { return new SwitchRecord(); } virtual const char* className() const { return "SwitchRecord"; } virtual int classOpcode() const { return SWITCH_OP; } - virtual int sizeofData() const { return sizeof(SSwitch); } + virtual size_t sizeofData() const { return sizeof(SSwitch); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/TextureMappingPaletteRecord.h b/src/osgPlugins/flt/TextureMappingPaletteRecord.h index 0103d87f8..49fe2aa1d 100644 --- a/src/osgPlugins/flt/TextureMappingPaletteRecord.h +++ b/src/osgPlugins/flt/TextureMappingPaletteRecord.h @@ -174,7 +174,7 @@ class TextureMappingPaletteRecord : public AncillaryRecord virtual Record* clone() const { return new TextureMappingPaletteRecord(); } virtual const char* className() const { return "TextureMappingPaletteRecord"; } virtual int classOpcode() const { return TEXTURE_MAPPING_PALETTE_OP; } - virtual int sizeofData() const { return sizeof(STextureMapping); } + virtual size_t sizeofData() const { return sizeof(STextureMapping); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/TexturePaletteRecord.h b/src/osgPlugins/flt/TexturePaletteRecord.h index bd1756e1d..1f8a45ef0 100644 --- a/src/osgPlugins/flt/TexturePaletteRecord.h +++ b/src/osgPlugins/flt/TexturePaletteRecord.h @@ -31,7 +31,7 @@ class TexturePaletteRecord : public AncillaryRecord virtual Record* clone() const { return new TexturePaletteRecord(); } virtual const char* className() const { return "TexturePaletteRecord"; } virtual int classOpcode() const { return TEXTURE_PALETTE_OP; } - virtual int sizeofData() const { return sizeof(STexturePalette); } + virtual size_t sizeofData() const { return sizeof(STexturePalette); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/TransformationRecords.h b/src/osgPlugins/flt/TransformationRecords.h index 904d102ed..a82cf4334 100644 --- a/src/osgPlugins/flt/TransformationRecords.h +++ b/src/osgPlugins/flt/TransformationRecords.h @@ -34,7 +34,7 @@ class MatrixRecord : public AncillaryRecord virtual Record* clone() const { return new MatrixRecord(); } virtual const char* className() const { return "MatrixRecord"; } virtual int classOpcode() const { return MATRIX_OP; } - virtual int sizeofData() const { return sizeof(SMatrix); } + virtual size_t sizeofData() const { return sizeof(SMatrix); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -71,7 +71,7 @@ class RotatAboutEdgeRecord : public AncillaryRecord virtual Record* clone() const { return new RotatAboutEdgeRecord(); } virtual const char* className() const { return "RotatAboutEdgeRecord"; } virtual int classOpcode() const { return ROTATE_ABOUT_EDGE_OP; } - virtual int sizeofData() const { return sizeof(SRotatAboutEdge); } + virtual size_t sizeofData() const { return sizeof(SRotatAboutEdge); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -108,7 +108,7 @@ class TranslateRecord : public AncillaryRecord virtual Record* clone() const { return new TranslateRecord(); } virtual const char* className() const { return "TranslateRecord"; } virtual int classOpcode() const { return TRANSLATE_OP; } - virtual int sizeofData() const { return sizeof(STranslate); } + virtual size_t sizeofData() const { return sizeof(STranslate); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -144,7 +144,7 @@ class OldTranslateRecord : public AncillaryRecord virtual Record* clone() const { return new OldTranslateRecord(); } virtual const char* className() const { return "OldTranslateRecord"; } virtual int classOpcode() const { return OLD_TRANSLATE_OP; } - virtual int sizeofData() const { return sizeof(SOldTranslate); } + virtual size_t sizeofData() const { return sizeof(SOldTranslate); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -178,7 +178,7 @@ class ScaleRecord : public AncillaryRecord virtual Record* clone() const { return new ScaleRecord(); } virtual const char* className() const { return "ScaleRecord"; } virtual int classOpcode() const { return SCALE_OP; } - virtual int sizeofData() const { return sizeof(SScale); } + virtual size_t sizeofData() const { return sizeof(SScale); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -211,7 +211,7 @@ class RotatAboutPointRecord : public AncillaryRecord virtual Record* clone() const { return new RotatAboutPointRecord(); } virtual const char* className() const { return "RotatAboutPointRecord"; } virtual int classOpcode() const { return ROTATE_ABOUT_POINT_OP; } - virtual int sizeofData() const { return sizeof(SRotatAboutPoint); } + virtual size_t sizeofData() const { return sizeof(SRotatAboutPoint); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -244,7 +244,7 @@ class RotatScaleToPointRecord : public AncillaryRecord virtual Record* clone() const { return new RotatScaleToPointRecord(); } virtual const char* className() const { return "RotatScaleToPointRecord"; } virtual int classOpcode() const { return ROTATE_SCALE_TO_POINT_OP; } - virtual int sizeofData() const { return sizeof(SRotatScaleToPoint); } + virtual size_t sizeofData() const { return sizeof(SRotatScaleToPoint); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -284,7 +284,7 @@ class PutTransformRecord : public AncillaryRecord virtual Record* clone() const { return new PutTransformRecord(); } virtual const char* className() const { return "PutTransformRecord"; } virtual int classOpcode() const { return PUT_TRANSFORM_OP; } - virtual int sizeofData() const { return sizeof(SPutTransform); } + virtual size_t sizeofData() const { return sizeof(SPutTransform); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); @@ -318,7 +318,7 @@ class GeneralMatrixRecord : public AncillaryRecord virtual Record* clone() const { return new GeneralMatrixRecord(); } virtual const char* className() const { return "GeneralMatrixRecord"; } virtual int classOpcode() const { return GENERAL_MATRIX_OP; } - virtual int sizeofData() const { return sizeof(SGeneralMatrix); } + virtual size_t sizeofData() const { return sizeof(SGeneralMatrix); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/VertexPoolRecords.h b/src/osgPlugins/flt/VertexPoolRecords.h index d2dffca11..1e038ed78 100644 --- a/src/osgPlugins/flt/VertexPoolRecords.h +++ b/src/osgPlugins/flt/VertexPoolRecords.h @@ -45,7 +45,7 @@ class VertexPaletteRecord : public AncillaryRecord virtual Record* clone() const { return new VertexPaletteRecord(); } virtual const char* className() const { return "VertexPaletteRecord"; } virtual int classOpcode() const { return VERTEX_PALETTE_OP; } - virtual int sizeofData() const { return sizeof(SVertexTableHeader); } + virtual size_t sizeofData() const { return sizeof(SVertexTableHeader); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); friend ostream& operator << (ostream& output, const VertexPaletteRecord& rec); @@ -86,7 +86,7 @@ class VertexRecord : public AncillaryRecord virtual Record* clone() const { return new VertexRecord(); } virtual const char* className() const { return "VertexRecord"; } virtual int classOpcode() const { return VERTEX_C_OP; } - virtual int sizeofData() const { return sizeof(SVertex); } + virtual size_t sizeofData() const { return sizeof(SVertex); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SVertex* getData() const { return (SVertex*)_pData; } @@ -130,7 +130,7 @@ class NormalVertexRecord : public AncillaryRecord virtual Record* clone() const { return new NormalVertexRecord(); } virtual const char* className() const { return "NormalVertexRecord"; } virtual int classOpcode() const { return VERTEX_CN_OP; } - virtual int sizeofData() const { return sizeof(SNormalVertex); } + virtual size_t sizeofData() const { return sizeof(SNormalVertex); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SNormalVertex* getData() const { return (SNormalVertex*)_pData; } @@ -173,7 +173,7 @@ class TextureVertexRecord : public AncillaryRecord virtual Record* clone() const { return new TextureVertexRecord(); } virtual const char* className() const { return "TextureVertexRecord"; } virtual int classOpcode() const { return VERTEX_CT_OP; } - virtual int sizeofData() const { return sizeof(STextureVertex); } + virtual size_t sizeofData() const { return sizeof(STextureVertex); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual STextureVertex* getData() const { return (STextureVertex*)_pData; } @@ -217,7 +217,7 @@ class NormalTextureVertexRecord : public AncillaryRecord virtual Record* clone() const { return new NormalTextureVertexRecord(); } virtual const char* className() const { return "NormalTextureVertexRecord"; } virtual int classOpcode() const { return VERTEX_CNT_OP; } - virtual int sizeofData() const { return sizeof(SNormalTextureVertex); } + virtual size_t sizeofData() const { return sizeof(SNormalTextureVertex); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); virtual SNormalTextureVertex* getData() const { return (SNormalTextureVertex*)_pData; } diff --git a/src/osgPlugins/flt/flt.h b/src/osgPlugins/flt/flt.h index 6b302b794..a1027cb80 100644 --- a/src/osgPlugins/flt/flt.h +++ b/src/osgPlugins/flt/flt.h @@ -173,7 +173,7 @@ struct SRecHeader uint16 _wLength; // total length of record inline int opcode() { return (int)_wOpcode; } - inline int length() { return (int)_wLength; } + inline size_t length() { return (size_t)_wLength; } void endian() { ENDIAN( _wOpcode ); ENDIAN( _wLength ); diff --git a/src/osgPlugins/flt/flt2osg.cpp b/src/osgPlugins/flt/flt2osg.cpp index a2defd977..3437867e7 100644 --- a/src/osgPlugins/flt/flt2osg.cpp +++ b/src/osgPlugins/flt/flt2osg.cpp @@ -9,6 +9,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -27,6 +31,7 @@ #include "flt.h" #include "flt2osg.h" #include "FltFile.h" +#include "Registry.h" #include "Record.h" #include "HeaderRecord.h" #include "ColorPaletteRecord.h" @@ -145,7 +150,7 @@ osg::Node* ConvertFromFLT::visitAncillary(osg::Group* osgParent, PrimNodeRecord* osg::Node* ConvertFromFLT::visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec) { osg::Node* node = NULL; - GeoSetBuilder geoSetBuilder(_pFltFile); + GeoSetBuilder geoSetBuilder(_pFltFile.get()); // Visit for(int i=0; i < rec->getNumChildren(); i++) @@ -215,31 +220,36 @@ osg::Node* ConvertFromFLT::visitHeader(osg::Group* osgParent, HeaderRecord* rec) /*osgParent*/ osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* rec) { - ColorPool* pColorPool = _pFltFile->getColorPool(); - if (pColorPool == NULL) - { - _pFltFile->useLocalColorPool(); - pColorPool = _pFltFile->getColorPool(); - } + if (!_pFltFile->useColorPalette()) return NULL; - if (rec->getSize() > sizeof(SOldColorPalette)) + ColorPool* pColorPool = _pFltFile->getColorPool(); + + if (_diOpenFlightVersion > 13) { SColorPalette* pCol = (SColorPalette*)rec->getData(); for (int i=0; i < 1024; i++) - pColorPool->addColor(i, pCol->Colors[i].get()); + { + osg::Vec4 color(pCol->Colors[i].get()); + color[3] = 1.0f; // Force alpha to one + pColorPool->addColor(i, color); + } } else // version 11, 12 & 13 { - SOldColorPalette* pSColor = (SOldColorPalette*)rec->getData(); + SOldColorPalette* pCol = (SOldColorPalette*)rec->getData(); unsigned int i; - for (i=0; i < sizeof(pSColor->Colors)/sizeof(pSColor->Colors[0]); i++) + for (i=0; i < sizeof(pCol->Colors)/sizeof(pCol->Colors[0]); i++) { - pColorPool->addColor(i, pSColor->Colors[i].get()); + osg::Vec4 color(pCol->Colors[i].get()); + color[3] = 1.0f; // Force alpha to one + pColorPool->addColor(i, color); } - for (i=0; i < sizeof(pSColor->FixedColors)/sizeof(pSColor->FixedColors[0]); i++) + for (i=0; i < sizeof(pCol->FixedColors)/sizeof(pCol->FixedColors[0]); i++) { - pColorPool->addColor(i+4096, pSColor->FixedColors[i].get()); + osg::Vec4 color(pCol->FixedColors[i].get()); + color[3] = 1.0f; // Force alpha to one + pColorPool->addColor(i+4096, color); } } @@ -250,12 +260,13 @@ osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* r /*osgParent*/ osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRecord* rec) { + if (!_pFltFile->useMaterialPalette()) return NULL; + SMaterial* pSMaterial = (SMaterial*)rec->getData(); MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); - - if (pSMaterial && pMaterialPool ) + if (pSMaterial && pMaterialPool) { - PoolMaterial* pPoolMat = new PoolMaterial; + MaterialPool::PoolMaterial* pPoolMat = new MaterialPool::PoolMaterial; pPoolMat->Ambient = pSMaterial->Ambient; pPoolMat->Diffuse = pSMaterial->Diffuse; @@ -272,6 +283,8 @@ osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRec /*osgParent*/ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPaletteRecord* rec) { + if (!_pFltFile->useMaterialPalette()) return NULL; + SOldMaterial* pSMaterial = (SOldMaterial*)rec->getData(); MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); @@ -279,7 +292,7 @@ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPale { for (int i=0; i < 64; i++) { - PoolMaterial* pPoolMat = new PoolMaterial; + MaterialPool::PoolMaterial* pPoolMat = new MaterialPool::PoolMaterial; pPoolMat->Ambient = pSMaterial->mat[i].Ambient; pPoolMat->Diffuse = pSMaterial->mat[i].Diffuse; @@ -297,24 +310,39 @@ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPale /*osgParent*/ osg::Node* ConvertFromFLT::visitTexturePalette(osg::Group* , TexturePaletteRecord* rec) { - STexturePalette* pTexture = (STexturePalette*)rec->getData(); + if (!_pFltFile->useTexturePalette()) return NULL; - if (pTexture) + STexturePalette* pTexture = (STexturePalette*)rec->getData(); + TexturePool* pTexturePool = _pFltFile->getTexturePool(); + + if (pTexture && pTexturePool) { - osg::ref_ptr image = osgDB::readImageFile(pTexture->szFilename); - if (image.valid()) + osg::Texture *osgTexture; + + osgTexture = Registry::instance()->getTexture(pTexture->szFilename); + if (osgTexture == NULL) { - osg::Texture *osgTexture = new osg::Texture; - TexturePool* pTexturePool = _pFltFile->getTexturePool(); - if (osgTexture && pTexturePool) + osg::ref_ptr image = osgDB::readImageFile(pTexture->szFilename); + if (image.valid()) { + osgTexture = new osg::Texture; osgTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); osgTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); osgTexture->setImage(image.get()); - pTexturePool->addTexture((int)pTexture->diIndex, osgTexture); + + // set up trilinear filtering. + osgTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR); + osgTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); + + // Add new texture to registry + Registry::instance()->addTexture(pTexture->szFilename, osgTexture); } } + + if (osgTexture) + pTexturePool->addTexture((int)pTexture->diIndex, osgTexture); } + return NULL; } @@ -485,6 +513,7 @@ osg::Node* ConvertFromFLT::visitSwitch(osg::Group* osgParent, SwitchRecord* rec) osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec) { osg::Group* group = new osg::Group; + if (group) { osg::Node* node = visitAncillary(osgParent, rec); @@ -505,6 +534,8 @@ osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec) void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) { + osg::GeoSet* geoSet = pBuilder->getGeoSet(); + osg::StateSet* stateSet = geoSet->getStateSet(); SFace *pSFace = (SFace*)rec->getData(); osg::Vec4 color(1,1,1,1); @@ -513,16 +544,25 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) switch(drawMode) { case FaceRecord::SOLID_BACKFACED: - pBuilder->setCullface(true); + // Enable backface culling + { + osg::CullFace* cullface = new osg::CullFace; + cullface->setMode(osg::CullFace::BACK); + stateSet->setAttributeAndModes(cullface, osg::StateAttribute::ON); + } break; + case FaceRecord::SOLID_NO_BACKFACE: - pBuilder->setCullface(false); + // Disable backface culling + stateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); break; + case FaceRecord::WIREFRAME_NOT_CLOSED: - pBuilder->setPrimType(osg::GeoSet::LINE_STRIP); + geoSet->setPrimType(osg::GeoSet::LINE_STRIP); break; + case FaceRecord::WIREFRAME_CLOSED: - pBuilder->setPrimType(osg::GeoSet::LINE_LOOP); + geoSet->setPrimType(osg::GeoSet::LINE_LOOP); break; } /* @@ -540,24 +580,48 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) } */ - // Lighting + + // Lighting and color binding if (_diOpenFlightVersion > 13) { switch(pSFace->swLightMode) { case FaceRecord::FACE_COLOR: - case FaceRecord::VERTEX_COLOR: - pBuilder->setLighting(false); + // Use face color, not illuminated + stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL ); break; + + case FaceRecord::VERTEX_COLOR: + // Use vertex colors, not illuminated + stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + break; + case FaceRecord::FACE_COLOR_LIGHTING: + // Use face color and vertex normal + stateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL ); + geoSet->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); + break; + case FaceRecord::VERTEX_COLOR_LIGHTING: - pBuilder->setLighting(true); + // Use vertex color and vertex normal + stateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + geoSet->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); break; } } - - // Color + else // Version 11, 12 & 13 { + geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL ); + } + + + // Face Color + { + float alpha = 1.0f; ColorPool* pColorPool = _pFltFile->getColorPool(); if (_diOpenFlightVersion > 13) @@ -577,29 +641,10 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f; color[3] = alpha; - - if (alpha < 1.0f) - pBuilder->setTransparency(true); - - pBuilder->setFaceColor(color); - - switch(pSFace->swLightMode) - { - case FaceRecord::FACE_COLOR: - case FaceRecord::FACE_COLOR_LIGHTING: - pBuilder->setColorBinding(osg::GeoSet::BIND_OVERALL); - break; - - case FaceRecord::VERTEX_COLOR: - case FaceRecord::VERTEX_COLOR_LIGHTING: - pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX); - break; - } } } else // Version 11, 12 & 13 { - float alpha; bool bPackedColor = _bHdrRgbMode || (pColorPool == NULL); if (bPackedColor) @@ -609,20 +654,24 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f; color[3] = alpha; - - if (alpha < 1.0f) - pBuilder->setTransparency(true); - - pBuilder->setColorBinding(osg::GeoSet::BIND_OVERALL); - pBuilder->setFaceColor(color); } + + // Transparency + if (alpha < 1.0f) + { + stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + } + + if (geoSet->getColorBinding() == osg::GeoSet::BIND_OVERALL) + geoSet->setColors( new osg::Vec4(color) ); } // Material MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); if (pMaterialPool) { - PoolMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial); + MaterialPool::PoolMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial); if (pSMaterial) { @@ -656,6 +705,7 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) emissiv[2] = pSMaterial->Emissive[2]; emissiv[3] = alpha; +// osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK, ambient); osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse); osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK, specular); @@ -664,128 +714,146 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) osgMaterial->setShininess(osg::Material::FRONT_AND_BACK, pSMaterial->sfShininess/128.0f); if (alpha < 1.0f) - pBuilder->setTransparency(true); - - switch (pSFace->swLightMode) { - case FaceRecord::VERTEX_COLOR: - case FaceRecord::VERTEX_COLOR_LIGHTING: - osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); - break; - - default: - osgMaterial->setColorMode(osg::Material::OFF); + stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } - pBuilder->setMaterial(osgMaterial); + stateSet->setAttribute(osgMaterial); } } // Subface if (rec->getParent()->isOfType(FACE_OP)) { - pBuilder->setSubface(_nSubfaceLevel); + if (_nSubfaceLevel > 0) + { + osg::PolygonOffset* polyoffset = new osg::PolygonOffset; + if (polyoffset) + { + polyoffset->setFactor(-1.0f*_nSubfaceLevel); + polyoffset->setUnits(-20.0f*_nSubfaceLevel); + stateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); + } + } } // Texture - TexturePool* pTexturePool = _pFltFile->getTexturePool(); - if (pTexturePool) + if (pSFace->iTexturePattern != -1) { - osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern); - if (osgTexture) + TexturePool* pTexturePool = _pFltFile->getTexturePool(); + if (pTexturePool) { - osg::Image* image = osgTexture->getImage(); - if (image) + osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern); + if (osgTexture) { - switch (image->pixelFormat()) + osg::Image* image = osgTexture->getImage(); + if (image) { - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - pBuilder->setTransparency(true); - break; + switch (image->pixelFormat()) + { + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + break; + } } + + geoSet->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); + + // TODO: Crrect when .attr loader implemented + osg::TexEnv* osgTexEnv = new osg::TexEnv; + osgTexEnv->setMode(osg::TexEnv::MODULATE); + stateSet->setAttribute( osgTexEnv ); + stateSet->setAttributeAndModes( osgTexture, osg::StateAttribute::ON ); } - pBuilder->setTexture(osgTexture); } } // Visit vertices - int i; - for(i=0; i < rec->getNumChildren(); i++) + if (_diOpenFlightVersion > 13) { - Record* child = rec->getChild(i); - - if (child) + int i; + for(i=0; i < rec->getNumChildren(); i++) { - int op = child->getOpcode(); - switch (op) + Record* child = rec->getChild(i); + if (child == NULL) break; + + switch (child->getOpcode()) { - case VERTEX_LIST_OP: - visitVertexList(pBuilder, (VertexListRecord*)child); - break; - - case OLD_VERTEX_OP: - pBuilder->addVertex(child); - break; - - case OLD_VERTEX_COLOR_OP: - pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX); - pBuilder->addVertex(child); - break; - - case OLD_VERTEX_COLOR_NORMAL_OP: - pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX); - pBuilder->addVertex(child); - pBuilder->setLighting(true); - break; - } - } - } - - // Add primitive to GeoSet and prepare for next. - pBuilder->addPrimitive(); - - // Look for subfaces - _nSubfaceLevel++; - for(i=0; i < rec->getNumChildren(); i++) - { - Record* child = rec->getChild(i); - - if (child && child->isOfType(FACE_OP)) - visitFace(pBuilder, (FaceRecord*)child); - } - _nSubfaceLevel--; -} - - -void ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec) -{ - int vertices = rec->numberOfVertices(); - - // Add vertices to GeoSetBuilder - if (pBuilder->getPrimType() == osg::GeoSet::POINTS) - { - for (int i=0; i < vertices; i++) - { - Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i)); - if (vertex) - { - pBuilder->setPrimType(osg::GeoSet::POINTS); - pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX); - pBuilder->addVertex(vertex); - pBuilder->addPrimitive(); + case VERTEX_LIST_OP: + pBuilder->addPrimLen( + visitVertexList(pBuilder, (VertexListRecord*)child)); + break; } } } else { - for (int i=0; i < vertices; i++) + int i; + int vertices=0; + for(i=0; i < rec->getNumChildren(); i++) { - Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i)); - if (vertex) - pBuilder->addVertex(vertex); + Record* child = rec->getChild(i); + if (child == NULL) break; + + switch (child->getOpcode()) + { + case OLD_VERTEX_OP: + pBuilder->addVertex(child); + vertices++; + break; + + case OLD_VERTEX_COLOR_OP: + geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + pBuilder->addVertex(child); + vertices++; + break; + + case OLD_VERTEX_COLOR_NORMAL_OP: + geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + pBuilder->addVertex(child); + vertices++; + break; + } } + pBuilder->addPrimLen(vertices); } + + // Add primitives to GeoSet and prepare for next. + pBuilder->addPrimitive(); + + // Look for subfaces + { + int n; + + _nSubfaceLevel++; + for(n=0; ngetNumChildren(); n++) + { + Record* child = rec->getChild(n); + + if (child && child->isOfType(FACE_OP)) + visitFace(pBuilder, (FaceRecord*)child); + } + _nSubfaceLevel--; + } +} + + +int ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec) +{ + osg::GeoSet* geoSet = pBuilder->getGeoSet(); + int vertices = rec->numberOfVertices(); + + // Add vertices to GeoSetBuilder + for (int i=0; i < vertices; i++) + { + Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i)); + if (vertex) + pBuilder->addVertex(vertex); + } + return vertices; } @@ -815,8 +883,7 @@ osg::Node* ConvertFromFLT::visitMatrix(osg::Group* osgParent, MatrixRecord* rec) osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord* rec) { - // SExternalReference *pSExternal = (SExternalReference*)rec->getData(); - + // SExternalReference *pSExternal = (SExternalReference*)rec->getData(); if (osgParent) { osg::Node* node = visitAncillary(osgParent, rec); @@ -840,7 +907,23 @@ osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord* void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec) { - // SLightPoint *pSLightPoint = (SLightPoint*)rec->getData(); + osg::GeoSet* geoSet = pBuilder->getGeoSet(); + osg::StateSet* stateSet = geoSet->getStateSet(); + SLightPoint *pSLightPoint = (SLightPoint*)rec->getData(); + + geoSet->setPrimType(osg::GeoSet::POINTS); + geoSet->setColorBinding(osg::GeoSet::BIND_PERVERTEX); + + osg::Point* point = new osg::Point; + if (point) + { + point->setSize( pSLightPoint->sfSize ); + stateSet->setAttributeAndModes( point, osg::StateAttribute::ON ); +// point->setFadeThresholdSize(const float fadeThresholdSize); +// point->setDistanceAttenuation(const Vec3& distanceAttenuation); +// point->setStateSetModes(*stateSet,const GLModeValue value); // GL_POINT_SMOOTH + + } // Visit vertices for(int i=0; i < rec->getNumChildren(); i++) @@ -853,22 +936,22 @@ void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* switch (op) { case VERTEX_LIST_OP: - pBuilder->setPrimType(osg::GeoSet::POINTS); - visitVertexList(pBuilder, (VertexListRecord*)child); + { + int vertices = visitVertexList(pBuilder, (VertexListRecord*)child); + for (int v=0; vaddPrimLen(1); + } break; case OLD_VERTEX_OP: - pBuilder->addVertex(child); - pBuilder->addPrimitive(); - break; - case OLD_VERTEX_COLOR_OP: case OLD_VERTEX_COLOR_NORMAL_OP: - pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX); pBuilder->addVertex(child); - pBuilder->addPrimitive(); + pBuilder->addPrimLen(1); break; } } } + + pBuilder->addPrimitive(); } diff --git a/src/osgPlugins/flt/flt2osg.h b/src/osgPlugins/flt/flt2osg.h index 853ab9e55..32cc18979 100644 --- a/src/osgPlugins/flt/flt2osg.h +++ b/src/osgPlugins/flt/flt2osg.h @@ -3,13 +3,15 @@ #ifndef __FLT_2_OSG_H #define __FLT_2_OSG_H -#include -#include -#include - +#include #include #include "Record.h" +#include "FltFile.h" + +#include +#include +#include namespace osg { @@ -51,66 +53,64 @@ class VertexListRecord; class LongIDRecord; class GeoSetBuilder; -class FltFile; struct SMaterial; class ConvertFromFLT { -public: + public: - ConvertFromFLT(FltFile* pFltFile); - virtual ~ConvertFromFLT(); + ConvertFromFLT(FltFile* pFltFile); + virtual ~ConvertFromFLT(); - osg::Node* convert(Record* rec); + osg::Node* convert(Record* rec); - osg::Node* visitNode(osg::Group* osgParent,Record* rec); - osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec); - osg::Node* visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec); + osg::Node* visitNode(osg::Group* osgParent,Record* rec); + osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec); + osg::Node* visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec); - osg::Node* visitLongID(osg::Group* osgParent, LongIDRecord* rec); + osg::Node* visitLongID(osg::Group* osgParent, LongIDRecord* rec); - osg::Node* visitHeader(osg::Group* osgParent, HeaderRecord* rec); - osg::Node* visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec); - osg::Node* visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec); - osg::Node* visitOldMaterialPalette(osg::Group* osgParent, OldMaterialPaletteRecord* rec); - osg::Node* visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec); - osg::Node* visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec); - osg::Node* visitVertex(osg::Group* osgParent, VertexRecord* rec); - osg::Node* visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec); - osg::Node* visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec); - osg::Node* visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec); - osg::Node* visitGroup(osg::Group* osgParent, GroupRecord* rec); - osg::Node* visitLOD(osg::Group* osgParent, LodRecord* rec); - osg::Node* visitOldLOD(osg::Group* osgParent, OldLodRecord* rec); - osg::Node* visitDOF(osg::Group* osgParent, DofRecord* rec); - osg::Node* visitSwitch(osg::Group* osgParent, SwitchRecord* rec); - osg::Node* visitObject(osg::Group* osgParent, ObjectRecord* rec); - osg::Node* visitMatrix(osg::Group* osgParent, MatrixRecord* rec); - osg::Node* visitExternal(osg::Group* osgParent, ExternalRecord* rec); + osg::Node* visitHeader(osg::Group* osgParent, HeaderRecord* rec); + osg::Node* visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec); + osg::Node* visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec); + osg::Node* visitOldMaterialPalette(osg::Group* osgParent, OldMaterialPaletteRecord* rec); + osg::Node* visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec); + osg::Node* visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec); + osg::Node* visitVertex(osg::Group* osgParent, VertexRecord* rec); + osg::Node* visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec); + osg::Node* visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec); + osg::Node* visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec); + osg::Node* visitGroup(osg::Group* osgParent, GroupRecord* rec); + osg::Node* visitLOD(osg::Group* osgParent, LodRecord* rec); + osg::Node* visitOldLOD(osg::Group* osgParent, OldLodRecord* rec); + osg::Node* visitDOF(osg::Group* osgParent, DofRecord* rec); + osg::Node* visitSwitch(osg::Group* osgParent, SwitchRecord* rec); + osg::Node* visitObject(osg::Group* osgParent, ObjectRecord* rec); + osg::Node* visitMatrix(osg::Group* osgParent, MatrixRecord* rec); + osg::Node* visitExternal(osg::Group* osgParent, ExternalRecord* rec); - void visitFace(GeoSetBuilder* pParent, FaceRecord* rec); - void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec); - void visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec); + void visitFace(GeoSetBuilder* pParent, FaceRecord* rec); + void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec); + int visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec); -private: + private: - Record* getVertexFromPool(int nOffset); - void regisiterVertex(int nOffset, Record* pRec); + Record* getVertexFromPool(int nOffset); + void regisiterVertex(int nOffset, Record* pRec); - typedef std::map VertexPaletteOffsetMap; - VertexPaletteOffsetMap _VertexPaletteOffsetMap; + typedef std::map VertexPaletteOffsetMap; + VertexPaletteOffsetMap _VertexPaletteOffsetMap; - FltFile* _pFltFile; - - int _diOpenFlightVersion; - int _diCurrentOffset; - unsigned short _wObjTransparency; - int _nSubfaceLevel; - float _sfHdrUnitScale; // iMultDivUnit - bool _bHdrRgbMode; + osg::ref_ptr _pFltFile; + int _diOpenFlightVersion; + int _diCurrentOffset; + unsigned short _wObjTransparency; + int _nSubfaceLevel; + float _sfHdrUnitScale; // iMultDivUnit + bool _bHdrRgbMode; };