diff --git a/src/osgPlugins/flt/ColorPaletteRecord.cpp b/src/osgPlugins/flt/ColorPaletteRecord.cpp index c4210440d..b9bd45bdd 100644 --- a/src/osgPlugins/flt/ColorPaletteRecord.cpp +++ b/src/osgPlugins/flt/ColorPaletteRecord.cpp @@ -29,24 +29,31 @@ ColorPaletteRecord::~ColorPaletteRecord() // virtual void ColorPaletteRecord::endian() { - if (getSize() > sizeof(SOldColorPalette)) + int flightVersion = getFlightVersion(); + + if (flightVersion > 13) { +// TODO: May cause crash on win32 +// It's only color names so we ignore +#if 0 SColorPalette* pSColor = (SColorPalette*)getData(); size_t nOffset = sizeof(SColorPalette); - if (nOffset < getSize()) + if ((nOffset < getSize()) + && (flightVersion >= 1500)) { int n = 0; ENDIAN( pSColor->nNames ); while ((n++ < pSColor->nNames) && (nOffset < getSize())) { - SColorName* pName = (SColorName*)((char*)getData())+nOffset; + SColorName* pName = (SColorName*)((char*)pSColor)+nOffset; ENDIAN( pName->swSize ); ENDIAN( pName->nIndex ); nOffset += pName->swSize; }; } +#endif } else // version 11, 12 & 13 { diff --git a/src/osgPlugins/flt/ColorPaletteRecord.h b/src/osgPlugins/flt/ColorPaletteRecord.h index 6f75ee689..dbeab0aaa 100644 --- a/src/osgPlugins/flt/ColorPaletteRecord.h +++ b/src/osgPlugins/flt/ColorPaletteRecord.h @@ -54,6 +54,7 @@ class ColorPaletteRecord : public AncillaryRecord virtual Record* clone() const { return new ColorPaletteRecord(); } virtual const char* className() const { return "ColorPaletteRecord"; } virtual int classOpcode() const { return COLOR_PALETTE_OP; } +// virtual size_t sizeofData() const { return sizeof(SColorPalette); } virtual void accept(RecordVisitor& rv) { rv.apply(*this); } // virtual void traverse(RecordVisitor& rv); diff --git a/src/osgPlugins/flt/ExternalRecord.cpp b/src/osgPlugins/flt/ExternalRecord.cpp index 004546d7e..f05a663a1 100644 --- a/src/osgPlugins/flt/ExternalRecord.cpp +++ b/src/osgPlugins/flt/ExternalRecord.cpp @@ -36,12 +36,8 @@ void ExternalRecord::endian() { SExternalReference *pSExternal = (SExternalReference*)getData(); - if (getSize() >= sizeof(SExternalReference)) + if (getFlightVersion() > 13) { - ENDIAN( pSExternal->diFlags ); - } - else - { - pSExternal->diFlags = 0; + ENDIAN( pSExternal->dwFlags ); } } diff --git a/src/osgPlugins/flt/ExternalRecord.h b/src/osgPlugins/flt/ExternalRecord.h index 7f64ac28d..d67b00a8b 100644 --- a/src/osgPlugins/flt/ExternalRecord.h +++ b/src/osgPlugins/flt/ExternalRecord.h @@ -15,18 +15,18 @@ namespace flt { struct SExternalReference { SRecHeader RecHeader; - char szPath[200]; // 199 char ASCII Path; 0 terminates + char szPath[200]; // 199 char ASCII Path; 0 terminates // version 11, 12 & 13 stops here! - uint8 swReserved[4]; // Reserved - int32 diFlags; // Flags (bits from left to right) - // 0 = Color Palette Override - // 1 = Material Palette Override - // 2 = Texture Palette Override - // 3 = Line Palette Override - // 4 = Sound Palette Override - // 5 = Light source Palette Override - // 6-31 Spare -// int16 iReserved; // Reserved + uint8 swReserved[4]; // Reserved + uint32 dwFlags; // Flags (bits from left to right) + // 0 = Color Palette Override + // 1 = Material Palette Override + // 2 = Texture Palette Override + // 3 = Line Palette Override + // 4 = Sound Palette Override + // 5 = Light source Palette Override + // 6-31 Spare +// int16 iReserved; // Reserved }; @@ -47,6 +47,16 @@ class ExternalRecord : public PrimNodeRecord FltFile* getExternal() { return _fltfile.get(); } const std::string getFilename( void ) const { return std::string(getData()->szPath); } + enum Flag + { + COLOR_PALETTE_OVERRIDE = BIT31, + MATERIAL_PALETTE_OVERRIDE = BIT30, + TEXTURE_PALETTE_OVERRIDE = BIT29, + LINESTYLE_PALETTE_OVERRIDE = BIT28, + SOUND_PALETTE_OVERRIDE = BIT27, + LIGHTSOURCE_PALETTE_OVERRIDE = BIT26 + }; + protected: virtual ~ExternalRecord(); diff --git a/src/osgPlugins/flt/FaceRecord.cpp b/src/osgPlugins/flt/FaceRecord.cpp index 91f554144..d2b8c4934 100644 --- a/src/osgPlugins/flt/FaceRecord.cpp +++ b/src/osgPlugins/flt/FaceRecord.cpp @@ -68,8 +68,8 @@ void FaceRecord::endian() ENDIAN( pSFace->diIRMaterial ); ENDIAN( pSFace->wTransparency ); - // Added after version 13 - if (Registry::instance()->getVersion() > 13) + // Face record extended after version 13 + if (getFltFile()->getFlightVersion() > 13) { ENDIAN( pSFace->dwFlags ); // ENDIAN( pSFace->PrimaryPackedColor ); @@ -93,12 +93,12 @@ bool FaceRecord::readLocalData(Input& fr) Record* pRec; - if (!(pRec=fr.readCreateRecord())) return false; + if (!(pRec=fr.readCreateRecord(_pFltFile))) return false; if (pRec->getOpcode() != PUSH_SUBFACE_OP) return fr.rewindLast(); - while ((pRec=fr.readCreateRecord())) + while ((pRec=fr.readCreateRecord(_pFltFile))) { if (pRec->getOpcode()==POP_SUBFACE_OP) return true; diff --git a/src/osgPlugins/flt/FaceRecord.h b/src/osgPlugins/flt/FaceRecord.h index cb00d23db..828f0e945 100644 --- a/src/osgPlugins/flt/FaceRecord.h +++ b/src/osgPlugins/flt/FaceRecord.h @@ -53,7 +53,8 @@ struct SFace uint16 wTransparency; // Transparency // = 0 opaque // = 65535 for totally clear - // version 11, 12 & 13 stops here! + // version 11, 12 & 13 ends here! + uint8 swInfluenceLODGen; // LOD Generation Control uint8 swLinestyle; // Linestyle Index uint32 dwFlags; // Flags (bits from left to right) @@ -70,9 +71,9 @@ struct SFace // = 2 use face color and vertex normal // = 3 use vertex color and vertex normal - uint8 Reserved1[7]; // Reserved - color32 PrimaryPackedColor; // Packed Color Primary (A, B, G, R) - color32 SecondaryPackedColor; // Packed Color Secondary (A, B, G, R) + uint8 Reserved1[7]; // Reserved + color32 PrimaryPackedColor; // Packed Color Primary (A, B, G, R) + color32 SecondaryPackedColor; // Packed Color Secondary (A, B, G, R) int16 iTextureMapIndex; // Texture mapping index int16 iReserved2; uint32 dwPrimaryColorIndex; diff --git a/src/osgPlugins/flt/FltFile.cpp b/src/osgPlugins/flt/FltFile.cpp index e9c7adcca..61cadbda6 100644 --- a/src/osgPlugins/flt/FltFile.cpp +++ b/src/osgPlugins/flt/FltFile.cpp @@ -11,6 +11,7 @@ #include #include +#include #include @@ -23,44 +24,42 @@ FltFile::FltFile( TexturePool* pTexturePool, MaterialPool* pMaterialPool) { - _pHeaderRecord = NULL; - if (pColorPool) { // use external color palette, ignore internal - _useColorPalette = false; + _useInternalColorPalette = false; setColorPool( pColorPool ); } else { // use internal color palette - _useColorPalette = true; + _useInternalColorPalette = true; setColorPool( new ColorPool ); } if (pTexturePool) { // use external texture palette, ignore internal - _useTexturePalette = false; + _useInternalTexturePalette = false; setTexturePool( pTexturePool ); } else { // use internal texture palette - _useTexturePalette = true; + _useInternalTexturePalette = true; setTexturePool( new TexturePool ); } if (pMaterialPool) { // use external material palette, ignore internal - _useMaterialPalette = false; + _useInternalMaterialPalette = false; setMaterialPool( pMaterialPool ); } else { // use internal material palette - _useMaterialPalette = true; + _useInternalMaterialPalette = true; setMaterialPool( new MaterialPool ); } } @@ -74,46 +73,44 @@ osg::Object* FltFile::readObject(const std::string& fileName) osg::Node* FltFile::readNode(const std::string& fileName) { - osg::Node* node = NULL; - Record* pRootRec = readModel(fileName); + _directory = osgDB::getFilePath(fileName); - if (pRootRec == NULL) - return NULL; + if (readModel(fileName)) + { + // Convert record tree to osg scene graph + return convert(); + } - // Convert record tree to osg scene graph - node = convert(); - - pRootRec->unref(); // delete record tree - - return node; + return NULL; } osg::Node* FltFile::convert() { - ConvertFromFLT visit(this); + ConvertFromFLT visit; return visit.convert(getHeaderRecord()); } // Read flight model (include externals) -Record* FltFile::readModel(const std::string& fileName) +bool FltFile::readModel(const std::string& fileName) { - Record* pRec = readFile(fileName); - if (pRec == NULL) return NULL; - - readExternals(pRec); - return pRec; + if (readFile(fileName)) + { + readExternals(); + return getHeaderRecord() ? true : false; + } + return false; } -Record* FltFile::readFile(const std::string& fileName) +bool FltFile::readFile(const std::string& fileName) { FileInput fin; if (!fin.open(fileName)) { - // ok havn't found file, resort to using findFile... + // havn't found file, look in OSGFILEPATH char* newFileName = osgDB::findFile(fileName.c_str()); if (!newFileName) return NULL; @@ -122,99 +119,99 @@ Record* FltFile::readFile(const std::string& fileName) osg::notify(osg::INFO) << "Loading " << fileName << " ... " << endl; - Record* pRec = fin.readCreateRecord(); - _pHeaderRecord = pRec; + Record* pRec = fin.readCreateRecord(this); if (pRec == NULL) { osg::notify(osg::WARN) << "File not found " << fileName << endl; - return NULL; + return false; } + _headerRecord = (HeaderRecord*)pRec; if (pRec->isPrimaryNode()) // Header pRec->readLocalData(fin);// Read rest of file fin.close(); - return pRec; + return true; } #define REGISTER_FLT 1 -class ReadExternal : public RecordVisitor +void FltFile::readExternals() { - public: - ReadExternal(FltFile* fltFile) - { - _parentFltFile = fltFile; - setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN); - } - - virtual void apply(ExternalRecord& rec) - { - SExternalReference* pSExternal = (SExternalReference*)rec.getData(); - - if (pSExternal) - { - FltFile* flt = NULL; - ColorPool* pColorPool = NULL; - TexturePool* pTexturePool = NULL; - MaterialPool* pMaterialPool = NULL; - std::string filename(pSExternal->szPath); - - osg::notify(osg::INFO) << "External=" << filename << endl; - - 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 = 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); - } - } - - public: - - FltFile* _parentFltFile; -}; - - -void FltFile::readExternals(Record* pRec) -{ - - if (pRec) + class ReadExternal : public RecordVisitor { - ReadExternal visitor(this); - pRec->accept(visitor); - } + public: + ReadExternal(FltFile* fltFile) + { + _pFltFile = fltFile; + setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN); + } + + virtual void apply(ExternalRecord& rec) + { + SExternalReference* pSExternal = (SExternalReference*)rec.getData(); + + if (pSExternal) + { + FltFile* pExternalFltFile = NULL; + ColorPool* pColorPool = NULL; + TexturePool* pTexturePool = NULL; + MaterialPool* pMaterialPool = NULL; + std::string filename(pSExternal->szPath); + + osg::notify(osg::INFO) << "External=" << filename << endl; + + if (rec.getFlightVersion() > 13) + { + if (pSExternal->dwFlags & ExternalRecord::COLOR_PALETTE_OVERRIDE) + pColorPool = NULL; + else + pColorPool = _pFltFile->getColorPool(); + + if (pSExternal->dwFlags & ExternalRecord::TEXTURE_PALETTE_OVERRIDE) + pTexturePool = NULL; + else + pTexturePool = _pFltFile->getTexturePool(); + + if (pSExternal->dwFlags & ExternalRecord::MATERIAL_PALETTE_OVERRIDE) + pMaterialPool = NULL; + else + pMaterialPool = _pFltFile->getMaterialPool(); + } + + #if REGISTER_FLT + pExternalFltFile = Registry::instance()->getFltFile(filename); + if (pExternalFltFile == NULL) + { + pExternalFltFile = new FltFile(pColorPool, pTexturePool, pMaterialPool); + pExternalFltFile->readModel(filename); + } + Registry::instance()->addFltFile(filename, pExternalFltFile); + #else + pExternalFltFile = new FltFile(pColorPool, pTexturePool, pMaterialPool); + pExternalFltFile->readModel(filename); + #endif + rec.setExternal(pExternalFltFile); + } + } + + public: + + FltFile* _pFltFile; + }; + + ReadExternal visitor(this); + _headerRecord->accept(visitor); } int FltFile::getFlightVersion() { - if (_pHeaderRecord) + if (_headerRecord.get()) { - SHeader* pSHeader = (SHeader*)_pHeaderRecord->getData(); + SHeader* pSHeader = (SHeader*)_headerRecord.get()->getData(); if (pSHeader) return pSHeader->diFormatRevLev; } diff --git a/src/osgPlugins/flt/FltFile.h b/src/osgPlugins/flt/FltFile.h index 4202324e9..653fed328 100644 --- a/src/osgPlugins/flt/FltFile.h +++ b/src/osgPlugins/flt/FltFile.h @@ -29,8 +29,7 @@ class FltFile : public osg::Referenced 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); + bool readModel(const std::string& fileName); ColorPool* getColorPool() { return _colorPool.get(); } TexturePool* getTexturePool() { return _texturePool.get(); } @@ -40,27 +39,30 @@ class FltFile : public osg::Referenced void setTexturePool(TexturePool* texturePool) { _texturePool = texturePool; } void setMaterialPool(MaterialPool* materialPool){ _materialPool = materialPool; } - inline const bool useColorPalette() const { return _useColorPalette; } - inline const bool useTexturePalette() const { return _useTexturePalette; } - inline const bool useMaterialPalette() const { return _useMaterialPalette; } + inline const bool useInternalColorPalette() const { return _useInternalColorPalette; } + inline const bool useInternalTexturePalette() const { return _useInternalTexturePalette; } + inline const bool useInternalMaterialPalette() const { return _useInternalMaterialPalette; } int getFlightVersion(); + inline HeaderRecord* getHeaderRecord() { return _headerRecord.get(); } protected: virtual ~FltFile() {} - Record* readFile(const std::string& fileName); - void readExternals(Record* pRec); + bool readFile(const std::string& fileName); + void readExternals(); private: - Record* _pHeaderRecord; + osg::ref_ptr _headerRecord; - bool _useColorPalette; - bool _useTexturePalette; - bool _useMaterialPalette; + bool _useInternalColorPalette; + bool _useInternalTexturePalette; + bool _useInternalMaterialPalette; + std::string _directory; + 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 061a87ab9..c2c18cbc5 100644 --- a/src/osgPlugins/flt/GeoSetBuilder.cpp +++ b/src/osgPlugins/flt/GeoSetBuilder.cpp @@ -8,9 +8,6 @@ #include "FltFile.h" #include "Pool.h" #include "opcodes.h" -#include "VertexPoolRecords.h" -#include "OldVertexRecords.h" -#include "MaterialPaletteRecord.h" #include "GeoSetBuilder.h" #include @@ -35,323 +32,91 @@ using namespace flt; //////////////////////////////////////////////////////////////////// // -// TmpGeoSet +// DynGeoSet // //////////////////////////////////////////////////////////////////// -// GeoSet with dynamic vertex size. -TmpGeoSet::TmpGeoSet(FltFile* pFltFile) +#define APPEND_DynGeoSet_List(list) \ + if (source->list.size() > 0) \ + list.insert(list.end(), \ + source->list.begin(), source->list.end()); + + +void DynGeoSet::append(DynGeoSet* source) { - _geoSet = new osg::GeoSet; - _geoSet->setStateSet( new osg::StateSet ); - - _colorPool = pFltFile->getColorPool(); - _texturePool = pFltFile->getTexturePool(); - _materialPool = pFltFile->getMaterialPool(); + APPEND_DynGeoSet_List(_primLenList) + APPEND_DynGeoSet_List(_coordList) + APPEND_DynGeoSet_List(_normalList) + APPEND_DynGeoSet_List(_colorList) + APPEND_DynGeoSet_List(_tcoordList) } -osg::GeoSet* TmpGeoSet::createOsgGeoSet() +#define VERIFY_DynGeoSet_Binding(binding,list) \ + switch (binding) \ + { \ + case osg::GeoSet::BIND_PERVERTEX: \ + if (list.size() < _coordList.size()) { \ + binding = osg::GeoSet::BIND_OFF; \ + list.clear(); } \ + break; \ + case osg::GeoSet::BIND_PERPRIM: \ + if (list.size() < _primLenList.size()) { \ + binding = osg::GeoSet::BIND_OFF; \ + list.clear(); } \ + break; \ + case osg::GeoSet::BIND_OVERALL: \ + if (list.size() < 1) { \ + binding = osg::GeoSet::BIND_OFF; \ + list.clear(); } \ + break; \ + } + +void DynGeoSet::setBinding() { - int prims = _primLenList.size(); - int indices = _vertexRecList.size(); + VERIFY_DynGeoSet_Binding(_normal_binding, _normalList) + VERIFY_DynGeoSet_Binding(_color_binding, _colorList) + VERIFY_DynGeoSet_Binding(_texture_binding, _tcoordList) - if (prims==0 || indices==0) - return NULL; + // Set bindings + setNormalBinding(_normal_binding); + setColorBinding(_color_binding); + setTextureBinding(_texture_binding); - osg::GeoSet* gset = getGeoSet(); - - gset->setNumPrims(prims); - - // prim lengths - switch( gset->getPrimType() ) + osg::StateSet* stateset = getStateSet(); + if (stateset) { - 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; + if (_normal_binding == osg::GeoSet::BIND_OFF) + stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); } - - // 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) +bool DynGeoSet::setLists() { - osg::Vec3* coords = gset->getCoords(); - osg::Vec4* colors = gset->getColors(); - osg::Vec3* normals = gset->getNormals(); - osg::Vec2* texuv = gset->getTextureCoords(); - - switch(vertex->getOpcode()) + if ((_primLenList.size() > 0) && (_coordList.size() > 0)) { - case VERTEX_C_OP: - { - SVertex* pVert = (SVertex*)vertex->getData(); + GeoSet::setPrimLengths(_primLenList.begin()); + GeoSet::setCoords(_coordList.begin()); - coords[index].set( - (float)pVert->Coord.x(), - (float)pVert->Coord.y(), - (float)pVert->Coord.z()); + if ((_normalList.size() > 0) + && (getNormalBinding() != osg::GeoSet::BIND_OFF)) + GeoSet::setNormals(_normalList.begin()); - 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; + if ((_colorList.size() > 0) + && (getColorBinding() != osg::GeoSet::BIND_OFF)) + GeoSet::setColors(_colorList.begin()); - case VERTEX_CN_OP: - { - SNormalVertex* pVert = (SNormalVertex*)vertex->getData(); + if ((_tcoordList.size() > 0) + && (getTextureBinding() != osg::GeoSet::BIND_OFF)) + GeoSet::setTextureCoords(_tcoordList.begin()); - 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; + return true; } -} + return false; +} //////////////////////////////////////////////////////////////////// @@ -363,108 +128,77 @@ void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex) // OpenFlight don't save data in GeoSets. This class tries to find // existing GeoSets with matching state before creating a new GeoSet. -GeoSetBuilder::GeoSetBuilder(FltFile* pFltFile) +GeoSetBuilder::GeoSetBuilder(osg::Geode* geode) { - _pFltFile = pFltFile; + _geode = geode; initPrimData(); } - void GeoSetBuilder::initPrimData() { - _tmpGeoSet = new TmpGeoSet(_pFltFile.get()); + _dynGeoSet = new DynGeoSet; + _dynGeoSet->setStateSet(new osg::StateSet); } -// Convert flt::TmpGeoSet's to osg::GeoSet's and add to osg::Geode. -// If geode parameter is NULL create new. -// If geode created inside this function and no osg::GeoSet's -// added free geode. -osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode) +osg::Geode* GeoSetBuilder::createOsgGeoSets() { - bool bInternalGeodeAllocation = false; - - if (geode == NULL) - { - geode = new osg::Geode; - bInternalGeodeAllocation = true; - } - - for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin(); - itr!=_tmpGeoSetList.end(); + for(DynGeoSetList::iterator itr=_dynGeoSetList.begin(); + itr!=_dynGeoSetList.end(); ++itr) { - osg::GeoSet* gset = (*itr)->createOsgGeoSet(); - if (gset) - geode->addDrawable(gset); + DynGeoSet* dgset = itr->get(); + if (dgset) + { + int prims = dgset->primLenListSize(); + if (prims > 0) + { + dgset->setLists(); + dgset->setNumPrims(prims); + _geode.get()->addDrawable(dgset); + } + } } - if (bInternalGeodeAllocation && (geode->getNumDrawables() == 0)) - { - geode->unref(); - return NULL; - } - - return geode; + return _geode.get(); } bool GeoSetBuilder::addPrimitive() { - osg::GeoSet* geoset = getGeoSet(); + DynGeoSet* dgset = getDynGeoSet(); // This is the new geoset we want to add - if (geoset->getPrimType() == osg::GeoSet::NO_TYPE) - geoset->setPrimType(findPrimType(numberOfVertices())); + if (dgset->getPrimType() == osg::GeoSet::NO_TYPE) + dgset->setPrimType(findPrimType(dgset->coordListSize())); // Still no primitive type? - if (geoset->getPrimType() == osg::GeoSet::NO_TYPE) + if (dgset->getPrimType() == osg::GeoSet::NO_TYPE) return false; - TmpGeoSet* match = findMatchingGeoSet(); + dgset->setBinding(); + + DynGeoSet* match = findMatchingGeoSet(); if (match) - // append vertices and prim length to match - match->addVertices( _tmpGeoSet.get() ); + match->append(dgset); else - // add new GeoSet+StateSet compination - _tmpGeoSetList.push_back(_tmpGeoSet.get()); - - initPrimData(); // initialize _tmpGeoSet + _dynGeoSetList.push_back(dgset); + initPrimData(); // initialize _dynGeoSet return true; } -TmpGeoSet* GeoSetBuilder::findMatchingGeoSet() +DynGeoSet* GeoSetBuilder::findMatchingGeoSet() { - osg::GeoSet* geoSet = getGeoSet(); - osg::StateSet* stateSet = geoSet->getStateSet(); - - for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin(); - itr!=_tmpGeoSetList.end(); + DynGeoSet* new_dgset = getDynGeoSet(); + for(DynGeoSetList::iterator itr=_dynGeoSetList.begin(); + itr!=_dynGeoSetList.end(); ++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; - } + DynGeoSet* dgset = itr->get(); + if (*new_dgset == *dgset) + return dgset; } return NULL; @@ -473,28 +207,16 @@ TmpGeoSet* GeoSetBuilder::findMatchingGeoSet() osg::GeoSet::PrimitiveType GeoSetBuilder::findPrimType(const int nVertices) { - osg::GeoSet::PrimitiveType primtype = osg::GeoSet::NO_TYPE; - switch (nVertices) { - case 1: - primtype = osg::GeoSet::POINTS; - break; - case 2: - primtype = osg::GeoSet::LINES; - break; - case 3: - primtype = osg::GeoSet::TRIANGLES; - break; - case 4: - primtype = osg::GeoSet::QUADS; - break; - default: - if (nVertices >= 5) primtype = osg::GeoSet::POLYGON; - break; + case 1: return osg::GeoSet::POINTS; + case 2: return osg::GeoSet::LINES; + case 3: return osg::GeoSet::TRIANGLES; + case 4: return osg::GeoSet::QUADS; } - return primtype; + if (nVertices >= 5) return osg::GeoSet::POLYGON; + return osg::GeoSet::NO_TYPE; } diff --git a/src/osgPlugins/flt/GeoSetBuilder.h b/src/osgPlugins/flt/GeoSetBuilder.h index 830b0295c..dc3352e46 100644 --- a/src/osgPlugins/flt/GeoSetBuilder.h +++ b/src/osgPlugins/flt/GeoSetBuilder.h @@ -2,11 +2,11 @@ #define __FLT_GEOSETBUILDER_H #include -#include #include #include #include #include +#include #include #include @@ -20,63 +20,85 @@ class Record; class TmpGeoSet; + //////////////////////////////////////////////////////////////////// // -// TmpGeoSet +// DynGeoSet // //////////////////////////////////////////////////////////////////// +#if 0 +# define COMPARE_DynGeoSet_Parameter(parameter) \ + if (parameter(obj)!=NULL; } + virtual const char* className() const { return "DynGeoSet"; } - void addVertex(Record* vertexRec) { _vertexRecList.push_back(vertexRec); } - void addPrimLen(int len) { _primLenList.push_back(len); } - - // Append vertices from other TmpGeoSet - void addVertices(TmpGeoSet* source) + int compare(const DynGeoSet& rhs) const { - _vertexRecList.insert(_vertexRecList.end(), - source->_vertexRecList.begin(), source->_vertexRecList.end()); - _primLenList.insert(_primLenList.end(), - source->_primLenList.begin(), source->_primLenList.end()); + COMPARE_DynGeoSet_Parameter(_primtype) + COMPARE_DynGeoSet_Parameter(_color_binding) + COMPARE_DynGeoSet_Parameter(_normal_binding) + COMPARE_DynGeoSet_Parameter(_texture_binding) + + if ((_color_binding == osg::GeoSet::BIND_OVERALL) + && (_colorList.size() >= 1) && (rhs._colorList.size() >= 1) + && (_colorList[0] != rhs._colorList[0])) + return -1; + + return getStateSet()->compare(*rhs.getStateSet(), true); } + + bool operator < (const DynGeoSet& rhs) const { return compare(rhs)<0; } + bool operator == (const DynGeoSet& rhs) const { return compare(rhs)==0; } + bool operator != (const DynGeoSet& rhs) const { return compare(rhs)!=0; } - inline const int numberOfVertices() const { return _vertexRecList.size(); } - inline osg::GeoSet* getGeoSet() { return _geoSet.get(); } - inline const osg::GeoSet* getGeoSet() const { return _geoSet.get(); } + inline void addPrimLen(const int len) { _primLenList.push_back(len); } + inline void addCoord(const osg::Vec3& coord) { _coordList.push_back(coord); } + inline void addNormal(const osg::Vec3& normal) { _normalList.push_back(normal); } + inline void addColor(const osg::Vec4& color) { _colorList.push_back(color); } + inline void addTCoord(const osg::Vec2& tcoord) { _tcoordList.push_back(tcoord); } - // Create complete osg::GeoSet. - osg::GeoSet* createOsgGeoSet(); + void append(DynGeoSet* source); + void setBinding(); + bool setLists(); + + inline const int primLenListSize() const { return _primLenList.size(); } + inline const int coordListSize() const { return _coordList.size(); } + inline const int normalListSize() const { return _normalList.size(); } + inline const int colorListSize() const { return _colorList.size(); } + inline const int tcoordListSize() const { return _tcoordList.size(); } 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; + typedef std::vector PrimLenList; + typedef std::vector CoordList; + typedef std::vector NormalList; + typedef std::vector ColorList; + typedef std::vector TcoordList; + PrimLenList _primLenList; + CoordList _coordList; + NormalList _normalList; + ColorList _colorList; + TcoordList _tcoordList; }; - //////////////////////////////////////////////////////////////////// // // GeoSetBuilder @@ -91,32 +113,28 @@ class GeoSetBuilder { public: - GeoSetBuilder(FltFile* pFltFile); + GeoSetBuilder(osg::Geode* geode); 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); + osg::Geode* createOsgGeoSets(); - 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(); } + inline DynGeoSet* getDynGeoSet() { return _dynGeoSet.get(); } + inline const DynGeoSet* getDynGeoSet() const { return _dynGeoSet.get(); } protected: void initPrimData(); - TmpGeoSet* findMatchingGeoSet(); + DynGeoSet* findMatchingGeoSet(); osg::GeoSet::PrimitiveType findPrimType(const int nVertices); private: - osg::ref_ptr _pFltFile; - osg::ref_ptr _tmpGeoSet; + osg::ref_ptr _geode; + osg::ref_ptr _dynGeoSet; - typedef std::vector > TmpGeoSetList; - TmpGeoSetList _tmpGeoSetList; + typedef std::vector > DynGeoSetList; + DynGeoSetList _dynGeoSetList; }; diff --git a/src/osgPlugins/flt/HeaderRecord.cpp b/src/osgPlugins/flt/HeaderRecord.cpp index abed1b5c6..dd94c12be 100644 --- a/src/osgPlugins/flt/HeaderRecord.cpp +++ b/src/osgPlugins/flt/HeaderRecord.cpp @@ -117,8 +117,6 @@ 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 4509ab378..a5de99853 100644 --- a/src/osgPlugins/flt/HeaderRecord.h +++ b/src/osgPlugins/flt/HeaderRecord.h @@ -99,6 +99,15 @@ class HeaderRecord : public PrimNodeRecord SHeader* getData() const { return (SHeader*)_pData; } virtual const std::string getName( void ) const { return std::string(getData()->szIdent); } + enum CoordUnit + { + METERS = 0, + KILOMETERS = 1, + FEET = 4, + INCHES = 5, + NAUTICAL_MILES = 8 + }; + protected: virtual ~HeaderRecord(); diff --git a/src/osgPlugins/flt/Input.cpp b/src/osgPlugins/flt/Input.cpp index bbd545ee3..a4e7e75c5 100644 --- a/src/osgPlugins/flt/Input.cpp +++ b/src/osgPlugins/flt/Input.cpp @@ -23,6 +23,7 @@ using namespace std; using namespace flt; + FileInput::FileInput() { _init(); @@ -165,7 +166,7 @@ SRecHeader* FileInput::readRecord() } -Record* Input::readCreateRecord() +Record* Input::readCreateRecord(FltFile* pFltFile) { SRecHeader* pData = readRecord(); @@ -194,6 +195,8 @@ Record* Input::readCreateRecord() return NULL; } + pRec->_pFltFile = pFltFile; + #if 0 osg::notify(osg::ALWAYS) << "class=" << pRec->className(); osg::notify(osg::ALWAYS) << " op=" << pRec->getOpcode(); diff --git a/src/osgPlugins/flt/Input.h b/src/osgPlugins/flt/Input.h index e044bb4f9..394212b7a 100644 --- a/src/osgPlugins/flt/Input.h +++ b/src/osgPlugins/flt/Input.h @@ -20,6 +20,7 @@ namespace flt { class Record; +class FltFile; class Input @@ -33,7 +34,7 @@ class Input virtual bool rewindLast() = 0; virtual long offset() = 0; - Record* readCreateRecord(); + Record* readCreateRecord(FltFile* pFltFile); protected: diff --git a/src/osgPlugins/flt/Makefile b/src/osgPlugins/flt/Makefile index b888072dd..25ea3225c 100644 --- a/src/osgPlugins/flt/Makefile +++ b/src/osgPlugins/flt/Makefile @@ -38,6 +38,7 @@ C++FILES = \ Pool.cpp\ TextureMappingPaletteRecord.cpp\ ReaderWriterFLT.cpp\ + ReaderWriterATTR.cpp\ # PointLight.cpp\ diff --git a/src/osgPlugins/flt/Pool.cpp b/src/osgPlugins/flt/Pool.cpp index 3da478075..e2afa76aa 100644 --- a/src/osgPlugins/flt/Pool.cpp +++ b/src/osgPlugins/flt/Pool.cpp @@ -61,7 +61,7 @@ ColorPool::ColorName* ColorPool::getColorName(int nIndex) //////////////////////////////////////////////////////////////////// -osg::Texture* TexturePool::getTexture(int nIndex) +osg::StateSet* TexturePool::getTexture(int nIndex) { TexturePaletteMap::iterator fitr = _textureMap.find(nIndex); if (fitr != _textureMap.end()) @@ -71,9 +71,9 @@ osg::Texture* TexturePool::getTexture(int nIndex) } -void TexturePool::addTexture(int nIndex, osg::Texture* osgTexture) +void TexturePool::addTexture(int nIndex, osg::StateSet* stateset) { - _textureMap[nIndex] = osgTexture; + _textureMap[nIndex] = stateset; } diff --git a/src/osgPlugins/flt/Pool.h b/src/osgPlugins/flt/Pool.h index df8f06b76..21f4ddd3c 100644 --- a/src/osgPlugins/flt/Pool.h +++ b/src/osgPlugins/flt/Pool.h @@ -8,12 +8,11 @@ #include #include #include +#include #include #include #include -//#include - namespace flt { @@ -59,8 +58,8 @@ class TexturePool : public osg::Referenced TexturePool() {} - osg::Texture* getTexture(int nIndex); - void addTexture(int nIndex, osg::Texture* osgTexture); + osg::StateSet* getTexture(int nIndex); + void addTexture(int nIndex, osg::StateSet* stateset); protected : @@ -68,7 +67,7 @@ class TexturePool : public osg::Referenced private : - typedef std::map > TexturePaletteMap; + typedef std::map > TexturePaletteMap; TexturePaletteMap _textureMap; }; diff --git a/src/osgPlugins/flt/ReaderWriterATTR.cpp b/src/osgPlugins/flt/ReaderWriterATTR.cpp new file mode 100644 index 000000000..f550be18e --- /dev/null +++ b/src/osgPlugins/flt/ReaderWriterATTR.cpp @@ -0,0 +1,713 @@ + +// +// OpenFlightŪ texture attribute loader for Open Scene Graph +// +// Copyright (C) 2001 Brede Johansen +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for +// real-time rendering of large 3D photo-realistic models. +// The OSG homepage is http://www.openscenegraph.org/ +// +// MultiGen, OpenFlight, and Flight Format are registered trademarks of MultiGen Inc. +// + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +typedef signed char int8; +typedef unsigned char uint8; +typedef signed short int16; +typedef unsigned short uint16; +typedef signed long int32; +typedef unsigned long uint32; +typedef float float32; +typedef double float64; + +#define READ(DST) readField(file, (void*)&(DST), sizeof(DST)) + + +static int isLittleEndianMachine() +{ + int a = 1; + return (int)(*(char*)&a); +} + + +static void endian2(void* pSrc, int nSrc, void* pDst) +{ + if (nSrc == 2) + { + short tmp1; + tmp1 = *(short *)pSrc; + tmp1 = (tmp1 << 8) | ((tmp1 >> 8) & 0xff); + *(short *)pDst = tmp1; + } + else if (nSrc == 4) + { + long tmp1; + tmp1 = *(long *)pSrc; + tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff); + *(long *)pDst = tmp1; + } + else if (nSrc == 8) + { + long tmp1, tmp2; + tmp1 = *(long *)pSrc; + tmp2 = *(1 + (long *)pSrc); + tmp1 = (tmp1 << 24) | ((tmp1 << 8) & 0xff0000) | ((tmp1 >> 8) & 0xff00) | ((tmp1 >> 24) & 0xff); + tmp2 = (tmp2 << 24) | ((tmp2 << 8) & 0xff0000) | ((tmp2 >> 8) & 0xff00) | ((tmp2 >> 24) & 0xff); + *(long *)pDst = tmp2; + *(1 + (long *)pDst) = tmp1; + } +} + + +using namespace osg; + + +class Attr +{ + public : + + enum MinFilterMode { + MIN_FILTER_POINT = 0, + MIN_FILTER_BILINEAR = 1, + MIN_FILTER_MIPMAP = 2, // (Obsolete) + MIN_FILTER_MIPMAP_POINT = 3, + MIN_FILTER_MIPMAP_LINEAR = 4, + MIN_FILTER_MIPMAP_BILINEAR = 5, + MIN_FILTER_MIPMAP_TRILINEAR = 6, + MIN_FILTER_NONE = 7, + MIN_FILTER_BICUBIC = 8, + MIN_FILTER_BILINEAR_GEQUAL = 8, + MIN_FILTER_BILINEAR_LEQUAL = 10, + MIN_FILTER_BICUBIC_GEQUAL = 11, + MIN_FILTER_BICUBIC_LEQUAL = 12 + }; + + enum MagFilterMode { + MAG_FILTER_POINT = 0, + MAG_FILTER_BILINEAR = 1, + MAG_FILTER_NONE = 2, + MAG_FILTER_BICUBIC = 3, + MAG_FILTER_SHARPEN = 4, + MAG_FILTER_ADD_DETAIL = 5, + MAG_FILTER_MODULATE_DETAIL = 6, + MAG_FILTER_BILINEAR_GEQUAL = 7, + MAG_FILTER_BILINEAR_LEQUAL = 8, + MAG_FILTER_BICUBIC_GEQUAL = 9, + MAG_FILTER_BICUBIC_LEQUAL = 10 + }; + + enum WrapMode { + WRAP_REPEAT = 0, + WRAP_CLAMP = 1 + }; + + enum TexEnvMode { + TEXENV_MODULATE = 0, + TEXENV_BLEND = 1, + TEXENV_DECAL = 2, + TEXENV_COLOR = 3 + }; + + enum Projection { + PROJECTION_FLAT = 0, + PROJECTION_LAMBERT_CONIC = 3, + PROJECTION_UTM = 4, + PROJECTION_UNDEFINED = 7 + }; + + enum Datum { + DATUM_WGS84 = 0, + DATUM_WGS72 = 1, + DATUM_BESSEL = 2, + DATUM_CLARK_1866 = 3, + DATUM_NAD27 = 4 + }; + + + Attr(int version) : _flt_version(version) { init(); } + void init(); + void readField(ifstream& file, void* buf, size_t size); + bool readAttrFile(const char* szName); + StateSet* createOsgStateSet(); + + + + int32 texels_u; // Number of texels in u direction + int32 textel_v; // Number of texels in v direction + int32 direction_u; // Real world size u direction + int32 direction_v; // Real world size v direction + int32 x_up; // x component of up vector + int32 y_up; // y component of up vector + int32 fileFormat; // File format type + // -1 Not used + // 0 AT&T image 8 pattern + // 1 AT&T image 8 template + // 2 SGI intensity modulation + // 3 SGI intensity w/ alpha + // 4 SGI RGB + // 5 SGI RGB w/ alpha + int32 minFilterMode; // Minification filter type + // 0 - TX_POINT + // 1 - TX_BILINEAR + // 2 - TX_MIPMAP (Obsolete) + // 3 - TX_MIPMAP_POINT + // 4 - TX_MIPMAP_LINEAR + // 5 - TX_MIPMAP_BILINEAR + // 6 - TX_MIPMAP_TRILINEAR + // 7 - None + // 8 - TX_BICUBIC + // 9 - TX_BILINEAR_GEQUAL + // 10 - TX_BILINEAR_LEQUAL + // 11 - TX_BICUBIC_GEQUAL + // 12 - TX_BICUBIC_LEQUAL + int32 magFilterMode; // Magnification filter type + // 0 - TX_POINT + // 1 - TX_BILINEAR + // 2 - None + // 3 - TX_BICUBIC + // 4 - TX_SHARPEN + // 5 - TX_ADD_DETAIL + // 6 - TX_MODULATE_DETAIL + // 7 - TX_BILINEAR_GEQUAL + // 8 - TX_BILINEAR_LEQUAL + // 9 - TX_BICUBIC_GEQUAL + // 10 - TX_BICUBIC_LEQUAL + int32 wrapMode; // Repetition type + // 0 - TX_REPEAT + // 1 - TX_CLAMP + // 2 - (Obsolete) + int32 wrapMode_u; // Repetition type in u direction (see above) + int32 wrapMode_v; // Repetition type in v direction (see above) + int32 modifyFlag; // Modify flag (for internal use) + int32 pivot_x; // x pivot point for rotating textures + int32 pivot_y; // y pivot point for rotating textures + + // -------------- + // v11 ends here + // -------------- + + int32 texEnvMode; // Environment type + // 0 - TV_MODULATE + // 1 - TV_BLEND + // 2 - TV_DECAL + // 3 - TV_COLOR + int32 intensityAsAlpha; // TRUE if intensity pattern to be loaded in alpha with white in color + int32 spare1[8]; // 8 words of spare + float64 size_u; // Real world size u for floating point databases + float64 size_v; // Real world size v for floating point databases + int32 originCode; // Code for origin of imported texture + int32 kernelVersion; // Kernel version number + int32 intFormat; // Internal format type + // 0 - Default + // 1 - TX_I_12A_4 + // 2 - TX_IA_8 + // 3 - TX_RGB_5 + // 4 - TX_RGBA_4 + // 5 - TX_IA_12 + // 6 - TX_RGBA_8 + // 7 - TX_RGBA_12 + // 8 - TX_I_16 (shadow mode only) + // 9 - TX_RGB_12 + int32 extFormat; // External format type + // 0 - Default + // 1 - TX_PACK_8 + // 2 - TX_PACK_16 + int32 useMips; // TRUE if using following 8 floats for MIPMAP kernel + float32 mips[8]; // 8 floats for kernel of separable symmetric filter + int32 useLodScale; // Boolean if TRUE send: + float32 lod0; // LOD0 for TX_CONTROL_POINT + float32 scale0; // SCALE0 for TX_CONTROL_POINT + float32 lod1; // LOD1 for TX_CONTROL_POINT + float32 scale1; // SCALE1 for TX_CONTROL_POINT + float32 lod2; // LOD2 for TX_CONTROL_POINT + float32 scale2; // SCALE2 for TX_CONTROL_POINT + float32 lod3; // LOD3 for TX_CONTROL_POINT + float32 scale3; // SCALE3 for TX_CONTROL_POINT + float32 lod4; // LOD4 for TX_CONTROL_POINT + float32 scale4; // SCALE4 for TX_CONTROL_POINT + float32 lod5; // LOD5 for TX_CONTROL_POINT + float32 scale5; // SCALE5 for TX_CONTROL_POINT + float32 lod6; // LOD6 for TX_CONTROL_POINT + float32 scale6; // SCALE6 for TX_CONTROL_POINT + float32 lod7; // LOD7 for TX_CONTROL_POINT + float32 scale7; // SCALE7 for TX_CONTROL_POINT + + float32 clamp; // Clamp + int32 magFilterAlpha; // magfilteralpha: + // 0 = TX_POINT + // 1 = TX_BILINEAR + // 2 = None + // 3 = TX_BICUBIC + // 4 = TX_SHARPEN + // 5 = TX_ADD_DETAIL + // 6 = TX_MODULATE_DETAIL + // 7 = TX_BILINEAR_GEQUAL + // 8 = TX_BILINEAR_LEQUAL + // 9 = TX_BICUBIC_GEQUAL + // 10 = TX_BIBICUBIC_LEQUAL + int32 magFilterColor; // magfiltercolor: + // 0 = TX_POINT + // 1 = TX_BILINEAR + // 2 = None + // 3 = TX_BICUBIC + // 4 = TX_SHARPEN + // 5 = TX_ADD_DETAIL + // 6 = TX_MODULATE_DETAIL + // 7 = TX_BILINEAR_GEQUAL + // 8 = TX_BILINEAR_LEQUAL + // 9 = TX_BICUBIC_GEQUAL + // 10 = TX_BIBICUBIC_LEQUAL + float32 reserved1; // Reserved + float32 reserved2[8]; // Reserved + float64 lambertMeridian; // Lambert conic projection central meridian + float64 lambertUpperLat; // Lambert conic projection upper latitude + float64 lambertlowerLat; // Lambert conic projection lower latitude + float64 reserved3; // Reserved + float32 spare2[5]; // Spare + int32 useDetail; // TRUE if using next 5 integers for detail texture + int32 txDetail_j; // J argument for TX_DETAIL + int32 txDetail_k; // K argument for TX_DETAIL + int32 txDetail_m; // M argument for TX_DETAIL + int32 txDetail_n; // N argument for TX_DETAIL + int32 txDetail_s; // Scramble argument for TX_DETAIL + int32 useTile; // TRUE if using next for floats for TX_TILE + float32 txTile_ll_u; // Lower-left u value for TX_TILE + float32 txTile_ll_v; // Lower-left v value for TX_TILE + float32 txTile_ur_u; // Upper-right u value for TX_TILE + float32 txTile_ur_v; // Upper-right v value for TX_TILE + int32 projection; // Projection + // 0 = Flat earth + // 3 = Lambert conic + // 4 = UTM + // 7 = Undefined projection + int32 earthModel; // Earth model + // 0 = WGS84 + // 1 = WGS72 + // 2 = Bessel + // 3 = Clark 1866 + // 4 = NAD27 + int32 reserved4; // Reserved + int32 utmZone; // UTM zone + int32 imageOrigin; // Image origin + // 0 = Lower-left + // 1 = Upper-left + int32 geoUnits; // Geospecific points units + // 0 = Degrees + // 1 = Meters + // 2 = Pixels + int32 reserved5; // Reserved + int32 reserved6; // Reserved + int32 hemisphere; // Hemisphere for geospecific points units + // 0 = Southern + // 1 = Northern + int32 reserved7; // Reserved + int32 reserved8; // Reserved + int32 spare3[149]; // Spare + char comments[512]; // Comments + + // -------------- + // v12 ends here + // -------------- + + int32 reserved9[13]; // Reserved + int32 attrVersion; // Attribute file version number + + int32 controlPoints; // Number of geospecific control points + // If the number of geospecific control points is > 0, + // the following fields are also in the attribute file: + int32 reserved10; // Reserved + #if 0 + // For each geospecific control point: + { + float64 texel_u; // Texel u of geospecific control point + float64 texel_v; // Texel v of geospecific control point + float64 geoPoint[2]; // Real earth coordinate of geospecific control point + // (this value depends on the projection, earth model, + // and geospecific points units) + } + + // ---------------- + // v15.6 ends here + // ---------------- + + // After all geospecific control points are listed, the following subtexture + // information appears: + int32 subtextures; // Number of subtexture definitions contained in the + // texture attribute file + // If the number of subtexture definitions is >0, + // the following fields are repeated for each subtexture definition: + { + char name[32]; // name of subtexture definition + int32 left; // Coordinate of left edge of subtexture + // definition measured in texels. + int32 bottom; // Coordinate of bottom edge of subtexture + // definition measured in texels. + int32 right; // Coordinate of right edge of subtexture + // definition measured in texels. + int32 top; // Coordinate of top edge of subtexture + // definition measured in texels. + } + #endif + + void read(); + + private : + + int _flt_version; +}; + + + +void Attr::init() +{ + texels_u = 0; + textel_v = 0; + direction_u = 0; + direction_v = 0; + x_up = 0; + y_up = 0; + fileFormat = -1; // -1 Not used + minFilterMode = MIN_FILTER_NONE; + magFilterMode = MAG_FILTER_POINT; + wrapMode = WRAP_REPEAT; + wrapMode_u = WRAP_REPEAT; + wrapMode_v = WRAP_REPEAT; + modifyFlag = 0; + pivot_x = 0; + pivot_y = 0; + texEnvMode = TEXENV_MODULATE; + intensityAsAlpha = 0; + size_u = 0; + size_v = 0; + originCode = 0; + kernelVersion = 0; + intFormat = 0; // 0 - Default + extFormat = 0; // 0 - Default + useMips = 0; + // float32 mips[8]; + useLodScale = 0; + // float32 lod0; + // float32 scale0; + // ... + // float32 lod7; + // float32 scale7; + clamp = 0; + magFilterAlpha = 2; // 2 = None + magFilterColor = 2; // 2 = None + lambertMeridian = 0; + lambertUpperLat = 0; + lambertlowerLat = 0; + useDetail = 0; + txDetail_j = 0; + txDetail_k = 0; + txDetail_m = 0; + txDetail_n = 0; + txDetail_s = 0; + useTile = 0; + txTile_ll_u = 0; + txTile_ll_v = 0; + txTile_ur_u = 0; + txTile_ur_v = 0; + projection = PROJECTION_UNDEFINED; + earthModel = DATUM_WGS84; + utmZone = 0; + imageOrigin = 0; + geoUnits = 0; + hemisphere = 1; + comments[0] = '\0'; + attrVersion = 0; + controlPoints = 0; + // TODO: +} + + +void Attr::readField(ifstream& file, void* buf, size_t size) +{ + if (file.eof()) return; + file.read((char*)buf, size); + if(::isLittleEndianMachine()) + ::endian2(buf, size, buf); +} + + +bool Attr::readAttrFile(const char* szName) +{ + int n; + ifstream file; + + file.open (szName, ios::in | ios::binary); + + READ( texels_u ); + READ( textel_v ); + READ( direction_u ); + READ( direction_v ); + READ( x_up ); + READ( y_up ); + READ( fileFormat ); + READ( minFilterMode ); + READ( magFilterMode ); + READ( wrapMode ); + READ( wrapMode_u ); + READ( wrapMode_v ); + READ( modifyFlag ); + READ( pivot_x ); + READ( pivot_y ); + + // v11 ends here + if (_flt_version <= 11) return true; + + READ( texEnvMode ); + READ( intensityAsAlpha ); + for (n=0; n<8; n++) { + READ(spare1[n]); } + READ( size_u ); + READ( size_v ); + READ( originCode ); + READ( kernelVersion ); + READ( intFormat ); + READ( extFormat ); + READ( useMips ); + for (n=0; n<8; n++) { + READ(mips[n]); } + READ( useLodScale ); + READ( lod0 ); + READ( scale0 ); + READ( lod1 ); + READ( scale1 ); + READ( lod2 ); + READ( scale2 ); + READ( lod3 ); + READ( scale3 ); + READ( lod4 ); + READ( scale4 ); + READ( lod5 ); + READ( scale5 ); + READ( lod6 ); + READ( scale6 ); + READ( lod7 ); + READ( scale7 ); + READ( clamp ); + READ( magFilterAlpha ); + READ( magFilterColor ); + READ( reserved1 ); + for (n=0; n<8; n++) { + READ(reserved2[n]); } + READ( lambertMeridian ); + READ( lambertUpperLat ); + READ( lambertlowerLat ); + READ( reserved3 ); + for (n=0; n<5; n++) { + READ(spare2[n]); } + READ( useDetail ); + READ( txDetail_j ); + READ( txDetail_k ); + READ( txDetail_m ); + READ( txDetail_n ); + READ( txDetail_s ); + READ( useTile ); + READ( txTile_ll_u ); + READ( txTile_ll_v ); + READ( txTile_ur_u ); + READ( txTile_ur_v ); + READ( projection ); + READ( earthModel ); + READ( reserved4 ); + READ( utmZone ); + READ( imageOrigin); + READ( geoUnits ); + READ( reserved5 ); + READ( reserved6 ); + READ( hemisphere ); + READ( reserved7 ); + READ( reserved8 ); + for (n=0; n<149; n++) { + READ(spare3[n]); } + file.read(comments, sizeof(comments)); + + // v12 ends here + if (_flt_version <= 12) return true; + + for (n=0; n<13; n++) { + READ(reserved9[n]); } + READ( attrVersion ); + READ( controlPoints); + READ( reserved10 ); + + file.close(); + return true; +} + + +StateSet* Attr::createOsgStateSet() +{ + StateSet* osgStateSet = new StateSet; + TexEnv* osgTexEnv = new TexEnv; + Texture* osgTexture = new Texture; + + if ((wrapMode_u != WRAP_CLAMP) && ((wrapMode_u != WRAP_REPEAT))) + wrapMode_u = wrapMode; + if ((wrapMode_v != WRAP_CLAMP) && ((wrapMode_v != WRAP_REPEAT))) + wrapMode_v = wrapMode; + + if (wrapMode_u == WRAP_CLAMP) osgTexture->setWrap(Texture::WRAP_S,Texture::CLAMP); + else osgTexture->setWrap(Texture::WRAP_S,Texture::REPEAT); + + if (wrapMode_v == WRAP_CLAMP) osgTexture->setWrap(Texture::WRAP_T,Texture::CLAMP); + else osgTexture->setWrap(Texture::WRAP_T,Texture::REPEAT); + + + switch (texEnvMode) + { + case TEXENV_MODULATE: + osgTexEnv->setMode(TexEnv::MODULATE); + break; + case TEXENV_BLEND: + osgTexEnv->setMode(TexEnv::BLEND); + break; + case TEXENV_DECAL: + osgTexEnv->setMode(TexEnv::DECAL); + break; + case TEXENV_COLOR: + osgTexEnv->setMode(TexEnv::REPLACE); + break; + } + + // ----------- + // Min filter + // ----------- + + switch (minFilterMode) + { + case MIN_FILTER_MIPMAP_POINT: + osgTexture->setFilter(osg::Texture::MIN_FILTER, Texture::LINEAR_MIPMAP_NEAREST); + break; + case MIN_FILTER_MIPMAP_LINEAR: + case MIN_FILTER_MIPMAP_BILINEAR: + case MIN_FILTER_MIPMAP_TRILINEAR: + osgTexture->setFilter(osg::Texture::MIN_FILTER, Texture::NEAREST_MIPMAP_LINEAR); + break; + +// case MIN_FILTER_POINT: +// case MIN_FILTER_BILINEAR: +// case MIN_FILTER_BICUBIC; +// case MIN_FILTER_BILINEAR_GEQUAL: +// case MIN_FILTER_BILINEAR_LEQUAL: +// case MIN_FILTER_BICUBIC_GEQUAL: +// case MIN_FILTER_BICUBIC_LEQUAL: +// osgTexture->setFilter(osg::Texture::MIN_FILTER, Texture::LINEAR_MIPMAP_LINEAR); +// break; + } + + + // ----------- + // Mag filter + // ----------- + + switch (magFilterMode) + { + case MAG_FILTER_POINT: + osgTexture->setFilter(osg::Texture::MAG_FILTER, Texture::NEAREST); + break; + case MAG_FILTER_BILINEAR: + case MAG_FILTER_BILINEAR_GEQUAL: + case MAG_FILTER_BILINEAR_LEQUAL: + case MAG_FILTER_SHARPEN: + osgTexture->setFilter(osg::Texture::MAG_FILTER, Texture::LINEAR); + break; + case MAG_FILTER_BICUBIC: + case MAG_FILTER_BICUBIC_GEQUAL: + case MAG_FILTER_BICUBIC_LEQUAL: + osgTexture->setFilter(osg::Texture::MAG_FILTER, Texture::ANISOTROPIC); + break; + +// case MAG_FILTER_ADD_DETAIL: +// case MAG_FILTER_MODULATE_DETAIL: +// osgTexture->setFilter(osg::Texture::MAG_FILTER, Texture::ANISOTROPIC); +// break; + } + + + osgStateSet->setAttribute( osgTexEnv ); + osgStateSet->setAttributeAndModes( osgTexture, StateAttribute::ON ); + + return osgStateSet; +} + + +class ReaderWriterATTR : public osgDB::ReaderWriter +{ + public: + virtual const char* className() { return "ATTR Image Attribute Reader/Writer"; } + + virtual bool acceptsExtension(const std::string& extension) + { + return osgDB::equalCaseInsensitive(extension,"attr"); + } + + virtual ReadResult readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*) + { + std::string ext = osgDB::getFileExtension(fileName); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + // options + char buf[256]; + int version=0; + + const ReaderWriter::Options* rwOptions= + osgDB::Registry::instance()->getOptions(); + + if (rwOptions) + { + sscanf(rwOptions->getOptionString().c_str(),"%s %d", buf, &version); + if (strcmp(buf, "FLT_VER")) version=0; + } + + Attr attr(version); + + if (!attr.readAttrFile(fileName.c_str())) + { + return "Unable to open \""+fileName+"\""; + } + + StateSet* stateset = attr.createOsgStateSet(); + + notify(INFO) << "texture attribute read ok" << endl; + return stateset; + } + +}; + +// now register with Registry to instantiate the above +// reader/writer. +osgDB::RegisterReaderWriterProxy g_readerWriter_ATTR_Proxy; diff --git a/src/osgPlugins/flt/Record.cpp b/src/osgPlugins/flt/Record.cpp index 69cd49de9..783d4a536 100644 --- a/src/osgPlugins/flt/Record.cpp +++ b/src/osgPlugins/flt/Record.cpp @@ -34,6 +34,7 @@ Record::Record() { _pData = NULL; _pParent = NULL; + _pFltFile = NULL; } @@ -43,6 +44,15 @@ Record::~Record() } +int Record::getFlightVersion() +{ + if (_pFltFile) + return _pFltFile->getFlightVersion(); + + return -1; +} + + Record* Record::cloneRecord(SRecHeader* pData) { Record* pRec = clone(); @@ -92,7 +102,7 @@ PrimNodeRecord::PrimNodeRecord() // virtual PrimNodeRecord::~PrimNodeRecord() { - removeAllChildren(); +// removeAllChildren(); } @@ -152,7 +162,7 @@ bool PrimNodeRecord::readExtensionLevel(Input& fr) { Record* pRec; - while (pRec=fr.readCreateRecord()) + while (pRec=fr.readCreateRecord(_pFltFile)) { if (pRec->isOfType(POP_EXTENSION_OP)) return true; @@ -192,12 +202,12 @@ bool PrimNodeRecord::readLevel(Input& fr) // Read next record, including extension record Record* PrimNodeRecord::readRecord(Input& fr) { - Record* pRec = fr.readCreateRecord(); + Record* pRec = fr.readCreateRecord(_pFltFile); while (pRec && (pRec->getOpcode() == PUSH_EXTENSION_OP)) { readExtensionLevel(fr); - pRec=fr.readCreateRecord(); + pRec=fr.readCreateRecord(_pFltFile); } return pRec; } diff --git a/src/osgPlugins/flt/Record.h b/src/osgPlugins/flt/Record.h index 25d4907ba..1c47320ad 100644 --- a/src/osgPlugins/flt/Record.h +++ b/src/osgPlugins/flt/Record.h @@ -19,8 +19,9 @@ using namespace std; namespace flt { -class Record; +//class Record; class Input; +class FltFile; class RecordVisitor; class FltFile; class PrimNodeRecord; @@ -53,7 +54,7 @@ class Record : public osg::Referenced virtual bool isPrimaryNode() const { return false; } virtual bool isControlRecord() const { return false; } virtual bool isAncillaryRecord() const { return false; } - virtual void endian(){} + virtual void endian() {} int getRecordType() const; @@ -65,6 +66,9 @@ class Record : public osg::Referenced size_t getBodyLength() const; bool isOfType(int op) const; Record* getParent() const { return _pParent; } + FltFile* getFltFile() { return _pFltFile; } + int getFlightVersion(); + friend ostream& operator << (ostream& output, const Record& rec); @@ -73,14 +77,15 @@ class Record : public osg::Referenced /** disallow creation of Records on the stack.*/ virtual ~Record(); - /** Template Method local read and write methods */ virtual bool readLocalData(Input& /*fr*/) { return false; } // virtual bool writeLocalData(Output& fw) { return false; } SRecHeader* _pData; Record* _pParent; + FltFile* _pFltFile; + friend Input; friend FltFile; friend PrimNodeRecord; diff --git a/src/osgPlugins/flt/Registry.cpp b/src/osgPlugins/flt/Registry.cpp index d0f22e477..2564fe6fe 100644 --- a/src/osgPlugins/flt/Registry.cpp +++ b/src/osgPlugins/flt/Registry.cpp @@ -54,14 +54,14 @@ Record* Registry::getPrototype(const int opcode) /////////////////////////////////////////////////////////////////// -void Registry::addTexture(const std::string& name, osg::Texture* texture) +void Registry::addTexture(const std::string& name, osg::StateSet* texture) { if (texture == NULL) return; _textureMap[name] = texture; } -osg::Texture* Registry::getTexture(const std::string name) +osg::StateSet* Registry::getTexture(const std::string name) { TextureMap::iterator itr = _textureMap.find(name); if (itr != _textureMap.end()) diff --git a/src/osgPlugins/flt/Registry.h b/src/osgPlugins/flt/Registry.h index c46f019d5..d7ebebe86 100644 --- a/src/osgPlugins/flt/Registry.h +++ b/src/osgPlugins/flt/Registry.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include "FltFile.h" @@ -47,19 +47,16 @@ class Registry void addPrototype(Record* rec); Record* getPrototype(const int opcode); - void addTexture(const std::string& name, osg::Texture* texture); - osg::Texture* getTexture(const std::string name); + void addTexture(const std::string& name, osg::StateSet* texture); + osg::StateSet* 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::map > RecordProtoMap; - typedef std::map > TextureMap; + typedef std::map > TextureMap; typedef std::map > FltFileMap; /** constructor is private, as its a singleton, preventing @@ -70,8 +67,6 @@ class Registry RecordProtoMap _recordProtoMap; TextureMap _textureMap; FltFileMap _fltFileMap; - int _fltFileVersion; - }; diff --git a/src/osgPlugins/flt/TextureMappingPaletteRecord.h b/src/osgPlugins/flt/TextureMappingPaletteRecord.h index 49fe2aa1d..4074bd504 100644 --- a/src/osgPlugins/flt/TextureMappingPaletteRecord.h +++ b/src/osgPlugins/flt/TextureMappingPaletteRecord.h @@ -29,10 +29,12 @@ struct STextureMapping int32 diWarpFlag; // Warped flag; if TRUE, 8 point warp applied float64 dfMat[4][4]; // Transformation matrix (valid only for Types 1 & 2) // Variable Variable; // Parameters (see below for parameters for each mapping type) +}; -#if 0 // Parameters for Put Texture Mapping (Type 1) +struct SPutTextureMapping +{ uint32 dwState; // State of Put Texture tool // 0 = Start state - no points entered // 1 = One point entered @@ -49,17 +51,19 @@ struct STextureMapping float64x3 dfTxtAlignment; // Texture alignment point float64x3 dfTxtShear; // Texture shear point float64x3 dfGeoOrigin; // Geometry origin point - float64x3 dfGeoAlignmentM // Geometry alignment point + float64x3 dfGeoAlignment; // Geometry alignment point float64x3 dfGeoShear; // Geometry shear point int32 TxtActive; // Active texture point // 1 = Origin point // 2 = Alignment point // 3 = Shear point int32 Reserved; // should always be set to 1 -// Variable Variable; // Parameters (see parameters below for each mapping type) +}; //Parameters for 4 Point Put Texture Mapping (Type 2) +struct SPointPutTextureMapping +{ int32 state; // State of Put Texture tool // 0 = Start state - no points entered // 1 = One point entered @@ -91,20 +95,25 @@ struct STextureMapping int32 Reserved; // should always be set to 1 float32 sfScale; // Depth scale factor float64 dfMat[4][4]; // Transformation matrix for the 4 point projection plane - +}; // Parameters for Spherical Project Mapping (Type 4) +struct SSphericalTextureMapping +{ float32 sfScale; // Scale float64x3 Center; // Center of the projection sphere - float32 sfScale; // Scale / (maximum dimension of the mapped geometry + float32 sfMaxScale; // Scale / (maximum dimension of the mapped geometry // bounding box) float32 sfMaxDimension; // Maximum dimension of the mapped geometry // bounding box +}; // Parameters for Radial Project Mapping (Type 5) - int32 active // Active geometry point +struct SRadialTextureMapping +{ + int32 active; // Active geometry point // 1 = End point 1 of cylinder center line // 2 = End point 2 of cylinder center line int32 reserved; // Reserved @@ -113,8 +122,11 @@ struct STextureMapping float64 dfMat[4][4]; // Trackplane to XY plane transformation matrix float64x3 endpoint1; // End point 1 of cylinder center line float64x3 endpoint2; // End point 2 of cylinder center line +}; // Parameters for Warped Mapping (Warped Flag Set) +struct SWarpedTextureMapping +{ int32 active; // Active geometry point // 0 = First warp FROM point // 1 = Second warp FROM point @@ -161,10 +173,10 @@ struct STextureMapping Double 16*2 x, y of the seventh TO point transformed to the XY plane by the above matrix Double 16*2 x, y of the eighth TO point transformed to the XY plane by the above matrix */ -#endif }; + class TextureMappingPaletteRecord : public AncillaryRecord { public: diff --git a/src/osgPlugins/flt/TexturePaletteRecord.h b/src/osgPlugins/flt/TexturePaletteRecord.h index 1f8a45ef0..7110b7543 100644 --- a/src/osgPlugins/flt/TexturePaletteRecord.h +++ b/src/osgPlugins/flt/TexturePaletteRecord.h @@ -12,14 +12,25 @@ namespace flt { -typedef struct TexturePaletteTag +struct STexturePalette { SRecHeader RecHeader; - char szFilename[200]; // Filename of texture pattern + char szFilename[200]; // Filename of texture pattern int32 diIndex; // Pattern index int32 diX; // x location in texture palette int32 diY; // y location in texture palette -} STexturePalette; +}; + + +// Version 10, 12, 13 +struct SOldTexturePalette +{ + SRecHeader RecHeader; + char szFilename[80]; // Filename of texture pattern + int32 diIndex; // Pattern index + int32 diX; // x location in texture palette + int32 diY; // y location in texture palette +}; class TexturePaletteRecord : public AncillaryRecord diff --git a/src/osgPlugins/flt/VertexPoolRecords.h b/src/osgPlugins/flt/VertexPoolRecords.h index 1e038ed78..05b42dacd 100644 --- a/src/osgPlugins/flt/VertexPoolRecords.h +++ b/src/osgPlugins/flt/VertexPoolRecords.h @@ -63,20 +63,20 @@ class VertexPaletteRecord : public AncillaryRecord // //////////////////////////////////////////////////////////////////// -typedef struct VertexTag // Vertex with Color Record Format +struct SVertex // Vertex with Color Record Format { - SRecHeader RecHeader; - uint16 swColor; // Color Name Index - uint16 swFlags; // Flags (bits, from left to right) + SRecHeader RecHeader; + uint16 swColor; // Color Name Index + uint16 swFlags; // Flags (bits, from left to right) // 0 = Start Hard Edge // 1 = Normal frozen // 2 = no Vertex Color // 3 = Packed Color // 4-15 Spare - float64x3 Coord; // x,y,z coordinate + float64x3 Coord; // x,y,z coordinate color32 PackedColor; // Packed color (A, B, G, R) - uint32 dwVertexColorIndex; -} SVertex; + uint32 dwVertexColorIndex; +}; class VertexRecord : public AncillaryRecord @@ -106,21 +106,21 @@ class VertexRecord : public AncillaryRecord //////////////////////////////////////////////////////////////////// -typedef struct NormalVertexTag // Vertex with Normal Record Format +struct SNormalVertex // Vertex with Normal Record Format { - SRecHeader RecHeader; - uint16 swColor; // Color Name Index - uint16 swFlags; // Flags (bits, from left to right) + SRecHeader RecHeader; + uint16 swColor; // Color Name Index + uint16 swFlags; // Flags (bits, from left to right) // 0 = Start Hard Edge // 1 = Normal frozen // 2 = no Vertex Color // 3 = Packed Color // 4-15 Spare - float64x3 Coord; // x,y,z coordinate - float32x3 Normal; // Vertex normal + float64x3 Coord; // x,y,z coordinate + float32x3 Normal; // Vertex normal color32 PackedColor; // Packed color (A, B, G, R) - uint32 dwVertexColorIndex; -} SNormalVertex; + uint32 dwVertexColorIndex; +}; class NormalVertexRecord : public AncillaryRecord @@ -149,21 +149,21 @@ class NormalVertexRecord : public AncillaryRecord // //////////////////////////////////////////////////////////////////// -typedef struct TextureVertexTag // Vertex with Texture Record Format +struct STextureVertex // Vertex with Texture Record Format { - SRecHeader RecHeader; - uint16 swColor; // Color Name Index - uint16 swFlags; // Flags (bits, from left to right) + SRecHeader RecHeader; + uint16 swColor; // Color Name Index + uint16 swFlags; // Flags (bits, from left to right) // 0 = Start Hard Edge // 1 = Normal frozen // 2 = no Vertex Color // 3 = Packed Color // 4-15 Spare - float64x3 Coord; // x,y,z coordinate - float32x2 Texture; // Texture (u,v) + float64x3 Coord; // x,y,z coordinate + float32x2 Texture; // Texture (u,v) color32 PackedColor; // Packed color (A, B, G, R) uint32 dwVertexColorIndex; -} STextureVertex; +}; class TextureVertexRecord : public AncillaryRecord @@ -192,22 +192,22 @@ class TextureVertexRecord : public AncillaryRecord // //////////////////////////////////////////////////////////////////// -typedef struct NormalTextureVertexTag //Vertex with Normal and Texture Format +struct SNormalTextureVertex //Vertex with Normal and Texture Format { - SRecHeader RecHeader; - uint16 swColor; // Color Name Index - uint16 swFlags; // Flags (bits, from left to right) + SRecHeader RecHeader; + uint16 swColor; // Color Name Index + uint16 swFlags; // Flags (bits, from left to right) // 0 = Start Hard Edge // 1 = Normal frozen // 2 = no Vertex Color // 3 = Packed Color // 4-15 Spare float64x3 Coord; // x,y,z coordinate - float32x3 Normal; // Vertex normal + float32x3 Normal; // Vertex normal float32x2 Texture; // Texture (u,v) - color32 PackedColor; // Packed color (A, B, G, R) - uint32 dwVertexColorIndex; -} SNormalTextureVertex; + color32 PackedColor; // Packed color (A, B, G, R) + uint32 dwVertexColorIndex; +}; class NormalTextureVertexRecord : public AncillaryRecord diff --git a/src/osgPlugins/flt/flt.cpp b/src/osgPlugins/flt/flt.cpp index af106ffd9..d200792be 100644 --- a/src/osgPlugins/flt/flt.cpp +++ b/src/osgPlugins/flt/flt.cpp @@ -41,3 +41,4 @@ void flt::endian2(void* pSrc, int nSrc, void* pDst, int ) *(1 + (long *)pDst) = tmp1; } } + diff --git a/src/osgPlugins/flt/flt.h b/src/osgPlugins/flt/flt.h index a1027cb80..2ac4babb8 100644 --- a/src/osgPlugins/flt/flt.h +++ b/src/osgPlugins/flt/flt.h @@ -33,6 +33,24 @@ namespace flt { #define BIT14 0x4000 #define BIT15 0x8000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + + //////////////////////////////////////////////////////////////////// typedef signed char int8; diff --git a/src/osgPlugins/flt/flt2osg.cpp b/src/osgPlugins/flt/flt2osg.cpp index 3437867e7..9341d93d6 100644 --- a/src/osgPlugins/flt/flt2osg.cpp +++ b/src/osgPlugins/flt/flt2osg.cpp @@ -1,7 +1,8 @@ // flt2osg.cpp +#include #include -#include "osg/GL" +#include #include #include @@ -12,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -39,6 +43,7 @@ #include "OldMaterialPaletteRecord.h" #include "TexturePaletteRecord.h" #include "VertexPoolRecords.h" +#include "OldVertexRecords.h" #include "GroupRecord.h" #include "LodRecord.h" #include "DofRecord.h" @@ -52,16 +57,19 @@ #include "GeoSetBuilder.h" #include "LongIDRecord.h" + + using namespace flt; -ConvertFromFLT::ConvertFromFLT(FltFile* pFltFile) + +ConvertFromFLT::ConvertFromFLT() : + _faceColor(1,1,1,1) { - _pFltFile = pFltFile; _diOpenFlightVersion = 0; _diCurrentOffset = 0; _wObjTransparency = 0; _nSubfaceLevel = 0; - _sfHdrUnitScale = 1; + _unitScale = 1.0; _bHdrRgbMode = false; } @@ -71,7 +79,7 @@ ConvertFromFLT::~ConvertFromFLT() } -osg::Node* ConvertFromFLT::convert(Record* rec) +osg::Node* ConvertFromFLT::convert(HeaderRecord* rec) { if (rec==NULL) return NULL; return visitNode(NULL, rec); @@ -150,7 +158,8 @@ osg::Node* ConvertFromFLT::visitAncillary(osg::Group* osgParent, PrimNodeRecord* osg::Node* ConvertFromFLT::visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec) { osg::Node* node = NULL; - GeoSetBuilder geoSetBuilder(_pFltFile.get()); + osg::Geode* geode = new osg::Geode; + GeoSetBuilder geoSetBuilder(geode); // Visit for(int i=0; i < rec->getNumChildren(); i++) @@ -168,8 +177,9 @@ osg::Node* ConvertFromFLT::visitPrimaryNode(osg::Group* osgParent, PrimNodeRecor } } - osg::Geode* geode = geoSetBuilder.createOsgGeoSets(); - if (osgParent && geode) + geoSetBuilder.createOsgGeoSets(); + + if (osgParent && (geode->getNumDrawables() > 0)) osgParent->addChild( geode ); return node; @@ -195,10 +205,35 @@ osg::Node* ConvertFromFLT::visitHeader(osg::Group* osgParent, HeaderRecord* rec) osg::notify(osg::INFO) << "Version " << _diOpenFlightVersion << endl; // Unit scale - if (pSHeader->iMultDivUnit < 0) - _sfHdrUnitScale = 1.f / -pSHeader->iMultDivUnit; - else if (pSHeader->iMultDivUnit > 0) - _sfHdrUnitScale = pSHeader->iMultDivUnit; + switch (pSHeader->swVertexCoordUnit) + { + case HeaderRecord::METERS: + _unitScale = 1.0; + break; + case HeaderRecord::KILOMETERS: + _unitScale = 1000.0; + break; + case HeaderRecord::FEET: + _unitScale = 0.3048; + break; + case HeaderRecord::INCHES: + _unitScale = 0.02540; + break; + case HeaderRecord::NAUTICAL_MILES: + _unitScale = 1852.0; + break; + default: + _unitScale = 1.0; + } + + // Flight v.11 & v.12 use integer coordinates + if (rec->getFlightVersion() < 13) + { + if (pSHeader->iMultDivUnit >= 0) + _unitScale *= (double)pSHeader->iMultDivUnit; + else + _unitScale /= (double)(-pSHeader->iMultDivUnit); + } _bHdrRgbMode = (pSHeader->dwFlags & 0x40000000) ? true : false; // RGB space (=packed color) @@ -220,14 +255,17 @@ osg::Node* ConvertFromFLT::visitHeader(osg::Group* osgParent, HeaderRecord* rec) /*osgParent*/ osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* rec) { - if (!_pFltFile->useColorPalette()) return NULL; + if (!rec->getFltFile()->useInternalColorPalette()) return NULL; - ColorPool* pColorPool = _pFltFile->getColorPool(); + ColorPool* pColorPool = rec->getFltFile()->getColorPool(); + int flightVersion = rec->getFlightVersion(); - if (_diOpenFlightVersion > 13) + if (flightVersion > 13) { SColorPalette* pCol = (SColorPalette*)rec->getData(); - for (int i=0; i < 1024; i++) + int colors = (flightVersion >= 1500) ? 1024 : 512; + + for (int i=0; i < colors; i++) { osg::Vec4 color(pCol->Colors[i].get()); color[3] = 1.0f; // Force alpha to one @@ -256,14 +294,13 @@ osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* r return NULL; } - /*osgParent*/ -osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRecord* rec) +osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group*, MaterialPaletteRecord* rec) { - if (!_pFltFile->useMaterialPalette()) return NULL; + if (!rec->getFltFile()->useInternalMaterialPalette()) return NULL; SMaterial* pSMaterial = (SMaterial*)rec->getData(); - MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); + MaterialPool* pMaterialPool = rec->getFltFile()->getMaterialPool(); if (pSMaterial && pMaterialPool) { MaterialPool::PoolMaterial* pPoolMat = new MaterialPool::PoolMaterial; @@ -283,10 +320,10 @@ osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRec /*osgParent*/ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPaletteRecord* rec) { - if (!_pFltFile->useMaterialPalette()) return NULL; + if (!rec->getFltFile()->useInternalMaterialPalette()) return NULL; SOldMaterial* pSMaterial = (SOldMaterial*)rec->getData(); - MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); + MaterialPool* pMaterialPool = rec->getFltFile()->getMaterialPool(); if (pSMaterial && pMaterialPool ) { @@ -310,37 +347,85 @@ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPale /*osgParent*/ osg::Node* ConvertFromFLT::visitTexturePalette(osg::Group* , TexturePaletteRecord* rec) { - if (!_pFltFile->useTexturePalette()) return NULL; + int nIndex; + char* pFilename; - STexturePalette* pTexture = (STexturePalette*)rec->getData(); - TexturePool* pTexturePool = _pFltFile->getTexturePool(); + if (!rec->getFltFile()->useInternalTexturePalette()) return NULL; - if (pTexture && pTexturePool) + if (rec->getFlightVersion() > 13) { - osg::Texture *osgTexture; + STexturePalette* pTexture = (STexturePalette*)rec->getData(); + pFilename = pTexture->szFilename; + nIndex = pTexture->diIndex; + } + else // version 11, 12 & 13 + { + SOldTexturePalette* pOldTexture = (SOldTexturePalette*)rec->getData(); + pFilename = pOldTexture->szFilename; + nIndex = pOldTexture->diIndex; + } - osgTexture = Registry::instance()->getTexture(pTexture->szFilename); - if (osgTexture == NULL) + TexturePool* pTexturePool = rec->getFltFile()->getTexturePool(); + if (pTexturePool == NULL) return NULL; + + // Get StateSet containing texture from registry pool. + osg::StateSet *osgStateSet = Registry::instance()->getTexture(pFilename); + + if (osgStateSet) + { + // Add texture to local pool to be able to get by index. + pTexturePool->addTexture(nIndex, osgStateSet); + return NULL; + } + + // Read texture and texture + osg::ref_ptr image = osgDB::readImageFile(pFilename); + if (image.valid()) + { + std::string attrName(pFilename); + attrName += ".attr"; + + // Read attribute file + char options[256]; + sprintf(options,"FLT_VER %d",rec->getFlightVersion()); + + osgDB::Registry::instance()->setOptions(new osgDB::ReaderWriter::Options(options)); + osg::StateSet* osgStateSet = + dynamic_cast(osgDB::readObjectFile(attrName)); + osgDB::Registry::instance()->setOptions(NULL); // Delete options + + // if not found create default StateSet + if (osgStateSet == NULL) { - 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()); - - // 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); - } + osgStateSet = new osg::StateSet; + osg::TexEnv* osgTexEnv = new osg::TexEnv; + osgTexEnv->setMode(osg::TexEnv::MODULATE); + osgStateSet->setAttribute( osgTexEnv ); } - if (osgTexture) - pTexturePool->addTexture((int)pTexture->diIndex, osgTexture); + osg::Texture *osgTexture = dynamic_cast(osgStateSet->getAttribute( osg::StateAttribute::TEXTURE)); + if (osgTexture == NULL) + { + osgTexture = new osg::Texture; + osgStateSet->setAttributeAndModes(osgTexture,osg::StateAttribute::ON); + } + + osgTexture->setImage(image.get()); + + switch (image->pixelFormat()) + { + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + osgStateSet->setMode(GL_BLEND,osg::StateAttribute::ON); + osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + break; + } + + // Add new texture to registry pool + Registry::instance()->addTexture(pFilename, osgStateSet); + + // Also add to local pool to be able to get texture by index. + pTexturePool->addTexture(nIndex, osgStateSet); } return NULL; @@ -353,7 +438,6 @@ osg::Node* ConvertFromFLT::visitVertexPalette(osg::Group* , VertexPaletteRecord* return NULL; } - /*osgParent*/ osg::Node* ConvertFromFLT::visitVertex(osg::Group* , VertexRecord* rec) { @@ -362,7 +446,6 @@ osg::Node* ConvertFromFLT::visitVertex(osg::Group* , VertexRecord* rec) return NULL; } - /*osgParent*/ osg::Node* ConvertFromFLT::visitNormalVertex(osg::Group* , NormalVertexRecord* rec) { @@ -371,7 +454,6 @@ osg::Node* ConvertFromFLT::visitNormalVertex(osg::Group* , NormalVertexRecord* r return NULL; } - /*osgParent*/ osg::Node* ConvertFromFLT::visitTextureVertex(osg::Group* , TextureVertexRecord* rec) { @@ -380,7 +462,6 @@ osg::Node* ConvertFromFLT::visitTextureVertex(osg::Group* , TextureVertexRecord* return NULL; } - /*osgParent*/ osg::Node* ConvertFromFLT::visitNormalTextureVertex(osg::Group* , NormalTextureVertexRecord* rec) { @@ -512,6 +593,7 @@ osg::Node* ConvertFromFLT::visitSwitch(osg::Group* osgParent, SwitchRecord* rec) osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec) { + SObject *pSObject = (SObject*)rec->getData(); osg::Group* group = new osg::Group; if (group) @@ -520,11 +602,11 @@ osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec) if (node) osgParent = (osg::Group*)node; unsigned short wPrevTransparency = _wObjTransparency; - _wObjTransparency = rec->getData()->wTransparency; + _wObjTransparency = pSObject->wTransparency; visitPrimaryNode(group, (PrimNodeRecord*)rec); _wObjTransparency = wPrevTransparency; - group->setName(rec->getData()->szIdent); + group->setName(pSObject->szIdent); osgParent->addChild( group ); } @@ -534,12 +616,21 @@ 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(); + DynGeoSet* dgset = pBuilder->getDynGeoSet(); + osg::StateSet* osgStateSet = dgset->getStateSet(); SFace *pSFace = (SFace*)rec->getData(); - osg::Vec4 color(1,1,1,1); + + if (rec->getFlightVersion() > 13) + { + if (pSFace->dwFlags & FaceRecord::HIDDEN_BIT) + return; + } + + // // Cull face & wireframe + // + int drawMode = pSFace->swDrawFlag & (BIT0 | BIT1); switch(drawMode) { @@ -548,21 +639,21 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) { osg::CullFace* cullface = new osg::CullFace; cullface->setMode(osg::CullFace::BACK); - stateSet->setAttributeAndModes(cullface, osg::StateAttribute::ON); + osgStateSet->setAttributeAndModes(cullface, osg::StateAttribute::ON); } break; case FaceRecord::SOLID_NO_BACKFACE: // Disable backface culling - stateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); + osgStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); break; case FaceRecord::WIREFRAME_NOT_CLOSED: - geoSet->setPrimType(osg::GeoSet::LINE_STRIP); + dgset->setPrimType(osg::GeoSet::LINE_STRIP); break; case FaceRecord::WIREFRAME_CLOSED: - geoSet->setPrimType(osg::GeoSet::LINE_LOOP); + dgset->setPrimType(osg::GeoSet::LINE_LOOP); break; } /* @@ -581,66 +672,84 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) */ + // // Lighting and color binding - if (_diOpenFlightVersion > 13) + // + + if (rec->getFlightVersion() > 13) { switch(pSFace->swLightMode) { case FaceRecord::FACE_COLOR: // Use face color, not illuminated - stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL ); + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + dgset->setColorBinding( osg::GeoSet::BIND_OVERALL /*BIND_PERPRIM*/ ); break; case FaceRecord::VERTEX_COLOR: // Use vertex colors, not illuminated - stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + dgset->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); + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + dgset->setColorBinding( osg::GeoSet::BIND_OVERALL ); + dgset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); break; case FaceRecord::VERTEX_COLOR_LIGHTING: // 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); + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + dgset->setColorBinding( osg::GeoSet::BIND_PERVERTEX ); + dgset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX); + break; + + default : + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + dgset->setColorBinding( osg::GeoSet::BIND_OVERALL ); break; } } else // Version 11, 12 & 13 { - geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL ); + osgStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + dgset->setColorBinding( osg::GeoSet::BIND_OVERALL /*BIND_PERPRIM*/ ); } + // // Face Color + // + + if (pSFace->swTexWhite && (pSFace->iTexturePattern != -1)) + { + // Render textured polygons white + _faceColor.set(1,1,1,1); + } + else { float alpha = 1.0f; - ColorPool* pColorPool = _pFltFile->getColorPool(); + ColorPool* pColorPool = rec->getFltFile()->getColorPool(); + _faceColor.set(1,1,1,1); - if (_diOpenFlightVersion > 13) + if (rec->getFlightVersion() > 13) { if (!(pSFace->dwFlags & FaceRecord::NO_COLOR_BIT)) { - float alpha; bool bPackedColor = _bHdrRgbMode || (pSFace->dwFlags & FaceRecord::PACKED_COLOR_BIT) || (pColorPool == NULL); if (bPackedColor) - color = pSFace->PrimaryPackedColor.get(); + _faceColor = pSFace->PrimaryPackedColor.get(); else - color = pColorPool->getColor(pSFace->dwPrimaryColorIndex); + _faceColor = pColorPool->getColor(pSFace->dwPrimaryColorIndex); alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f; - color[3] = alpha; + _faceColor[3] = alpha; } } else // Version 11, 12 & 13 @@ -648,27 +757,32 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) bool bPackedColor = _bHdrRgbMode || (pColorPool == NULL); if (bPackedColor) - color = pSFace->PrimaryPackedColor.get(); + _faceColor = pSFace->PrimaryPackedColor.get(); else - color = pColorPool->getColor(pSFace->wPrimaryNameIndex); + _faceColor = pColorPool->getColor(pSFace->wPrimaryNameIndex); alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f; - color[3] = alpha; + _faceColor[3] = alpha; } // Transparency if (alpha < 1.0f) { - stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + osgStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } - - if (geoSet->getColorBinding() == osg::GeoSet::BIND_OVERALL) - geoSet->setColors( new osg::Vec4(color) ); } + if ((dgset->getColorBinding() == osg::GeoSet::BIND_OVERALL) + || (dgset->getColorBinding() == osg::GeoSet::BIND_PERPRIM)) + dgset->addColor(_faceColor); + + + // // Material - MaterialPool* pMaterialPool = _pFltFile->getMaterialPool(); + // + + MaterialPool* pMaterialPool = rec->getFltFile()->getMaterialPool(); if (pMaterialPool) { MaterialPool::PoolMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial); @@ -685,14 +799,14 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) alpha = pSMaterial->sfAlpha * (1.0f - ( ((float)pSFace->wTransparency / 65535.0f) * ((float)_wObjTransparency / 65535.0f) )); - ambient[0] = pSMaterial->Ambient[0] * color[0]; - ambient[1] = pSMaterial->Ambient[1] * color[1]; - ambient[2] = pSMaterial->Ambient[2] * color[2]; + ambient[0] = pSMaterial->Ambient[0] * _faceColor[0]; + ambient[1] = pSMaterial->Ambient[1] * _faceColor[1]; + ambient[2] = pSMaterial->Ambient[2] * _faceColor[2]; ambient[3] = alpha; - diffuse[0] = pSMaterial->Diffuse[0] * color[0]; - diffuse[1] = pSMaterial->Diffuse[1] * color[1]; - diffuse[2] = pSMaterial->Diffuse[2] * color[2]; + diffuse[0] = pSMaterial->Diffuse[0] * _faceColor[0]; + diffuse[1] = pSMaterial->Diffuse[1] * _faceColor[1]; + diffuse[2] = pSMaterial->Diffuse[2] * _faceColor[2]; diffuse[3] = alpha; specular[0] = pSMaterial->Specular[0]; @@ -705,7 +819,6 @@ 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); @@ -715,15 +828,18 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) if (alpha < 1.0f) { - stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + osgStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } - stateSet->setAttribute(osgMaterial); + osgStateSet->setAttribute(osgMaterial); } } + // // Subface + // + if (rec->getParent()->isOfType(FACE_OP)) { if (_nSubfaceLevel > 0) @@ -733,102 +849,66 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) { polyoffset->setFactor(-1.0f*_nSubfaceLevel); polyoffset->setUnits(-20.0f*_nSubfaceLevel); - stateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); + osgStateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); } } } + // // Texture + // + if (pSFace->iTexturePattern != -1) { - TexturePool* pTexturePool = _pFltFile->getTexturePool(); + TexturePool* pTexturePool = rec->getFltFile()->getTexturePool(); if (pTexturePool) { - osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern); - if (osgTexture) + osg::StateSet *textureStateSet = dynamic_cast + (pTexturePool->getTexture((int)pSFace->iTexturePattern)); + + if (textureStateSet) { - osg::Image* image = osgTexture->getImage(); - if (image) + // Merge face stateset with texture stateset + osgStateSet->merge(*textureStateSet); + + // current version of merge dosn't merge rendering hint + if (textureStateSet->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN) + osgStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + + +#if 0 // Started to experiment with OpenFlight texture mapping modes + if (pSFace->iTextureMapIndex > -1) { - switch (image->pixelFormat()) - { - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - stateSet->setMode(GL_BLEND,osg::StateAttribute::ON); - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - break; - } + osg::TexGen* osgTexGen = new osg::TexGen; + osgTexGen->setMode(osg::TexGen::SPHERE_MAP); + osgStateSet->setAttributeAndModes(osgTexGen,osg::StateAttribute::ON); } +#endif - 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 ); + dgset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); } } } - // Visit vertices - if (_diOpenFlightVersion > 13) - { - int i; - for(i=0; i < rec->getNumChildren(); i++) - { - Record* child = rec->getChild(i); - if (child == NULL) break; + // + // Vertices + // - switch (child->getOpcode()) - { - case VERTEX_LIST_OP: - pBuilder->addPrimLen( - visitVertexList(pBuilder, (VertexListRecord*)child)); - break; - } - } - } - else - { - int i; - int vertices=0; - for(i=0; i < rec->getNumChildren(); i++) - { - Record* child = rec->getChild(i); - if (child == NULL) break; + addVertices(pBuilder, rec); - switch (child->getOpcode()) - { - case OLD_VERTEX_OP: - pBuilder->addVertex(child); - vertices++; - break; + // + // Add face to builder GeoSet pool + // - 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++; + int n; for(n=0; ngetNumChildren(); n++) { Record* child = rec->getChild(n); @@ -841,9 +921,38 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec) } +// Return number of vertices added to builder. +int ConvertFromFLT::addVertices(GeoSetBuilder* pBuilder, PrimNodeRecord* primRec) +{ + int i; + int vertices=0; + DynGeoSet* dgset = pBuilder->getDynGeoSet(); + + for(i=0; i < primRec->getNumChildren(); i++) + { + Record* child = primRec->getChild(i); + if (child == NULL) break; + + switch (child->getOpcode()) + { + case VERTEX_LIST_OP: + vertices += visitVertexList(pBuilder, (VertexListRecord*)child); + break; + + default : + vertices += addVertex(pBuilder, child); + break; + } + } + + if (vertices > 0) dgset->addPrimLen(vertices); + return vertices; +} + + int ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec) { - osg::GeoSet* geoSet = pBuilder->getGeoSet(); + DynGeoSet* dgset = pBuilder->getDynGeoSet(); int vertices = rec->numberOfVertices(); // Add vertices to GeoSetBuilder @@ -851,12 +960,130 @@ int ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* r { Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i)); if (vertex) - pBuilder->addVertex(vertex); + addVertex(pBuilder, vertex); } + return vertices; } + + + +// Return 1 if record is a known vertex record else return 0. +int ConvertFromFLT::addVertex(GeoSetBuilder* pBuilder, Record* rec) +{ + DynGeoSet* dgset = pBuilder->getDynGeoSet(); + + switch(rec->getOpcode()) + { + case VERTEX_C_OP: + { + SVertex* pVert = (SVertex*)rec->getData(); + osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z()); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + + } + break; + + case VERTEX_CN_OP: + { + SNormalVertex* pVert = (SNormalVertex*)rec->getData(); + osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z()); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_NORMAL(dgset, pVert) + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + } + break; + + case VERTEX_CNT_OP: + { + SNormalTextureVertex* pVert = (SNormalTextureVertex*)rec->getData(); + osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z()); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_NORMAL(dgset, pVert) + if (dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_TCOORD(dgset, pVert) + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + } + break; + + case VERTEX_CT_OP: + { + STextureVertex* pVert = (STextureVertex*)rec->getData(); + osg::Vec3 coord(pVert->Coord.x(), pVert->Coord.y(), pVert->Coord.z()); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_TCOORD(dgset, pVert) + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_VERTEX_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + } + break; + + case OLD_VERTEX_OP: + { + SOldVertex* pVert = (SOldVertex*)rec->getData(); + osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (rec->getSize() >= sizeof(SOldVertex))) + ADD_OLD_TCOORD(dgset, pVert) + } + break; + + case OLD_VERTEX_COLOR_OP: + { + SOldVertexColor* pVert = (SOldVertexColor*)rec->getData(); + osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_OLD_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (rec->getSize() >= sizeof(SOldVertexColor))) + ADD_OLD_TCOORD(dgset, pVert) + } + break; + + case OLD_VERTEX_COLOR_NORMAL_OP: + { + SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)rec->getData(); + osg::Vec3 coord(pVert->v[0], pVert->v[1], pVert->v[2]); + coord *= (float)_unitScale; + dgset->addCoord(coord); + if (dgset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX) + { + osg::Vec3 normal(pVert->n[0], pVert->n[1], pVert->n[2]); + normal /= (float)(1L<<30); + dgset->addNormal(normal); + } + if (dgset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX) + ADD_OLD_COLOR(dgset, pVert, rec->getFltFile()->getColorPool()) + if ((dgset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX) + && (rec->getSize() >= sizeof(SOldVertexColorNormal))) + ADD_OLD_TCOORD(dgset, pVert) + } + break; + + default : + return 0; + } + + return 1; +} + + osg::Node* ConvertFromFLT::visitMatrix(osg::Group* osgParent, MatrixRecord* rec) { SMatrix* pSMatrix = (SMatrix*)rec->getData(); @@ -872,6 +1099,14 @@ osg::Node* ConvertFromFLT::visitMatrix(osg::Group* osgParent, MatrixRecord* rec) m(i,j) = pSMatrix->sfMat[i][j]; } } + + // scale position. + // BJ Don't know if this should be done if version > 12 + osg::Vec3 pos = m.getTrans(); + m *= osg::Matrix::trans(-pos.x(),-pos.y(),-pos.z()); + pos *= (float)_unitScale; + m *= osg::Matrix::trans(pos); + dcs->setMatrix(m); osgParent->addChild(dcs); return (osg::Node*)dcs; @@ -907,51 +1142,27 @@ osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord* void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec) { - osg::GeoSet* geoSet = pBuilder->getGeoSet(); - osg::StateSet* stateSet = geoSet->getStateSet(); + DynGeoSet* dgset = pBuilder->getDynGeoSet(); + osg::StateSet* stateSet = dgset->getStateSet(); SLightPoint *pSLightPoint = (SLightPoint*)rec->getData(); - geoSet->setPrimType(osg::GeoSet::POINTS); - geoSet->setColorBinding(osg::GeoSet::BIND_PERVERTEX); + dgset->setPrimType(osg::GeoSet::POINTS); + stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateSet->setMode(GL_POINT_SMOOTH, osg::StateAttribute::ON); + dgset->setColorBinding(osg::GeoSet::BIND_PERVERTEX); osg::Point* point = new osg::Point; if (point) { - point->setSize( pSLightPoint->sfSize ); + 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 +// point->setStateSetModes(*stateSet, osg::StateAttribute::ON); // GL_POINT_SMOOTH } // Visit vertices - for(int i=0; i < rec->getNumChildren(); i++) - { - Record* child = rec->getChild(i); - - if (child) - { - int op = child->getOpcode(); - switch (op) - { - case VERTEX_LIST_OP: - { - int vertices = visitVertexList(pBuilder, (VertexListRecord*)child); - for (int v=0; vaddPrimLen(1); - } - break; - - case OLD_VERTEX_OP: - case OLD_VERTEX_COLOR_OP: - case OLD_VERTEX_COLOR_NORMAL_OP: - pBuilder->addVertex(child); - pBuilder->addPrimLen(1); - break; - } - } - } - + addVertices(pBuilder, rec); pBuilder->addPrimitive(); } diff --git a/src/osgPlugins/flt/flt2osg.h b/src/osgPlugins/flt/flt2osg.h index 32cc18979..1db4f33cb 100644 --- a/src/osgPlugins/flt/flt2osg.h +++ b/src/osgPlugins/flt/flt2osg.h @@ -6,13 +6,12 @@ #include #include -#include "Record.h" -#include "FltFile.h" - #include #include #include +#include "Record.h" +#include "GeoSetBuilder.h" namespace osg { class Object; @@ -52,19 +51,62 @@ class LightPointRecord; class VertexListRecord; class LongIDRecord; -class GeoSetBuilder; +//class GeoSetBuilder; struct SMaterial; +#define ADD_NORMAL(DGSET,VERTEX) \ + (DGSET)->addNormal(osg::Vec3( \ + (float)(VERTEX)->Normal.x(), \ + (float)(VERTEX)->Normal.y(), \ + (float)(VERTEX)->Normal.z())); + +#define ADD_VERTEX_COLOR(DGSET,VERTEX,COLOR_POOL) \ + { \ + if ((VERTEX)->swFlags & V_NO_COLOR_BIT) \ + (DGSET)->addColor(_faceColor); \ + else \ + { \ + if ((VERTEX)->swFlags & V_PACKED_COLOR_BIT) \ + (DGSET)->addColor(pVert->PackedColor.get()); \ + else \ + (DGSET)->addColor((COLOR_POOL)->getColor((VERTEX)->dwVertexColorIndex)); \ + } \ + } + +#define ADD_TCOORD(DGSET,VERTEX) \ + (DGSET)->addTCoord(osg::Vec2( \ + (float)(VERTEX)->Texture.x(), \ + (float)(VERTEX)->Texture.y())); + +#define ADD_OLD_COLOR(DGSET,VERTEX,COLOR_POOL) \ + { \ + if (COLOR_POOL) \ + (DGSET)->addColor((COLOR_POOL)->getColor((VERTEX)->color_index)); \ + else \ + (DGSET)->addColor(osg::Vec4(1,1,1,1)); \ + } + +#define ADD_OLD_TCOORD(DGSET,VERTEX) \ + (DGSET)->addTCoord(osg::Vec2( \ + (float)(VERTEX)->t[0], \ + (float)(VERTEX)->t[1])); + +#define ADD_OLD_NORMAL(DGSET,VERTEX) \ + (DGSET)->addNormal(osg::Vec3( \ + (float)pVert->n[0] / (1<<30), \ + (float)pVert->n[1] / (1<<30), \ + (float)pVert->n[2] / (1<<30))); + class ConvertFromFLT { public: - ConvertFromFLT(FltFile* pFltFile); + ConvertFromFLT(); virtual ~ConvertFromFLT(); - osg::Node* convert(Record* rec); + osg::Node* convert(HeaderRecord* rec); osg::Node* visitNode(osg::Group* osgParent,Record* rec); osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec); @@ -97,20 +139,21 @@ class ConvertFromFLT private: + int addVertices(GeoSetBuilder* pBuilder, PrimNodeRecord* primRec); + int addVertex(GeoSetBuilder* pBuilder, Record* rec); Record* getVertexFromPool(int nOffset); void regisiterVertex(int nOffset, Record* pRec); typedef std::map VertexPaletteOffsetMap; VertexPaletteOffsetMap _VertexPaletteOffsetMap; - osg::ref_ptr _pFltFile; - int _diOpenFlightVersion; int _diCurrentOffset; unsigned short _wObjTransparency; int _nSubfaceLevel; - float _sfHdrUnitScale; // iMultDivUnit + double _unitScale; bool _bHdrRgbMode; + osg::Vec4 _faceColor; }; diff --git a/src/osgPlugins/flt/opcodes.h b/src/osgPlugins/flt/opcodes.h index 1d16dd7b9..66ee00af3 100644 --- a/src/osgPlugins/flt/opcodes.h +++ b/src/osgPlugins/flt/opcodes.h @@ -8,43 +8,43 @@ #define UNKNOWN_OP 0 -#define HEADER_OP 1 -#define GROUP_OP 2 +#define HEADER_OP 1 +#define GROUP_OP 2 #define OLD_LOD_OP 3 -#define OBJECT_OP 4 -#define FACE_OP 5 +#define OBJECT_OP 4 +#define FACE_OP 5 #define OLD_VERTEX_OP 7 #define OLD_VERTEX_COLOR_OP 8 #define OLD_VERTEX_COLOR_NORMAL_OP 9 -#define PUSH_LEVEL_OP 10 -#define POP_LEVEL_OP 11 -#define DOF_OP 14 +#define PUSH_LEVEL_OP 10 +#define POP_LEVEL_OP 11 +#define DOF_OP 14 #define PUSH_SUBFACE_OP 19 #define POP_SUBFACE_OP 20 #define PUSH_EXTENSION_OP 21 #define POP_EXTENSION_OP 22 -#define COMMENT_OP 31 -#define COLOR_PALETTE_OP 32 +#define COMMENT_OP 31 +#define COLOR_PALETTE_OP 32 #define LONG_ID_OP 33 /* Ignore 40-48 #define OLD_TRANSLATE_OP 44 */ -#define MATRIX_OP 49 +#define MATRIX_OP 49 #define VECTOR_OP 50 -#define REPLICATE_OP 60 -#define INSTANCE_REFERENCE_OP 61 -#define INSTANCE_DEFINITION_OP 62 -#define EXTERNAL_REFERENCE_OP 63 -#define TEXTURE_PALETTE_OP 64 +#define REPLICATE_OP 60 +#define INSTANCE_REFERENCE_OP 61 +#define INSTANCE_DEFINITION_OP 62 +#define EXTERNAL_REFERENCE_OP 63 +#define TEXTURE_PALETTE_OP 64 #define OLD_MATERIAL_PALETTE_OP 66 -#define VERTEX_PALETTE_OP 67 +#define VERTEX_PALETTE_OP 67 #define VERTEX_C_OP 68 #define VERTEX_CN_OP 69 #define VERTEX_CNT_OP 70 #define VERTEX_CT_OP 71 #define VERTEX_LIST_OP 72 -#define LOD_OP 73 +#define LOD_OP 73 #define BOUNDING_BOX_OP 74 /* Ignore 76-82