Updates to the flt loader from Brede Johansen.

This commit is contained in:
Robert Osfield
2001-11-01 16:35:26 +00:00
parent f7a2567bca
commit aa725e899a
32 changed files with 1061 additions and 1359 deletions

View File

@@ -29,17 +29,10 @@ ColorPaletteRecord::~ColorPaletteRecord()
// virtual
void ColorPaletteRecord::endian()
{
// note, sizeof returns unsigned int, while getSize() etc returns
// int, this correctly generates a warning when comparisons are made
// under Linux. This really needs to be fixed so getSize() returns
// an unsigned int. I won't do it now as it may well break code
// which I don't fully understand. I've made the hacky use of an
// (int) cast to fix the warning, I don't think this will cause an
// problems. RO August 2001.
if (getSize() > (int) sizeof(SOldColorPalette))
if (getSize() > sizeof(SOldColorPalette))
{
SColorPalette* pSColor = (SColorPalette*)getData();
int nOffset = sizeof(SColorPalette);
size_t nOffset = sizeof(SColorPalette);
if (nOffset < getSize())
{
@@ -58,7 +51,7 @@ void ColorPaletteRecord::endian()
else // version 11, 12 & 13
{
SOldColorPalette* pSColor = (SOldColorPalette*)getData();
unsigned int i;
size_t i;
for (i=0; i < sizeof(pSColor->Colors)/sizeof(pSColor->Colors[0]); i++)
{
ENDIAN( pSColor->Colors[i]._red );

View File

@@ -63,7 +63,7 @@ class DofRecord : public PrimNodeRecord
virtual Record* clone() const { return new DofRecord(); }
virtual const char* className() const { return "DofRecord"; }
virtual int classOpcode() const { return DOF_OP; }
virtual int sizeofData() const { return sizeof(SDegreeOfFreedom); }
virtual size_t sizeofData() const { return sizeof(SDegreeOfFreedom); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -43,7 +43,7 @@ class ExtensionRecord : public PrimNodeRecord
virtual Record* clone() const { return new ExtensionRecord(); }
virtual const char* className() const { return "ExtensionRecord"; }
virtual int classOpcode() const { return EXTENSION_OP; }
virtual int sizeofData() const { return sizeof(SExtension); }
virtual size_t sizeofData() const { return sizeof(SExtension); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -69,7 +69,7 @@ void FaceRecord::endian()
ENDIAN( pSFace->wTransparency );
// Added after version 13
if (getSize() >= sizeof(SFace))
if (Registry::instance()->getVersion() > 13)
{
ENDIAN( pSFace->dwFlags );
// ENDIAN( pSFace->PrimaryPackedColor );

View File

@@ -117,7 +117,7 @@ class FaceRecord : public PrimNodeRecord
virtual Record* clone() const { return new FaceRecord(); }
virtual const char* className() const { return "FaceRecord"; }
virtual int classOpcode() const { return FACE_OP; }
virtual int sizeofData() const { return sizeof(SFace); }
virtual size_t sizeofData() const { return sizeof(SFace); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -162,7 +162,7 @@ class VertexListRecord : public PrimNodeRecord
virtual Record* clone() const { return new VertexListRecord(); }
virtual const char* className() const { return "VertexListRecord"; }
virtual int classOpcode() const { return VERTEX_LIST_OP; }
virtual int sizeofData() const { return sizeof(SSingleVertexList); }
virtual size_t sizeofData() const { return sizeof(SSingleVertexList); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -200,7 +200,7 @@ class MorphVertexListRecord : public PrimNodeRecord
virtual Record* clone() const { return new MorphVertexListRecord(); }
virtual const char* className() const { return "MorphVertexListRecord"; }
virtual int classOpcode() const { return MORPH_VERTEX_LIST_OP; }
virtual int sizeofData() const { return sizeof(SMorphVertexList); }
virtual size_t sizeofData() const { return sizeof(SMorphVertexList); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -240,7 +240,7 @@ class VectorRecord : public AncillaryRecord
virtual Record* clone() const { return new VectorRecord(); }
virtual const char* className() const { return "VectorRecord"; }
virtual int classOpcode() const { return VECTOR_OP; }
virtual int sizeofData() const { return sizeof(SVector); }
virtual size_t sizeofData() const { return sizeof(SVector); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -1,11 +1,3 @@
// FltFile.cpp
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osg/Notify>
#include <osgDB/FileUtils>
#include "FltFile.h"
#include "Registry.h"
#include "Record.h"
@@ -14,32 +6,63 @@
#include "flt2osg.h" // ConvertFromFLT
#include "Input.h"
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osg/Notify>
#include <osgDB/FileUtils>
#include <string>
using namespace flt;
FltFile::FltFile(
ColorPool* pColorPool,
TexturePool* pTexturePool,
MaterialPool* pMaterialPool)
FltFile::FltFile(
ColorPool* pColorPool,
TexturePool* pTexturePool,
MaterialPool* pMaterialPool)
{
_pColorPool = pColorPool;
_pHeaderRecord = NULL;
if (pColorPool)
{
// use external color palette, ignore internal
_useColorPalette = false;
setColorPool( pColorPool );
}
else
{
// use internal color palette
_useColorPalette = true;
setColorPool( new ColorPool );
}
if (pTexturePool)
_pTexturePool = pTexturePool;
{
// use external texture palette, ignore internal
_useTexturePalette = false;
setTexturePool( pTexturePool );
}
else
_pTexturePool = &_texturePool;
{
// use internal texture palette
_useTexturePalette = true;
setTexturePool( new TexturePool );
}
if (pMaterialPool)
_pMaterialPool = pMaterialPool;
{
// use external material palette, ignore internal
_useMaterialPalette = false;
setMaterialPool( pMaterialPool );
}
else
_pMaterialPool = &_materialPool;
_pHeaderRecord = NULL;
}
FltFile::~FltFile()
{
{
// use internal material palette
_useMaterialPalette = true;
setMaterialPool( new MaterialPool );
}
}
@@ -116,62 +139,63 @@ Record* FltFile::readFile(const std::string& fileName)
}
class ReadExternal : public RecordVisitor
{
public:
ReadExternal(FltFile* fltFile)
{
_fltFile = fltFile;
setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN);
}
#define REGISTER_FLT 1
virtual void apply(ExternalRecord& rec)
{
SExternalReference* pSExternal = (SExternalReference*)rec.getData();
if (pSExternal)
class ReadExternal : public RecordVisitor
{
public:
ReadExternal(FltFile* fltFile)
{
FltFile* flt = NULL;
ColorPool* pColorPool = NULL;
TexturePool* pTexturePool = NULL;
MaterialPool* pMaterialPool = NULL;
std::string filename(pSExternal->szPath);
_parentFltFile = fltFile;
setTraverseMode(RecordVisitor::TRAVERSE_ALL_CHILDREN);
}
osg::notify(osg::INFO) << "External=" << filename << endl;
virtual void apply(ExternalRecord& rec)
{
SExternalReference* pSExternal = (SExternalReference*)rec.getData();
if (_fltFile && _fltFile->getFlightVersion() > 13)
if (pSExternal)
{
if (pSExternal->diFlags & BIT0)
pColorPool = _fltFile->getColorPool();
FltFile* flt = NULL;
ColorPool* pColorPool = NULL;
TexturePool* pTexturePool = NULL;
MaterialPool* pMaterialPool = NULL;
std::string filename(pSExternal->szPath);
if (pSExternal->diFlags & BIT2)
pTexturePool = _fltFile->getTexturePool();
osg::notify(osg::INFO) << "External=" << filename << endl;
if (pSExternal->diFlags & BIT1)
pMaterialPool = _fltFile->getMaterialPool();
}
if (_parentFltFile && (_parentFltFile->getFlightVersion() > 13))
{
if (pSExternal->diFlags & BIT0)
pColorPool = _parentFltFile->getColorPool();
if (pSExternal->diFlags & BIT2)
pTexturePool = _parentFltFile->getTexturePool();
if (pSExternal->diFlags & BIT1)
pMaterialPool = _parentFltFile->getMaterialPool();
}
#if REGISTER_FLT
flt = Registry::instance()->getFltFile(filename);
if (flt == NULL)
{
flt = Registry::instance()->getFltFile(filename);
if (flt == NULL)
{
flt = new FltFile(pColorPool, pTexturePool, pMaterialPool);
flt->readModel(filename);
}
Registry::instance()->addFltFile(filename, flt);
#else
flt = new FltFile(pColorPool, pTexturePool, pMaterialPool);
flt->readModel(filename);
}
Registry::instance()->addFltFile(filename, flt);
#else
flt = new FltFile(pColorPool, pTexturePool, pMaterialPool);
flt->readModel(filename);
#endif
rec.setExternal(flt);
rec.setExternal(flt);
}
}
}
public:
FltFile* _fltFile;
public:
FltFile* _parentFltFile;
};

View File

@@ -20,45 +20,50 @@ class Record;
class FltFile : public osg::Referenced
{
public:
FltFile(
ColorPool* pColorPool = NULL,
TexturePool* pTexturePool = NULL,
MaterialPool* pMaterialPool = NULL);
virtual ~FltFile();
public:
FltFile(
ColorPool* pColorPool = NULL,
TexturePool* pTexturePool = NULL,
MaterialPool* pMaterialPool = NULL);
virtual osg::Object* readObject(const std::string& fileName);
virtual osg::Node* readNode(const std::string& fileName);
osg::Node* convert();
Record* getHeaderRecord() { return _pHeaderRecord; }
Record* readModel(const std::string& fileName);
virtual osg::Object* readObject(const std::string& fileName);
virtual osg::Node* readNode(const std::string& fileName);
osg::Node* convert();
Record* getHeaderRecord() { return _pHeaderRecord; }
Record* readModel(const std::string& fileName);
ColorPool* getColorPool() { return _pColorPool; }
TexturePool* getTexturePool() { return _pTexturePool; }
MaterialPool* getMaterialPool() { return _pMaterialPool; }
ColorPool* getColorPool() { return _colorPool.get(); }
TexturePool* getTexturePool() { return _texturePool.get(); }
MaterialPool* getMaterialPool() { return _materialPool.get(); }
void useLocalColorPool() { _pColorPool = &_colorPool; }
void useLocalTexturePool() { _pTexturePool = &_texturePool; }
void useLocalMaterialPool() { _pMaterialPool = &_materialPool; }
void setColorPool(ColorPool* colorPool) { _colorPool = colorPool; }
void setTexturePool(TexturePool* texturePool) { _texturePool = texturePool; }
void setMaterialPool(MaterialPool* materialPool){ _materialPool = materialPool; }
int getFlightVersion();
inline const bool useColorPalette() const { return _useColorPalette; }
inline const bool useTexturePalette() const { return _useTexturePalette; }
inline const bool useMaterialPalette() const { return _useMaterialPalette; }
protected:
int getFlightVersion();
Record* readFile(const std::string& fileName);
void readExternals(Record* pRec);
protected:
private:
virtual ~FltFile() {}
Record* _pHeaderRecord;
Record* readFile(const std::string& fileName);
void readExternals(Record* pRec);
ColorPool _colorPool;
TexturePool _texturePool;
MaterialPool _materialPool;
private:
ColorPool* _pColorPool;
TexturePool* _pTexturePool;
MaterialPool* _pMaterialPool;
Record* _pHeaderRecord;
bool _useColorPalette;
bool _useTexturePalette;
bool _useMaterialPalette;
osg::ref_ptr<ColorPool> _colorPool;
osg::ref_ptr<TexturePool> _texturePool;
osg::ref_ptr<MaterialPool> _materialPool;
};

View File

@@ -16,8 +16,9 @@
#include <osg/Object>
#include <osg/LOD>
#include <osg/Transparency>
#include <osg/GeoSet>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/StateSet>
#include <osg/Material>
#include <osg/Texture>
#include <osg/TexEnv>
@@ -31,6 +32,328 @@
using namespace flt;
////////////////////////////////////////////////////////////////////
//
// TmpGeoSet
//
////////////////////////////////////////////////////////////////////
// GeoSet with dynamic vertex size.
TmpGeoSet::TmpGeoSet(FltFile* pFltFile)
{
_geoSet = new osg::GeoSet;
_geoSet->setStateSet( new osg::StateSet );
_colorPool = pFltFile->getColorPool();
_texturePool = pFltFile->getTexturePool();
_materialPool = pFltFile->getMaterialPool();
}
osg::GeoSet* TmpGeoSet::createOsgGeoSet()
{
int prims = _primLenList.size();
int indices = _vertexRecList.size();
if (prims==0 || indices==0)
return NULL;
osg::GeoSet* gset = getGeoSet();
gset->setNumPrims(prims);
// prim lengths
switch( gset->getPrimType() )
{
case osg::GeoSet::QUAD_STRIP :
case osg::GeoSet::FLAT_TRIANGLE_FAN :
case osg::GeoSet::TRIANGLE_FAN :
case osg::GeoSet::LINE_LOOP :
case osg::GeoSet::LINE_STRIP :
case osg::GeoSet::FLAT_LINE_STRIP :
case osg::GeoSet::TRIANGLE_STRIP :
case osg::GeoSet::FLAT_TRIANGLE_STRIP :
case osg::GeoSet::POLYGON :
{
int *lens = new int[prims];
gset->setPrimLengths( lens );
for (int n=0; n < prims; n++)
lens[n] = _primLenList[n];
}
break;
}
// create osg compatible buffers
gset->setCoords(new osg::Vec3[indices]);
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
gset->setColors(new osg::Vec4[indices]);
if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
gset->setNormals(new osg::Vec3[indices]);
if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
gset->setTextureCoords(new osg::Vec2[indices]);
// Copy vertices across
{
int index;
VertexRecList::iterator itr;
for(index=0, itr=_vertexRecList.begin();
itr!=_vertexRecList.end();
++index, ++itr)
{
setVertex(gset, index, itr->get());
}
}
return gset;
}
void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex)
{
osg::Vec3* coords = gset->getCoords();
osg::Vec4* colors = gset->getColors();
osg::Vec3* normals = gset->getNormals();
osg::Vec2* texuv = gset->getTextureCoords();
switch(vertex->getOpcode())
{
case VERTEX_C_OP:
{
SVertex* pVert = (SVertex*)vertex->getData();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = osg::Vec4(1,1,1,1);
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _colorPool.get();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CN_OP:
{
SNormalVertex* pVert = (SNormalVertex*)vertex->getData();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
{
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
normals[index].normalize();
}
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = osg::Vec4(1,1,1,1);
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _colorPool.get();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CNT_OP:
{
SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
{
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
normals[index].normalize();
}
if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
{
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
}
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = osg::Vec4(1,1,1,1);
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _colorPool.get();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CT_OP:
{
STextureVertex* pVert = (STextureVertex*)vertex->getData();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
{
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
}
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = osg::Vec4(1,1,1,1);
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _colorPool.get();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case OLD_VERTEX_OP:
{
SOldVertex* pVert = (SOldVertex*)vertex->getData();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
&& (vertex->getSize() >= sizeof(SOldVertex)))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
case OLD_VERTEX_COLOR_OP:
{
SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
osg::Vec4* colors = gset->getColors();
ColorPool* pColorPool = _colorPool.get();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->color_index);
else
colors[index] = osg::Vec4(1,1,1,1);
}
if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
&& (vertex->getSize() >= sizeof(SOldVertexColor)))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
{
SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
if (gset->getNormalBinding() == osg::GeoSet::BIND_PERVERTEX)
{
normals[index].set(
(float)pVert->n[0] / (1<<30), // =pow(2,30)
(float)pVert->n[1] / (1<<30),
(float)pVert->n[2] / (1<<30));
normals[index].normalize();
}
if (gset->getColorBinding() == osg::GeoSet::BIND_PERVERTEX)
{
osg::Vec4* colors = gset->getColors();
ColorPool* pColorPool = _colorPool.get();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->color_index);
else
colors[index] = osg::Vec4(1,1,1,1);
}
if ((gset->getTextureBinding() == osg::GeoSet::BIND_PERVERTEX)
&& (vertex->getSize() >= sizeof(SOldVertexColorNormal)))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
}
}
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
@@ -47,22 +370,10 @@ GeoSetBuilder::GeoSetBuilder(FltFile* pFltFile)
}
// virtual
GeoSetBuilder::~GeoSetBuilder()
{
for(GeoSetList::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
++itr)
{
delete *itr;
}
}
void GeoSetBuilder::initPrimData()
{
_appearance.init();
_aVertex.clear();
_tmpGeoSet = new TmpGeoSet(_pFltFile.get());
}
@@ -80,8 +391,8 @@ osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode)
bInternalGeodeAllocation = true;
}
for(GeoSetList::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin();
itr!=_tmpGeoSetList.end();
++itr)
{
osg::GeoSet* gset = (*itr)->createOsgGeoSet();
@@ -99,88 +410,70 @@ osg::Geode* GeoSetBuilder::createOsgGeoSets(osg::Geode* geode)
}
void GeoSetBuilder::addVertex(Record* vertex)
{
_aVertex.push_back(vertex);
_appearance.setVertexOp(vertex->getOpcode());
}
bool GeoSetBuilder::addPrimitive()
{
int nVertices = _aVertex.size();
osg::GeoSet* geoset = getGeoSet();
if (nVertices == 0) return false;
if (geoset->getPrimType() == osg::GeoSet::NO_TYPE)
geoset->setPrimType(findPrimType(numberOfVertices()));
if (_appearance.getPrimType() == osg::GeoSet::NO_TYPE)
_appearance.setPrimType(findPrimType(nVertices));
// Still no primitive type?
if (geoset->getPrimType() == osg::GeoSet::NO_TYPE)
return false;
TmpGeoSet* gset = findMatchingGeoSet();
if (gset)
{
addTo(gset);
if (_appearance.getMaterial())
{
_appearance.getMaterial()->unref();
_appearance.setMaterial(NULL);
}
}
TmpGeoSet* match = findMatchingGeoSet();
if (match)
// append vertices and prim length to match
match->addVertices( _tmpGeoSet.get() );
else
addToNew();
// add new GeoSet+StateSet compination
_tmpGeoSetList.push_back(_tmpGeoSet.get());
initPrimData();
initPrimData(); // initialize _tmpGeoSet
return true;
}
//////////////////////// protected /////////////////////////////////
TmpGeoSet* GeoSetBuilder::findMatchingGeoSet()
{
osg::GeoSet* geoSet = getGeoSet();
osg::StateSet* stateSet = geoSet->getStateSet();
for(std::vector<TmpGeoSet*>::iterator itr=_aGeoSet.begin();
itr!=_aGeoSet.end();
for(TmpGeoSetList::iterator itr=_tmpGeoSetList.begin();
itr!=_tmpGeoSetList.end();
++itr)
{
if (_appearance == (*itr)->_appearance)
return *itr;
TmpGeoSet* tmpgeoset = itr->get();
osg::GeoSet* gset = tmpgeoset->getGeoSet();
osg::StateSet* sset = gset->getStateSet();
// Do we have a match?
if ((geoSet->getPrimType() == gset->getPrimType())
&& (geoSet->getColorBinding() == gset->getColorBinding())
&& (geoSet->getNormalBinding() == gset->getNormalBinding())
&& (geoSet->getTextureBinding() == gset->getTextureBinding())
&& (stateSet->compare(*sset, true) == 0))
{
if (geoSet->getColorBinding() == osg::GeoSet::BIND_OVERALL)
{
osg::Vec4* col1 = geoSet->getColors();
osg::Vec4* col2 = gset->getColors();
if (*col1 != *col2)
return NULL;
}
return tmpgeoset;
}
}
return NULL;
}
void GeoSetBuilder::addTo(TmpGeoSet* gset)
osg::GeoSet::PrimitiveType GeoSetBuilder::findPrimType(const int nVertices)
{
int nVertices = _aVertex.size();
gset->addPrimLen(nVertices);
for(std::vector<Record*>::iterator itr=_aVertex.begin();
itr!=_aVertex.end();
++itr)
{
gset->addVertex(*itr);
}
}
void GeoSetBuilder::addToNew()
{
TmpGeoSet* gset = new TmpGeoSet(_pFltFile);
if (gset == NULL) return;
// Transfer data to TmpGeoSet
gset->_appearance = _appearance;
addTo(gset);
_aGeoSet.push_back(gset);
}
PrimitiveType GeoSetBuilder::findPrimType( int nVertices)
{
PrimitiveType primtype = osg::GeoSet::NO_TYPE;
osg::GeoSet::PrimitiveType primtype = osg::GeoSet::NO_TYPE;
switch (nVertices)
{
@@ -205,446 +498,3 @@ PrimitiveType GeoSetBuilder::findPrimType( int nVertices)
}
////////////////////////////////////////////////////////////////////
//
// TmpGeoSet
//
////////////////////////////////////////////////////////////////////
// GeoSet with dynamic size. Used by GeoSetBuilder as a temp. buffer.
TmpGeoSet::TmpGeoSet(FltFile* pFltFile)
{
_pFltFile = pFltFile;
}
TmpGeoSet::~TmpGeoSet()
{
}
void TmpGeoSet::addVertex(Record* vertex)
{
_appearance.setVertexOp(vertex->getOpcode());
_aVertex.push_back(vertex);
}
void TmpGeoSet::addPrimLen(int len)
{
_aPrimLen.push_back(len);
}
osg::GeoSet* TmpGeoSet::createOsgGeoSet()
{
int prims = _aPrimLen.size();
int indices = _aVertex.size();
if (prims==0 || indices==0)
return NULL;
osg::GeoSet* gset = new osg::GeoSet;
gset->setNumPrims(prims);
gset->setPrimType(_appearance.getPrimType());
osg::StateSet* gstate = new osg::StateSet;
gset->setStateSet(gstate);
// Material
osg::Material* osgMaterial = _appearance.getMaterial();
if (osgMaterial)
gstate->setAttribute(osgMaterial);
// Color
switch(_appearance.getColorBinding())
{
case osg::GeoSet::BIND_OVERALL:
{
osg::Vec4* color = new osg::Vec4[1];
*color = _appearance.getFaceColor();
gset->setColorBinding(osg::GeoSet::BIND_OVERALL);
gset->setColors(color);
}
break;
case osg::GeoSet::BIND_PERVERTEX:
{
gset->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setColors(new osg::Vec4[indices]);
}
break;
}
// Transparency
if (_appearance.getTransparency())
{
gstate->setMode(GL_BLEND,osg::StateAttribute::ON);
gstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
// Cull face
if (_appearance.getCullface())
{
osg::CullFace* cullface = new osg::CullFace;
if (cullface)
{
cullface->setMode(osg::CullFace::BACK);
gstate->setAttributeAndModes(cullface, osg::StateAttribute::ON);
}
}
else
{
gstate->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
}
// Texture
if (_appearance.getTexture())
{
gstate->setAttributeAndModes( _appearance.getTexture(), osg::StateAttribute::ON );
gstate->setAttribute( new osg::TexEnv );
}
// Lighting
if (_appearance.getLighting())
gstate->setMode( GL_LIGHTING, osg::StateAttribute::ON );
else
gstate->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
// Subface
if (_appearance.getSubface() > 0)
{
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
if (polyoffset)
{
int level = _appearance.getSubface();
polyoffset->setFactor(-1*level);
polyoffset->setUnits(-20*level);
gstate->setAttributeAndModes(polyoffset,osg::StateAttribute::ON);
}
}
// Point
if (_appearance.getPrimType() == osg::GeoSet::POINTS)
{
osg::Point* point = new osg::Point;
if (point)
{
point->setSize(8);
gstate->setAttributeAndModes(point,osg::StateAttribute::ON);
}
}
// PrimLengths
int nPrimLenSize = 1;
if (_appearance.getPrimType() == osg::GeoSet::POLYGON)
nPrimLenSize = prims;
int *lens = new int[nPrimLenSize];
gset->setPrimLengths( lens );
for (int n=0; n < nPrimLenSize; n++)
lens[n] = _aPrimLen[n];
// Vertices
switch(_appearance.getVertexOp())
{
case VERTEX_C_OP:
gset->setCoords(new osg::Vec3[indices]);
break;
case VERTEX_CN_OP:
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setNormals(new osg::Vec3[indices]);
break;
case VERTEX_CT_OP:
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setTextureCoords(new osg::Vec2[indices]);
break;
case VERTEX_CNT_OP:
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setCoords(new osg::Vec3[indices]);
gset->setNormals(new osg::Vec3[indices]);
gset->setTextureCoords(new osg::Vec2[indices]);
break;
case OLD_VERTEX_OP:
gset->setCoords(new osg::Vec3[indices]);
if (_appearance.getTexture())
{
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setTextureCoords(new osg::Vec2[indices]);
}
break;
case OLD_VERTEX_COLOR_OP:
gset->setCoords(new osg::Vec3[indices]);
if (_appearance.getTexture())
{
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setTextureCoords(new osg::Vec2[indices]);
}
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
gset->setCoords(new osg::Vec3[indices]);
gset->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setNormals(new osg::Vec3[indices]);
if (_appearance.getTexture())
{
gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
gset->setTextureCoords(new osg::Vec2[indices]);
}
break;
}
// Copy vertices
{
int index;
std::vector<Record*>::iterator itr;
for(index=0, itr=_aVertex.begin();
itr!=_aVertex.end();
++index, ++itr)
{
setVertex(gset, index, *itr);
}
}
return gset;
}
///////////////////////// private //////////////////////////////////
void TmpGeoSet::setVertex(osg::GeoSet* gset, int index, Record* vertex)
{
bool bColorBindPerVertex = _appearance.getColorBinding() == osg::GeoSet::BIND_PERVERTEX;
switch(_appearance.getVertexOp())
{
case VERTEX_C_OP:
{
SVertex* pVert = (SVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = _appearance.getFaceColor();
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CN_OP:
{
SNormalVertex* pVert = (SNormalVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec3* normals = gset->getNormals();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = _appearance.getFaceColor();
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CNT_OP:
{
SNormalTextureVertex* pVert = (SNormalTextureVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec3* normals = gset->getNormals();
osg::Vec2* texuv = gset->getTextureCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
normals[index].set(
(float)pVert->Normal.x(),
(float)pVert->Normal.y(),
(float)pVert->Normal.z());
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = _appearance.getFaceColor();
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case VERTEX_CT_OP:
{
STextureVertex* pVert = (STextureVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec2* texuv = gset->getTextureCoords();
coords[index].set(
(float)pVert->Coord.x(),
(float)pVert->Coord.y(),
(float)pVert->Coord.z());
texuv[index].set(
(float)pVert->Texture.x(),
(float)pVert->Texture.y());
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
if (pVert->swFlags & V_NO_COLOR_BIT)
colors[index] = _appearance.getFaceColor();
else
{
if (pVert->swFlags & V_PACKED_COLOR_BIT)
colors[index] = pVert->PackedColor.get();
else
{
ColorPool* pColorPool = _pFltFile->getColorPool();
colors[index] = pColorPool->getColor(pVert->dwVertexColorIndex);
}
}
}
}
break;
case OLD_VERTEX_OP:
{
SOldVertex* pVert = (SOldVertex*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec2* texuv = gset->getTextureCoords();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
if (texuv && vertex->getSize() >= sizeof(SOldVertex))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
case OLD_VERTEX_COLOR_OP:
{
SOldVertexColor* pVert = (SOldVertexColor*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec2* texuv = gset->getTextureCoords();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->color_index);
else
colors[index] = _appearance.getFaceColor();
}
if (texuv && vertex->getSize() >= sizeof(SOldVertexColor))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
{
SOldVertexColorNormal* pVert = (SOldVertexColorNormal*)vertex->getData();
osg::Vec3* coords = gset->getCoords();
osg::Vec3* normals = gset->getNormals();
osg::Vec2* texuv = gset->getTextureCoords();
coords[index].set(
(float)pVert->v[0],
(float)pVert->v[1],
(float)pVert->v[2]);
normals[index].set(
(float)pVert->n[0] / (1<<30), // =pow(2,30)
(float)pVert->n[1] / (1<<30),
(float)pVert->n[2] / (1<<30));
if (bColorBindPerVertex)
{
osg::Vec4* colors = gset->getColors();
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool)
colors[index] = pColorPool->getColor(pVert->color_index);
else
colors[index] = _appearance.getFaceColor();
}
if (texuv && vertex->getSize() >= sizeof(SOldVertexColorNormal))
{
texuv[index].set(
(float)pVert->t[0],
(float)pVert->t[1]);
}
}
break;
}
}

View File

@@ -1,25 +1,17 @@
// GeoSetBuilder.h
#ifndef __FLT_GEOSETBUILDER_H
#define __FLT_GEOSETBUILDER_H
#ifndef __FLT_GEOSETS_H
#define __FLT_GEOSETS_H
#include <map>
#include <vector>
#include <osg/GeoSet>
#include <osg/Material>
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/GeoSet>
#include <osg/Material>
#include <osg/StateSet>
namespace osg {
class Node;
class LOD;
class Geode;
class GeoState;
class Texture;
}
#include <map>
#include <vector>
namespace flt {
@@ -27,171 +19,6 @@ namespace flt {
class Record;
class TmpGeoSet;
typedef osg::GeoSet::PrimitiveType PrimitiveType;
typedef std::vector<osg::Vec3> CoordList;
typedef std::vector<osg::Vec3> NormalList;
typedef std::vector<osg::Vec2> TexUVList;
typedef std::vector<osg::Vec4> ColorList;
typedef std::vector<Record*> VertexList;
typedef std::vector<int> PrimLenList;
class Appearance
{
public:
typedef osg::GeoSet::BindingType BindingType;
Appearance() { init(); }
void init()
{
_nVertexOp = 0;
_primtype = osg::GeoSet::NO_TYPE;
_material = NULL;
_texture = NULL;
_face_color = osg::Vec4(1,1,1,1);
_color_binding = osg::GeoSet::BIND_OFF;
_cullface = false;
_transparency = false;
_lighting = false;
_subface = 0;
}
void setVertexOp(int op) { _nVertexOp = op; }
int getVertexOp() { return _nVertexOp; }
void setPrimType(PrimitiveType pt) { _primtype = pt; }
PrimitiveType getPrimType() { return _primtype; }
void setFaceColor(osg::Vec4 color) { _face_color = color; }
osg::Vec4& getFaceColor() { return _face_color; }
inline void setColorBinding( BindingType binding ) { _color_binding = binding; }
inline const BindingType getColorBinding() const { return _color_binding; }
void setMaterial(osg::Material *material) { _material = material; }
osg::Material* getMaterial() { return _material; }
void setTexture(osg::Texture *texture) { _texture = texture; }
osg::Texture* getTexture() { return _texture; }
void setCullface(bool cullface) { _cullface = cullface; }
bool getCullface() { return _cullface; }
void setTransparency(bool transp) { _transparency = transp; }
bool getTransparency() { return _transparency; }
void setLighting(bool light) { _lighting = light; }
bool getLighting() { return _lighting; }
void setSubface(int level) { _subface = level; }
int getSubface() { return _subface; }
bool mat_equal(const void *m) const
{
if (_material && m)
return !memcmp(_material, m, sizeof(osg::Material));
return (!_material && !m);
}
bool col_equal(const BindingType b, const osg::Vec4 c) const
{
if (_color_binding != b)
return false;
if (_color_binding == osg::GeoSet::BIND_OVERALL)
return (_face_color == c);
return true;
}
/*inline*/ bool operator == (const Appearance& a) const
{
return ((_nVertexOp == a._nVertexOp)
&& (_primtype == a._primtype)
&& mat_equal(a._material)
&& col_equal(a._color_binding, a._face_color)
&& (_texture == a._texture)
&& (_cullface == a._cullface)
&& (_transparency == a._transparency)
&& (_lighting == a._lighting)
&& (_subface == a._subface));
}
private:
int _nVertexOp;
PrimitiveType _primtype;
osg::Material* _material;
osg::Texture* _texture;
osg::Vec4 _face_color;
BindingType _color_binding;
bool _cullface;
bool _transparency;
bool _lighting;
int _subface;
};
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
//
////////////////////////////////////////////////////////////////////
class GeoSetBuilder
{
public:
typedef osg::GeoSet::BindingType BindingType;
GeoSetBuilder(FltFile* pFltFile);
virtual ~GeoSetBuilder();
void addVertex(Record* vertex);
void setPrimType(PrimitiveType pt) { _appearance.setPrimType(pt); }
void setFaceColor(osg::Vec4 color) { _appearance.setFaceColor(color); }
void setColorBinding(const BindingType binding) { _appearance.setColorBinding(binding); }
void setMaterial(osg::Material *material) { _appearance.setMaterial(material); }
void setTexture(osg::Texture *texture) { _appearance.setTexture(texture); }
void setCullface(bool cullface) { _appearance.setCullface(cullface); }
void setTransparency(bool transp) { _appearance.setTransparency(transp); }
void setLighting(bool light) { _appearance.setLighting(light); }
void setSubface(int level) { _appearance.setSubface(level); }
PrimitiveType getPrimType() { return _appearance.getPrimType(); }
osg::Vec4& getFaceColor() { return _appearance.getFaceColor(); }
BindingType getColorBinding() { return _appearance.getColorBinding(); }
osg::Material* getMaterial() { return _appearance.getMaterial(); }
osg::Texture* getTexture() { return _appearance.getTexture(); }
bool getCullface() { return _appearance.getCullface(); }
bool getTransparency() { return _appearance.getTransparency(); }
bool getLighting() { return _appearance.getLighting(); }
int getSubface() { return _appearance.getSubface(); }
bool addPrimitive();
osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL);
protected:
void initPrimData();
TmpGeoSet* findMatchingGeoSet();
void addTo(TmpGeoSet* gset);
void addToNew();
PrimitiveType findPrimType( int nVertices);
private:
VertexList _aVertex;
Appearance _appearance;
typedef std::vector<TmpGeoSet*> GeoSetList;
GeoSetList _aGeoSet;
FltFile* _pFltFile;
};
////////////////////////////////////////////////////////////////////
//
@@ -200,34 +27,101 @@ private:
////////////////////////////////////////////////////////////////////
class TmpGeoSet
/** TmpGeoSet - Temporary GeoSet with dynamic vertex array.
* Problem: osg::GeoSet use C arrays (static size) for coordinates,
* normals, colors and texture coordinates.
*/
class TmpGeoSet : public osg::Referenced
{
public:
public:
TmpGeoSet(FltFile* pFltFile);
virtual ~TmpGeoSet();
TmpGeoSet(FltFile* pFltFile);
virtual ~TmpGeoSet() {};
void addVertex(Record* vertex);
void addPrimLen(int len);
osg::GeoSet* createOsgGeoSet();
void addVertex(Record* vertexRec) { _vertexRecList.push_back(vertexRec); }
void addPrimLen(int len) { _primLenList.push_back(len); }
Appearance _appearance;
// Append vertices from other TmpGeoSet
void addVertices(TmpGeoSet* source)
{
_vertexRecList.insert(_vertexRecList.end(),
source->_vertexRecList.begin(), source->_vertexRecList.end());
_primLenList.insert(_primLenList.end(),
source->_primLenList.begin(), source->_primLenList.end());
}
private:
inline const int numberOfVertices() const { return _vertexRecList.size(); }
inline osg::GeoSet* getGeoSet() { return _geoSet.get(); }
inline const osg::GeoSet* getGeoSet() const { return _geoSet.get(); }
void setVertex(osg::GeoSet* gset, int index, Record* vertex);
// Create complete osg::GeoSet.
osg::GeoSet* createOsgGeoSet();
PrimLenList _aPrimLen;
VertexList _aVertex;
private:
typedef std::vector<osg::ref_ptr<Record> > VertexRecList;
typedef std::vector<int> PrimLenList;
void setVertex(osg::GeoSet* gset, int index, Record* vertex);
osg::ref_ptr<osg::GeoSet> _geoSet;
PrimLenList _primLenList;
VertexRecList _vertexRecList;
osg::ref_ptr<ColorPool> _colorPool;
osg::ref_ptr<TexturePool> _texturePool;
osg::ref_ptr<MaterialPool> _materialPool;
FltFile* _pFltFile;
};
} // end of namespace flt
////////////////////////////////////////////////////////////////////
//
// GeoSetBuilder
//
////////////////////////////////////////////////////////////////////
/** GeoSetBuilder - Contains a list of TmpGeoSets to be converted to osg::Geode.
*
*/
class GeoSetBuilder
{
public:
GeoSetBuilder(FltFile* pFltFile);
virtual ~GeoSetBuilder() {}
void addVertex(Record* vertex) { _tmpGeoSet.get()->addVertex(vertex); }
void addPrimLen(int len) { _tmpGeoSet.get()->addPrimLen(len); }
bool addPrimitive();
osg::Geode* createOsgGeoSets(osg::Geode* geode=NULL);
inline osg::GeoSet* getGeoSet() { return _tmpGeoSet.get()->getGeoSet(); }
inline const osg::GeoSet* getGeoSet() const { return _tmpGeoSet.get()->getGeoSet(); }
const int numberOfVertices() const { return _tmpGeoSet.get()->numberOfVertices(); }
protected:
void initPrimData();
TmpGeoSet* findMatchingGeoSet();
osg::GeoSet::PrimitiveType findPrimType(const int nVertices);
private:
osg::ref_ptr<FltFile> _pFltFile;
osg::ref_ptr<TmpGeoSet> _tmpGeoSet;
typedef std::vector<osg::ref_ptr<TmpGeoSet> > TmpGeoSetList;
TmpGeoSetList _tmpGeoSetList;
};
}; // end of namespace flt
#endif // __FLT_GEOSETS_H
#endif

View File

@@ -41,7 +41,7 @@ class GroupRecord : public PrimNodeRecord
virtual Record* clone() const { return new GroupRecord(); }
virtual const char* className() const { return "GroupRecord"; }
virtual int classOpcode() const { return GROUP_OP; }
virtual int sizeofData() const { return sizeof(SGroup); }
virtual size_t sizeofData() const { return sizeof(SGroup); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -117,6 +117,8 @@ void HeaderRecord::endian()
ENDIAN( pHeader->dfLambertUpperLat );
ENDIAN( pHeader->dfLambertLowerLat );
ENDIAN( pHeader->iNextLightSource );
Registry::instance()->setVersion(pHeader->diFormatRevLev);
}

View File

@@ -93,7 +93,7 @@ class HeaderRecord : public PrimNodeRecord
virtual Record* clone() const { return new HeaderRecord(); }
virtual const char* className() const { return "HeaderRecord"; }
virtual int classOpcode() const { return HEADER_OP; }
virtual int sizeofData() const { return sizeof(SHeader); }
virtual size_t sizeofData() const { return sizeof(SHeader); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
SHeader* getData() const { return (SHeader*)_pData; }

View File

@@ -172,10 +172,10 @@ Record* Input::readCreateRecord()
if (pData == NULL) return NULL;
// find matching record prototype class
Record* pProto = Registry::instance()->getRecordProto(pData->opcode());
Record* pProto = Registry::instance()->getPrototype(pData->opcode());
if (pProto == NULL)
pProto = Registry::instance()->getRecordProto(0);
pProto = Registry::instance()->getPrototype(0);
if (pProto == NULL)
{

View File

@@ -45,7 +45,7 @@ class LodRecord : public PrimNodeRecord
virtual Record* clone() const { return new LodRecord(); }
virtual const char* className() const { return "LodRecord"; }
virtual int classOpcode() const { return LOD_OP; }
virtual int sizeofData() const { return sizeof(SLevelOfDetail); }
virtual size_t sizeofData() const { return sizeof(SLevelOfDetail); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -94,7 +94,7 @@ class OldLodRecord : public PrimNodeRecord
virtual Record* clone() const { return new OldLodRecord(); }
virtual const char* className() const { return "OldLodRecord"; }
virtual int classOpcode() const { return OLD_LOD_OP; }
virtual int sizeofData() const { return sizeof(SOldLOD); }
virtual size_t sizeofData() const { return sizeof(SOldLOD); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -38,7 +38,7 @@ class MaterialPaletteRecord : public AncillaryRecord
virtual Record* clone() const { return new MaterialPaletteRecord(); }
virtual const char* className() const { return "MaterialPaletteRecord"; }
virtual int classOpcode() const { return MATERIAL_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(SMaterial); }
virtual size_t sizeofData() const { return sizeof(SMaterial); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -12,27 +12,27 @@
namespace flt {
typedef struct ObjectTag
struct SObject
{
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
uint32 dwFlags; // Flags (bits from to right)
// 0 = Don't display in daylight
// 1 = Don't display at dusk
// 2 = Don't display at night
// 3 = Don't illuminate
// 4 = Flat shaded
// 5 = Group's shadow object
// 6-31 Spare
int16 iObjectRelPriority; // Object relative priority
uint16 wTransparency; // Transparency factor
// = 0 opaque
// = 65535 for totally clear
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int16 iSignificance; // Significance
int16 iSpare; // Spare
} SObject;
SRecHeader RecHeader;
char szIdent[8]; // 7 char ASCII ID; 0 terminates
uint32 dwFlags; // Flags (bits from to right)
// 0 = Don't display in daylight
// 1 = Don't display at dusk
// 2 = Don't display at night
// 3 = Don't illuminate
// 4 = Flat shaded
// 5 = Group's shadow object
// 6-31 Spare
int16 iObjectRelPriority; // Object relative priority
uint16 wTransparency; // Transparency factor
// = 0 opaque
// = 65535 for totally clear
int16 iSpecialId_1; // Special effects ID 1 - defined by real time
int16 iSpecialId_2; // Special effects ID 2 - defined by real time
int16 iSignificance; // Significance
int16 iSpare; // Spare
};

View File

@@ -39,7 +39,7 @@ class OldMaterialPaletteRecord : public AncillaryRecord
virtual Record* clone() const { return new OldMaterialPaletteRecord(); }
virtual const char* className() const { return "OldMaterialPaletteRecord"; }
virtual int classOpcode() const { return OLD_MATERIAL_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(SOldMaterial); }
virtual size_t sizeofData() const { return sizeof(SOldMaterial); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -42,7 +42,7 @@ class OldVertexRecord : public PrimNodeRecord
virtual Record* clone() const { return new OldVertexRecord(); }
virtual const char* className() const { return "OldVertexRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_OP; }
virtual int sizeofData() const { return sizeof(SOldVertex); }
virtual size_t sizeofData() const { return sizeof(SOldVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertex* getData() const { return (SOldVertex*)_pData; }
@@ -83,7 +83,7 @@ class OldVertexColorRecord : public PrimNodeRecord
virtual Record* clone() const { return new OldVertexColorRecord(); }
virtual const char* className() const { return "OldVertexColorRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_COLOR_OP; }
virtual int sizeofData() const { return sizeof(SOldVertexColor); }
virtual size_t sizeofData() const { return sizeof(SOldVertexColor); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertexColor* getData() const { return (SOldVertexColor*)_pData; }
@@ -124,7 +124,7 @@ class OldVertexColorNormalRecord : public PrimNodeRecord
virtual Record* clone() const { return new OldVertexColorNormalRecord(); }
virtual const char* className() const { return "OldVertexColorNormalRecord"; }
virtual int classOpcode() const { return OLD_VERTEX_COLOR_NORMAL_OP; }
virtual int sizeofData() const { return sizeof(SOldVertexColorNormal); }
virtual size_t sizeofData() const { return sizeof(SOldVertexColorNormal); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SOldVertexColorNormal* getData() const { return (SOldVertexColorNormal*)_pData; }

View File

@@ -13,17 +13,6 @@
using namespace flt;
ColorPool::ColorPool()
{
}
// virtual
ColorPool::~ColorPool()
{
eraseAll();
}
osg::Vec4 ColorPool::getColor(int nColorIndex)
{
@@ -63,45 +52,20 @@ ColorPool::ColorName* ColorPool::getColorName(int nIndex)
{
ColorNameMap::iterator itr = _colorNameMap.find(nIndex);
if (itr != _colorNameMap.end())
return (*itr).second;
return (*itr).second.get();
return NULL;
}
void ColorPool::eraseAll()
{
for(ColorNameMap::iterator itr=_colorNameMap.begin();
itr!=_colorNameMap.end();
++itr)
{
ColorName* colorname = (*itr).second;
if (colorname)
delete colorname;
}
_colorNameMap.clear();
}
////////////////////////////////////////////////////////////////////
TexturePool::TexturePool()
{
}
// virtual
TexturePool::~TexturePool()
{
eraseAll();
}
osg::Texture* TexturePool::getTexture(int nIndex)
{
TexturePaletteMap::iterator fitr = _textureMap.find(nIndex);
if (fitr != _textureMap.end())
return (*fitr).second;
return (*fitr).second.get();
else
return NULL;
}
@@ -113,32 +77,15 @@ void TexturePool::addTexture(int nIndex, osg::Texture* osgTexture)
}
void TexturePool::eraseAll()
{
_textureMap.clear();
}
////////////////////////////////////////////////////////////////////
MaterialPool::MaterialPool()
{
}
// virtual
MaterialPool::~MaterialPool()
{
eraseAll();
}
PoolMaterial* MaterialPool::getMaterial(int nIndex)
MaterialPool::PoolMaterial* MaterialPool::getMaterial(int nIndex)
{
if (nIndex < 0) return NULL;
MaterialMap::iterator fitr = _MaterialMap.find(nIndex);
if (fitr != _MaterialMap.end())
return (*fitr).second;
return (*fitr).second.get();
return NULL;
}
@@ -150,15 +97,3 @@ void MaterialPool::addMaterial(int nIndex, PoolMaterial* material)
}
void MaterialPool::eraseAll()
{
for(MaterialMap::iterator itr=_MaterialMap.begin();
itr!=_MaterialMap.end();
++itr)
{
PoolMaterial* material = (*itr).second;
if (material)
delete material;
}
_MaterialMap.clear();
}

View File

@@ -1,12 +1,13 @@
// Pool.cpp
#ifndef __FLT_POOL_H
#define __FLT_POOL_H
#include "flt.h"
#include <osg/ref_ptr>
#include <osg/Referenced>
#include <osg/Vec4>
#include <osg/Texture>
#include <osg/Material>
#include <string>
#include <algorithm>
@@ -17,87 +18,89 @@
namespace flt {
class ColorPool
class ColorPool : public osg::Referenced
{
public :
public:
ColorPool();
virtual ~ColorPool();
ColorPool() {}
osg::Vec4 getColor(int nColorIndex);
void addColor(int nIndex, const osg::Vec4& color);
osg::Vec4 getColor(int nColorIndex);
void addColor(int nIndex, const osg::Vec4& color);
private:
protected :
class ColorName
{
public:
void setName( const std::string& name ) { _name = name; }
const std::string& getName( void ) { return _name; }
void setColor(const osg::Vec4& color ) { _color = color; }
osg::Vec4& getColor() { return _color; }
virtual ~ColorPool() {}
private:
osg::Vec4 _color;
std::string _name;
};
private :
void eraseAll();
ColorName* getColorName(int nIndex);
class ColorName : public osg::Referenced
{
public:
void setName( const std::string& name ) { _name = name; }
const std::string& getName( void ) { return _name; }
void setColor(const osg::Vec4& color ) { _color = color; }
osg::Vec4 getColor() { return _color; }
typedef std::map<int,ColorName*>ColorNameMap;
ColorNameMap _colorNameMap;
private:
osg::Vec4 _color;
std::string _name;
};
ColorName* getColorName(int nIndex);
typedef std::map<int,osg::ref_ptr<ColorName> > ColorNameMap;
ColorNameMap _colorNameMap;
};
class TexturePool
class TexturePool : public osg::Referenced
{
public:
public :
TexturePool();
virtual ~TexturePool();
TexturePool() {}
osg::Texture* getTexture(int nIndex);
void addTexture(int nIndex, osg::Texture* osgTexture);
osg::Texture* getTexture(int nIndex);
void addTexture(int nIndex, osg::Texture* osgTexture);
private:
protected :
void eraseAll();
virtual ~TexturePool() {}
typedef std::map<int,osg::Texture*> TexturePaletteMap;
TexturePaletteMap _textureMap;
private :
typedef std::map<int,osg::ref_ptr<osg::Texture> > TexturePaletteMap;
TexturePaletteMap _textureMap;
};
struct PoolMaterial
class MaterialPool : public osg::Referenced
{
float32x3 Ambient; // Ambient component of material
float32x3 Diffuse; // Diffuse component of material
float32x3 Specular; // Specular component of material
float32x3 Emissive; // Emissive component of material
float32 sfShininess; // Shininess. [0.0-128.0]
float32 sfAlpha; // Alpha. [0.0-1.0], where 1.0 is opaque
};
public:
struct SMaterial;
struct SOldMaterial;
struct PoolMaterial : public osg::Referenced
{
float32x3 Ambient; // Ambient component of material
float32x3 Diffuse; // Diffuse component of material
float32x3 Specular; // Specular component of material
float32x3 Emissive; // Emissive component of material
float32 sfShininess; // Shininess. [0.0-128.0]
float32 sfAlpha; // Alpha. [0.0-1.0], where 1.0 is opaque
};
MaterialPool() {}
class MaterialPool
{
public:
PoolMaterial* getMaterial(int nIndex);
void addMaterial(int nIndex, PoolMaterial* material);
MaterialPool();
virtual ~MaterialPool();
protected :
PoolMaterial* getMaterial(int nIndex);
void addMaterial(int nIndex, PoolMaterial* material);
virtual ~MaterialPool() {}
private:
private:
void eraseAll();
typedef std::map<int, PoolMaterial*> MaterialMap;
MaterialMap _MaterialMap;
typedef std::map<int, osg::ref_ptr<PoolMaterial> > MaterialMap;
MaterialMap _MaterialMap;
};

View File

@@ -16,9 +16,9 @@ using namespace flt;
osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*)
{
FltFile read;
osg::ref_ptr<FltFile> read = new FltFile;
osg::Object* obj=read.readObject(fileName);
osg::Object* obj = read.get()->readObject(fileName);
if (obj) return obj;
else return ReadResult::FILE_NOT_HANDLED;
}
@@ -26,10 +26,10 @@ osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readObject(const std::string& f
osgDB::ReaderWriter::ReadResult ReaderWriterFLT::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*)
{
FltFile read;
osg::ref_ptr<FltFile> read = new FltFile;
osg::Node* obj=read.readNode(fileName);
if (obj) return obj;
osg::Node* node = read.get()->readNode(fileName);
if (node) return node;
else return ReadResult::FILE_NOT_HANDLED;
}

View File

@@ -44,7 +44,7 @@ class Record : public osg::Referenced
virtual const char* className() const { return "Record"; } //const = 0;
virtual int classOpcode() const { return 0; } //const = 0;
virtual int sizeofData() const { return 0; } //const = 0;
virtual size_t sizeofData() const { return 0; } //const = 0;
virtual void accept(RecordVisitor& rv);
virtual void traverse(RecordVisitor&) {}
@@ -60,9 +60,9 @@ class Record : public osg::Referenced
SRecHeader* getData() const;
void* getBody() const;
int getOpcode() const;
int getSize() const;
int getHeaderLength() const;
int getBodyLength() const;
size_t getSize() const;
size_t getHeaderLength() const;
size_t getBodyLength() const;
bool isOfType(int op) const;
Record* getParent() const { return _pParent; }
@@ -115,19 +115,19 @@ int Record::getOpcode() const
}
inline
int Record::getSize() const
size_t Record::getSize() const
{
return (_pData) ? _pData->length() : 0;
}
inline
int Record::getHeaderLength() const
size_t Record::getHeaderLength() const
{
return sizeof(SRecHeader);
}
inline
int Record::getBodyLength() const
size_t Record::getBodyLength() const
{
return getSize() - getHeaderLength();
}

View File

@@ -1,7 +1,6 @@
#include <osg/Node>
#include <osg/Group>
//#include <osg/Output>
#include <osg/Notify>
#include <algorithm>
@@ -11,35 +10,20 @@
#include "Input.h"
#include "FltFile.h"
#include "Registry.h"
/*
#ifdef OSG_USE_IO_DOT_H
//#include <ostream.h>
#else
#include <iostream>
using namespace std;
#endif
#include <stdio.h>
*/
//#include <stdio.h>
using namespace flt;
// definition of the Registry
Registry::Registry()
{
osg::notify(osg::INFO) << "Constructing flt record flt::Registry\n";
}
Registry::~Registry()
{
osg::notify(osg::INFO) << "Destructing flt flt::Registry"<< endl;
// note, do not need to unrefence records as the combination of
// std::vector and ref_ptr will do it automatical on destruction.
}
// static
Registry* Registry::instance()
{
static Registry s_nodeFactory;
@@ -52,112 +36,45 @@ void Registry::addPrototype(Record* rec)
if (rec==0L) return;
osg::notify(osg::INFO) << "flt::Registry::addPrototype("<< rec->className()<<")\n";
RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec);
if (pitr==_recordProtoList.end())
{
_recordProtoList.push_back(rec);
}
else
{
osg::notify(osg::INFO) << " failed - flt::Registry::addPrototype() - prototype already exists"<<")\n";
}
rec->ref();
int op = rec->classOpcode();
_recordProtoMap[op] = rec;
}
void Registry::removePrototype(Record* rec)
Record* Registry::getPrototype(const int opcode)
{
if (rec==0L) return;
RecordProtoMap::iterator itr = _recordProtoMap.find(opcode);
if (itr != _recordProtoMap.end())
return (*itr).second.get();
osg::notify(osg::INFO) << "flt::Registry::removePrototype("<<rec->className()<<")\n";
return NULL;
RecordProtoList::iterator pitr = std::find(_recordProtoList.begin(),_recordProtoList.end(),rec);
if (pitr!=_recordProtoList.end())
{
_recordProtoList.erase(pitr);
}
}
Registry::RecordProtoList::iterator Registry::getRecordProtoItr(const int opcode)
{
for(RecordProtoList::iterator itr=_recordProtoList.begin();
itr!=_recordProtoList.end();
++itr)
{
if ((*itr)->classOpcode() == opcode)
return itr;
}
return _recordProtoList.end();
}
Record* Registry::getRecordProto(const int opcode)
{
RecordProtoList::iterator itr = getRecordProtoItr(opcode);
if (itr==_recordProtoList.end())
return NULL;
return itr->get();
}
///////////////////////////////////////////////////////////////////
void Registry::addTexture(osg::Texture* texture)
void Registry::addTexture(const std::string& name, osg::Texture* texture)
{
if (texture==0L) return;
osg::notify(osg::INFO) << "flt::Registry::addTexture("<< texture->className()<<")\n";
TextureList::iterator pitr = std::find(_textureList.begin(),_textureList.end(),texture);
if (pitr==_textureList.end())
_textureList.push_back(texture);
else
osg::notify(osg::INFO) << "failed - flt::Registry::addTexture() - texture already exists"<<")\n";
}
void Registry::removeTexture(osg::Texture* texture)
{
if (texture==0L) return;
osg::notify(osg::INFO) << "flt::Registry::removeTexture("<< texture->className()<<")\n";
TextureList::iterator itr = std::find(_textureList.begin(),_textureList.end(),texture);
if (itr!=_textureList.end())
{
_textureList.erase(itr);
}
}
Registry::TextureList::iterator Registry::getTextureItr(const std::string name)
{
for(TextureList::iterator itr=_textureList.begin();
itr!=_textureList.end();
++itr)
{
osg::Image* image = (*itr)->getImage();
if (image && name == image->getFileName())
return itr;
}
return _textureList.end();
if (texture == NULL) return;
_textureMap[name] = texture;
}
osg::Texture* Registry::getTexture(const std::string name)
{
TextureList::iterator itr = getTextureItr(name);
if (itr==_textureList.end())
return NULL;
TextureMap::iterator itr = _textureMap.find(name);
if (itr != _textureMap.end())
return (*itr).second.get();
return *itr;
return NULL;
}
void Registry::addFltFile(const std::string& name, FltFile* file)
{
if (file == NULL) return;
_fltFileMap[name] = file;
}
@@ -166,12 +83,7 @@ FltFile* Registry::getFltFile(const std::string& name)
FltFileMap::iterator itr = _fltFileMap.find(name);
if (itr != _fltFileMap.end())
return (*itr).second.get();
else
return NULL;
}
void Registry::addFltFile(const std::string& name, FltFile* file)
{
_fltFileMap[name] = file;
return NULL;
}

View File

@@ -40,38 +40,38 @@ class Registry
{
public:
~Registry();
~Registry() {}
static Registry* instance();
void addPrototype(Record* rec);
void removePrototype(Record* rec);
Record* getRecordProto(const int opcode);
Record* getPrototype(const int opcode);
void addTexture(osg::Texture* texture);
void removeTexture(osg::Texture* texture);
void addTexture(const std::string& name, osg::Texture* texture);
osg::Texture* getTexture(const std::string name);
void addFltFile(const std::string& name, FltFile* file);
FltFile* getFltFile(const std::string& name);
inline void setVersion(int ver) { _fltFileVersion = ver; }
inline int getVersion() const { return _fltFileVersion; }
private:
typedef std::vector<osg::ref_ptr<Record> > RecordProtoList;
typedef std::vector<osg::Texture*> TextureList;
typedef std::map<std::string,osg::ref_ptr<FltFile> > FltFileMap;
typedef std::map<int, osg::ref_ptr<Record> > RecordProtoMap;
typedef std::map<std::string, osg::ref_ptr<osg::Texture> > TextureMap;
typedef std::map<std::string, osg::ref_ptr<FltFile> > FltFileMap;
/** constructor is private, as its a singleton, preventing
construction other than via the instance() method and
therefore ensuring only one copy is ever constructed*/
Registry();
Registry() {}
RecordProtoList::iterator getRecordProtoItr(const int opcode);
TextureList::iterator getTextureItr(const std::string name);
RecordProtoMap _recordProtoMap;
TextureMap _textureMap;
FltFileMap _fltFileMap;
int _fltFileVersion;
RecordProtoList _recordProtoList;
TextureList _textureList;
FltFileMap _fltFileMap;
};
@@ -81,22 +81,22 @@ template<class T>
class RegisterRecordProxy
{
public:
RegisterRecordProxy()
{
_obj = new T;
_obj->ref();
Registry::instance()->addPrototype(_obj);
}
~RegisterRecordProxy()
{
//commented out to prevent seg fault under Linux
//due to the registry being previously destructed.
//Registry::instance()->removePrototype(_obj);
_obj->unref();
if (Registry::instance())
{
_obj = new T;
Registry::instance()->addPrototype(_obj.get());
}
}
~RegisterRecordProxy() {}
protected:
T* _obj;
osg::ref_ptr<T> _obj;
};
@@ -104,3 +104,4 @@ class RegisterRecordProxy
}; // end namespace flt
#endif // __FLT_REGISTRY_H

View File

@@ -33,7 +33,7 @@ class SwitchRecord : public PrimNodeRecord
virtual Record* clone() const { return new SwitchRecord(); }
virtual const char* className() const { return "SwitchRecord"; }
virtual int classOpcode() const { return SWITCH_OP; }
virtual int sizeofData() const { return sizeof(SSwitch); }
virtual size_t sizeofData() const { return sizeof(SSwitch); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -174,7 +174,7 @@ class TextureMappingPaletteRecord : public AncillaryRecord
virtual Record* clone() const { return new TextureMappingPaletteRecord(); }
virtual const char* className() const { return "TextureMappingPaletteRecord"; }
virtual int classOpcode() const { return TEXTURE_MAPPING_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(STextureMapping); }
virtual size_t sizeofData() const { return sizeof(STextureMapping); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -31,7 +31,7 @@ class TexturePaletteRecord : public AncillaryRecord
virtual Record* clone() const { return new TexturePaletteRecord(); }
virtual const char* className() const { return "TexturePaletteRecord"; }
virtual int classOpcode() const { return TEXTURE_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(STexturePalette); }
virtual size_t sizeofData() const { return sizeof(STexturePalette); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -34,7 +34,7 @@ class MatrixRecord : public AncillaryRecord
virtual Record* clone() const { return new MatrixRecord(); }
virtual const char* className() const { return "MatrixRecord"; }
virtual int classOpcode() const { return MATRIX_OP; }
virtual int sizeofData() const { return sizeof(SMatrix); }
virtual size_t sizeofData() const { return sizeof(SMatrix); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -71,7 +71,7 @@ class RotatAboutEdgeRecord : public AncillaryRecord
virtual Record* clone() const { return new RotatAboutEdgeRecord(); }
virtual const char* className() const { return "RotatAboutEdgeRecord"; }
virtual int classOpcode() const { return ROTATE_ABOUT_EDGE_OP; }
virtual int sizeofData() const { return sizeof(SRotatAboutEdge); }
virtual size_t sizeofData() const { return sizeof(SRotatAboutEdge); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -108,7 +108,7 @@ class TranslateRecord : public AncillaryRecord
virtual Record* clone() const { return new TranslateRecord(); }
virtual const char* className() const { return "TranslateRecord"; }
virtual int classOpcode() const { return TRANSLATE_OP; }
virtual int sizeofData() const { return sizeof(STranslate); }
virtual size_t sizeofData() const { return sizeof(STranslate); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -144,7 +144,7 @@ class OldTranslateRecord : public AncillaryRecord
virtual Record* clone() const { return new OldTranslateRecord(); }
virtual const char* className() const { return "OldTranslateRecord"; }
virtual int classOpcode() const { return OLD_TRANSLATE_OP; }
virtual int sizeofData() const { return sizeof(SOldTranslate); }
virtual size_t sizeofData() const { return sizeof(SOldTranslate); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -178,7 +178,7 @@ class ScaleRecord : public AncillaryRecord
virtual Record* clone() const { return new ScaleRecord(); }
virtual const char* className() const { return "ScaleRecord"; }
virtual int classOpcode() const { return SCALE_OP; }
virtual int sizeofData() const { return sizeof(SScale); }
virtual size_t sizeofData() const { return sizeof(SScale); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -211,7 +211,7 @@ class RotatAboutPointRecord : public AncillaryRecord
virtual Record* clone() const { return new RotatAboutPointRecord(); }
virtual const char* className() const { return "RotatAboutPointRecord"; }
virtual int classOpcode() const { return ROTATE_ABOUT_POINT_OP; }
virtual int sizeofData() const { return sizeof(SRotatAboutPoint); }
virtual size_t sizeofData() const { return sizeof(SRotatAboutPoint); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -244,7 +244,7 @@ class RotatScaleToPointRecord : public AncillaryRecord
virtual Record* clone() const { return new RotatScaleToPointRecord(); }
virtual const char* className() const { return "RotatScaleToPointRecord"; }
virtual int classOpcode() const { return ROTATE_SCALE_TO_POINT_OP; }
virtual int sizeofData() const { return sizeof(SRotatScaleToPoint); }
virtual size_t sizeofData() const { return sizeof(SRotatScaleToPoint); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -284,7 +284,7 @@ class PutTransformRecord : public AncillaryRecord
virtual Record* clone() const { return new PutTransformRecord(); }
virtual const char* className() const { return "PutTransformRecord"; }
virtual int classOpcode() const { return PUT_TRANSFORM_OP; }
virtual int sizeofData() const { return sizeof(SPutTransform); }
virtual size_t sizeofData() const { return sizeof(SPutTransform); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
@@ -318,7 +318,7 @@ class GeneralMatrixRecord : public AncillaryRecord
virtual Record* clone() const { return new GeneralMatrixRecord(); }
virtual const char* className() const { return "GeneralMatrixRecord"; }
virtual int classOpcode() const { return GENERAL_MATRIX_OP; }
virtual int sizeofData() const { return sizeof(SGeneralMatrix); }
virtual size_t sizeofData() const { return sizeof(SGeneralMatrix); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);

View File

@@ -45,7 +45,7 @@ class VertexPaletteRecord : public AncillaryRecord
virtual Record* clone() const { return new VertexPaletteRecord(); }
virtual const char* className() const { return "VertexPaletteRecord"; }
virtual int classOpcode() const { return VERTEX_PALETTE_OP; }
virtual int sizeofData() const { return sizeof(SVertexTableHeader); }
virtual size_t sizeofData() const { return sizeof(SVertexTableHeader); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
friend ostream& operator << (ostream& output, const VertexPaletteRecord& rec);
@@ -86,7 +86,7 @@ class VertexRecord : public AncillaryRecord
virtual Record* clone() const { return new VertexRecord(); }
virtual const char* className() const { return "VertexRecord"; }
virtual int classOpcode() const { return VERTEX_C_OP; }
virtual int sizeofData() const { return sizeof(SVertex); }
virtual size_t sizeofData() const { return sizeof(SVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SVertex* getData() const { return (SVertex*)_pData; }
@@ -130,7 +130,7 @@ class NormalVertexRecord : public AncillaryRecord
virtual Record* clone() const { return new NormalVertexRecord(); }
virtual const char* className() const { return "NormalVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CN_OP; }
virtual int sizeofData() const { return sizeof(SNormalVertex); }
virtual size_t sizeofData() const { return sizeof(SNormalVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SNormalVertex* getData() const { return (SNormalVertex*)_pData; }
@@ -173,7 +173,7 @@ class TextureVertexRecord : public AncillaryRecord
virtual Record* clone() const { return new TextureVertexRecord(); }
virtual const char* className() const { return "TextureVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CT_OP; }
virtual int sizeofData() const { return sizeof(STextureVertex); }
virtual size_t sizeofData() const { return sizeof(STextureVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual STextureVertex* getData() const { return (STextureVertex*)_pData; }
@@ -217,7 +217,7 @@ class NormalTextureVertexRecord : public AncillaryRecord
virtual Record* clone() const { return new NormalTextureVertexRecord(); }
virtual const char* className() const { return "NormalTextureVertexRecord"; }
virtual int classOpcode() const { return VERTEX_CNT_OP; }
virtual int sizeofData() const { return sizeof(SNormalTextureVertex); }
virtual size_t sizeofData() const { return sizeof(SNormalTextureVertex); }
virtual void accept(RecordVisitor& rv) { rv.apply(*this); }
// virtual void traverse(RecordVisitor& rv);
virtual SNormalTextureVertex* getData() const { return (SNormalTextureVertex*)_pData; }

View File

@@ -173,7 +173,7 @@ struct SRecHeader
uint16 _wLength; // total length of record
inline int opcode() { return (int)_wOpcode; }
inline int length() { return (int)_wLength; }
inline size_t length() { return (size_t)_wLength; }
void endian() {
ENDIAN( _wOpcode );
ENDIAN( _wLength );

View File

@@ -9,6 +9,10 @@
#include <osg/Switch>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osg/StateSet>
#include <osg/CullFace>
#include <osg/TexEnv>
#include <osg/Point>
#include <osg/Material>
#include <osg/PolygonOffset>
#include <osg/Vec3>
@@ -27,6 +31,7 @@
#include "flt.h"
#include "flt2osg.h"
#include "FltFile.h"
#include "Registry.h"
#include "Record.h"
#include "HeaderRecord.h"
#include "ColorPaletteRecord.h"
@@ -145,7 +150,7 @@ osg::Node* ConvertFromFLT::visitAncillary(osg::Group* osgParent, PrimNodeRecord*
osg::Node* ConvertFromFLT::visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec)
{
osg::Node* node = NULL;
GeoSetBuilder geoSetBuilder(_pFltFile);
GeoSetBuilder geoSetBuilder(_pFltFile.get());
// Visit
for(int i=0; i < rec->getNumChildren(); i++)
@@ -215,31 +220,36 @@ osg::Node* ConvertFromFLT::visitHeader(osg::Group* osgParent, HeaderRecord* rec)
/*osgParent*/
osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* rec)
{
ColorPool* pColorPool = _pFltFile->getColorPool();
if (pColorPool == NULL)
{
_pFltFile->useLocalColorPool();
pColorPool = _pFltFile->getColorPool();
}
if (!_pFltFile->useColorPalette()) return NULL;
if (rec->getSize() > sizeof(SOldColorPalette))
ColorPool* pColorPool = _pFltFile->getColorPool();
if (_diOpenFlightVersion > 13)
{
SColorPalette* pCol = (SColorPalette*)rec->getData();
for (int i=0; i < 1024; i++)
pColorPool->addColor(i, pCol->Colors[i].get());
{
osg::Vec4 color(pCol->Colors[i].get());
color[3] = 1.0f; // Force alpha to one
pColorPool->addColor(i, color);
}
}
else // version 11, 12 & 13
{
SOldColorPalette* pSColor = (SOldColorPalette*)rec->getData();
SOldColorPalette* pCol = (SOldColorPalette*)rec->getData();
unsigned int i;
for (i=0; i < sizeof(pSColor->Colors)/sizeof(pSColor->Colors[0]); i++)
for (i=0; i < sizeof(pCol->Colors)/sizeof(pCol->Colors[0]); i++)
{
pColorPool->addColor(i, pSColor->Colors[i].get());
osg::Vec4 color(pCol->Colors[i].get());
color[3] = 1.0f; // Force alpha to one
pColorPool->addColor(i, color);
}
for (i=0; i < sizeof(pSColor->FixedColors)/sizeof(pSColor->FixedColors[0]); i++)
for (i=0; i < sizeof(pCol->FixedColors)/sizeof(pCol->FixedColors[0]); i++)
{
pColorPool->addColor(i+4096, pSColor->FixedColors[i].get());
osg::Vec4 color(pCol->FixedColors[i].get());
color[3] = 1.0f; // Force alpha to one
pColorPool->addColor(i+4096, color);
}
}
@@ -250,12 +260,13 @@ osg::Node* ConvertFromFLT::visitColorPalette(osg::Group* , ColorPaletteRecord* r
/*osgParent*/
osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRecord* rec)
{
if (!_pFltFile->useMaterialPalette()) return NULL;
SMaterial* pSMaterial = (SMaterial*)rec->getData();
MaterialPool* pMaterialPool = _pFltFile->getMaterialPool();
if (pSMaterial && pMaterialPool )
if (pSMaterial && pMaterialPool)
{
PoolMaterial* pPoolMat = new PoolMaterial;
MaterialPool::PoolMaterial* pPoolMat = new MaterialPool::PoolMaterial;
pPoolMat->Ambient = pSMaterial->Ambient;
pPoolMat->Diffuse = pSMaterial->Diffuse;
@@ -272,6 +283,8 @@ osg::Node* ConvertFromFLT::visitMaterialPalette(osg::Group* , MaterialPaletteRec
/*osgParent*/
osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPaletteRecord* rec)
{
if (!_pFltFile->useMaterialPalette()) return NULL;
SOldMaterial* pSMaterial = (SOldMaterial*)rec->getData();
MaterialPool* pMaterialPool = _pFltFile->getMaterialPool();
@@ -279,7 +292,7 @@ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPale
{
for (int i=0; i < 64; i++)
{
PoolMaterial* pPoolMat = new PoolMaterial;
MaterialPool::PoolMaterial* pPoolMat = new MaterialPool::PoolMaterial;
pPoolMat->Ambient = pSMaterial->mat[i].Ambient;
pPoolMat->Diffuse = pSMaterial->mat[i].Diffuse;
@@ -297,24 +310,39 @@ osg::Node* ConvertFromFLT::visitOldMaterialPalette(osg::Group* , OldMaterialPale
/*osgParent*/
osg::Node* ConvertFromFLT::visitTexturePalette(osg::Group* , TexturePaletteRecord* rec)
{
STexturePalette* pTexture = (STexturePalette*)rec->getData();
if (!_pFltFile->useTexturePalette()) return NULL;
if (pTexture)
STexturePalette* pTexture = (STexturePalette*)rec->getData();
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (pTexture && pTexturePool)
{
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(pTexture->szFilename);
if (image.valid())
osg::Texture *osgTexture;
osgTexture = Registry::instance()->getTexture(pTexture->szFilename);
if (osgTexture == NULL)
{
osg::Texture *osgTexture = new osg::Texture;
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (osgTexture && pTexturePool)
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(pTexture->szFilename);
if (image.valid())
{
osgTexture = new osg::Texture;
osgTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
osgTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
osgTexture->setImage(image.get());
pTexturePool->addTexture((int)pTexture->diIndex, osgTexture);
// set up trilinear filtering.
osgTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR);
osgTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
// Add new texture to registry
Registry::instance()->addTexture(pTexture->szFilename, osgTexture);
}
}
if (osgTexture)
pTexturePool->addTexture((int)pTexture->diIndex, osgTexture);
}
return NULL;
}
@@ -485,6 +513,7 @@ osg::Node* ConvertFromFLT::visitSwitch(osg::Group* osgParent, SwitchRecord* rec)
osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec)
{
osg::Group* group = new osg::Group;
if (group)
{
osg::Node* node = visitAncillary(osgParent, rec);
@@ -505,6 +534,8 @@ osg::Node* ConvertFromFLT::visitObject(osg::Group* osgParent, ObjectRecord* rec)
void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
{
osg::GeoSet* geoSet = pBuilder->getGeoSet();
osg::StateSet* stateSet = geoSet->getStateSet();
SFace *pSFace = (SFace*)rec->getData();
osg::Vec4 color(1,1,1,1);
@@ -513,16 +544,25 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
switch(drawMode)
{
case FaceRecord::SOLID_BACKFACED:
pBuilder->setCullface(true);
// Enable backface culling
{
osg::CullFace* cullface = new osg::CullFace;
cullface->setMode(osg::CullFace::BACK);
stateSet->setAttributeAndModes(cullface, osg::StateAttribute::ON);
}
break;
case FaceRecord::SOLID_NO_BACKFACE:
pBuilder->setCullface(false);
// Disable backface culling
stateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
break;
case FaceRecord::WIREFRAME_NOT_CLOSED:
pBuilder->setPrimType(osg::GeoSet::LINE_STRIP);
geoSet->setPrimType(osg::GeoSet::LINE_STRIP);
break;
case FaceRecord::WIREFRAME_CLOSED:
pBuilder->setPrimType(osg::GeoSet::LINE_LOOP);
geoSet->setPrimType(osg::GeoSet::LINE_LOOP);
break;
}
/*
@@ -540,24 +580,48 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
}
*/
// Lighting
// Lighting and color binding
if (_diOpenFlightVersion > 13)
{
switch(pSFace->swLightMode)
{
case FaceRecord::FACE_COLOR:
case FaceRecord::VERTEX_COLOR:
pBuilder->setLighting(false);
// Use face color, not illuminated
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL );
break;
case FaceRecord::VERTEX_COLOR:
// Use vertex colors, not illuminated
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
break;
case FaceRecord::FACE_COLOR_LIGHTING:
// Use face color and vertex normal
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL );
geoSet->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
break;
case FaceRecord::VERTEX_COLOR_LIGHTING:
pBuilder->setLighting(true);
// Use vertex color and vertex normal
stateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
geoSet->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
break;
}
}
// Color
else // Version 11, 12 & 13
{
geoSet->setColorBinding( osg::GeoSet::BIND_OVERALL );
}
// Face Color
{
float alpha = 1.0f;
ColorPool* pColorPool = _pFltFile->getColorPool();
if (_diOpenFlightVersion > 13)
@@ -577,29 +641,10 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f;
color[3] = alpha;
if (alpha < 1.0f)
pBuilder->setTransparency(true);
pBuilder->setFaceColor(color);
switch(pSFace->swLightMode)
{
case FaceRecord::FACE_COLOR:
case FaceRecord::FACE_COLOR_LIGHTING:
pBuilder->setColorBinding(osg::GeoSet::BIND_OVERALL);
break;
case FaceRecord::VERTEX_COLOR:
case FaceRecord::VERTEX_COLOR_LIGHTING:
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
break;
}
}
}
else // Version 11, 12 & 13
{
float alpha;
bool bPackedColor = _bHdrRgbMode || (pColorPool == NULL);
if (bPackedColor)
@@ -609,20 +654,24 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
alpha = 1.0f - (float)pSFace->wTransparency / 65535.0f;
color[3] = alpha;
if (alpha < 1.0f)
pBuilder->setTransparency(true);
pBuilder->setColorBinding(osg::GeoSet::BIND_OVERALL);
pBuilder->setFaceColor(color);
}
// Transparency
if (alpha < 1.0f)
{
stateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
if (geoSet->getColorBinding() == osg::GeoSet::BIND_OVERALL)
geoSet->setColors( new osg::Vec4(color) );
}
// Material
MaterialPool* pMaterialPool = _pFltFile->getMaterialPool();
if (pMaterialPool)
{
PoolMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial);
MaterialPool::PoolMaterial* pSMaterial = pMaterialPool->getMaterial((int)pSFace->iMaterial);
if (pSMaterial)
{
@@ -656,6 +705,7 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
emissiv[2] = pSMaterial->Emissive[2];
emissiv[3] = alpha;
// osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
osgMaterial->setAmbient(osg::Material::FRONT_AND_BACK, ambient);
osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
osgMaterial->setSpecular(osg::Material::FRONT_AND_BACK, specular);
@@ -664,128 +714,146 @@ void ConvertFromFLT::visitFace(GeoSetBuilder* pBuilder, FaceRecord* rec)
osgMaterial->setShininess(osg::Material::FRONT_AND_BACK, pSMaterial->sfShininess/128.0f);
if (alpha < 1.0f)
pBuilder->setTransparency(true);
switch (pSFace->swLightMode)
{
case FaceRecord::VERTEX_COLOR:
case FaceRecord::VERTEX_COLOR_LIGHTING:
osgMaterial->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
break;
default:
osgMaterial->setColorMode(osg::Material::OFF);
stateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
pBuilder->setMaterial(osgMaterial);
stateSet->setAttribute(osgMaterial);
}
}
// Subface
if (rec->getParent()->isOfType(FACE_OP))
{
pBuilder->setSubface(_nSubfaceLevel);
if (_nSubfaceLevel > 0)
{
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
if (polyoffset)
{
polyoffset->setFactor(-1.0f*_nSubfaceLevel);
polyoffset->setUnits(-20.0f*_nSubfaceLevel);
stateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON);
}
}
}
// Texture
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (pTexturePool)
if (pSFace->iTexturePattern != -1)
{
osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern);
if (osgTexture)
TexturePool* pTexturePool = _pFltFile->getTexturePool();
if (pTexturePool)
{
osg::Image* image = osgTexture->getImage();
if (image)
osg::Texture* osgTexture = pTexturePool->getTexture((int)pSFace->iTexturePattern);
if (osgTexture)
{
switch (image->pixelFormat())
osg::Image* image = osgTexture->getImage();
if (image)
{
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
pBuilder->setTransparency(true);
break;
switch (image->pixelFormat())
{
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
stateSet->setMode(GL_BLEND,osg::StateAttribute::ON);
stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
break;
}
}
geoSet->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
// TODO: Crrect when .attr loader implemented
osg::TexEnv* osgTexEnv = new osg::TexEnv;
osgTexEnv->setMode(osg::TexEnv::MODULATE);
stateSet->setAttribute( osgTexEnv );
stateSet->setAttributeAndModes( osgTexture, osg::StateAttribute::ON );
}
pBuilder->setTexture(osgTexture);
}
}
// Visit vertices
int i;
for(i=0; i < rec->getNumChildren(); i++)
if (_diOpenFlightVersion > 13)
{
Record* child = rec->getChild(i);
if (child)
int i;
for(i=0; i < rec->getNumChildren(); i++)
{
int op = child->getOpcode();
switch (op)
Record* child = rec->getChild(i);
if (child == NULL) break;
switch (child->getOpcode())
{
case VERTEX_LIST_OP:
visitVertexList(pBuilder, (VertexListRecord*)child);
break;
case OLD_VERTEX_OP:
pBuilder->addVertex(child);
break;
case OLD_VERTEX_COLOR_OP:
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(child);
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(child);
pBuilder->setLighting(true);
break;
}
}
}
// Add primitive to GeoSet and prepare for next.
pBuilder->addPrimitive();
// Look for subfaces
_nSubfaceLevel++;
for(i=0; i < rec->getNumChildren(); i++)
{
Record* child = rec->getChild(i);
if (child && child->isOfType(FACE_OP))
visitFace(pBuilder, (FaceRecord*)child);
}
_nSubfaceLevel--;
}
void ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec)
{
int vertices = rec->numberOfVertices();
// Add vertices to GeoSetBuilder
if (pBuilder->getPrimType() == osg::GeoSet::POINTS)
{
for (int i=0; i < vertices; i++)
{
Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i));
if (vertex)
{
pBuilder->setPrimType(osg::GeoSet::POINTS);
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(vertex);
pBuilder->addPrimitive();
case VERTEX_LIST_OP:
pBuilder->addPrimLen(
visitVertexList(pBuilder, (VertexListRecord*)child));
break;
}
}
}
else
{
for (int i=0; i < vertices; i++)
int i;
int vertices=0;
for(i=0; i < rec->getNumChildren(); i++)
{
Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i));
if (vertex)
pBuilder->addVertex(vertex);
Record* child = rec->getChild(i);
if (child == NULL) break;
switch (child->getOpcode())
{
case OLD_VERTEX_OP:
pBuilder->addVertex(child);
vertices++;
break;
case OLD_VERTEX_COLOR_OP:
geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
pBuilder->addVertex(child);
vertices++;
break;
case OLD_VERTEX_COLOR_NORMAL_OP:
geoSet->setColorBinding( osg::GeoSet::BIND_PERVERTEX );
pBuilder->addVertex(child);
vertices++;
break;
}
}
pBuilder->addPrimLen(vertices);
}
// Add primitives to GeoSet and prepare for next.
pBuilder->addPrimitive();
// Look for subfaces
{
int n;
_nSubfaceLevel++;
for(n=0; n<rec->getNumChildren(); n++)
{
Record* child = rec->getChild(n);
if (child && child->isOfType(FACE_OP))
visitFace(pBuilder, (FaceRecord*)child);
}
_nSubfaceLevel--;
}
}
int ConvertFromFLT::visitVertexList(GeoSetBuilder* pBuilder, VertexListRecord* rec)
{
osg::GeoSet* geoSet = pBuilder->getGeoSet();
int vertices = rec->numberOfVertices();
// Add vertices to GeoSetBuilder
for (int i=0; i < vertices; i++)
{
Record* vertex = getVertexFromPool(rec->getVertexPoolOffset(i));
if (vertex)
pBuilder->addVertex(vertex);
}
return vertices;
}
@@ -815,8 +883,7 @@ osg::Node* ConvertFromFLT::visitMatrix(osg::Group* osgParent, MatrixRecord* rec)
osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord* rec)
{
// SExternalReference *pSExternal = (SExternalReference*)rec->getData();
// SExternalReference *pSExternal = (SExternalReference*)rec->getData();
if (osgParent)
{
osg::Node* node = visitAncillary(osgParent, rec);
@@ -840,7 +907,23 @@ osg::Node* ConvertFromFLT::visitExternal(osg::Group* osgParent, ExternalRecord*
void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec)
{
// SLightPoint *pSLightPoint = (SLightPoint*)rec->getData();
osg::GeoSet* geoSet = pBuilder->getGeoSet();
osg::StateSet* stateSet = geoSet->getStateSet();
SLightPoint *pSLightPoint = (SLightPoint*)rec->getData();
geoSet->setPrimType(osg::GeoSet::POINTS);
geoSet->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
osg::Point* point = new osg::Point;
if (point)
{
point->setSize( pSLightPoint->sfSize );
stateSet->setAttributeAndModes( point, osg::StateAttribute::ON );
// point->setFadeThresholdSize(const float fadeThresholdSize);
// point->setDistanceAttenuation(const Vec3& distanceAttenuation);
// point->setStateSetModes(*stateSet,const GLModeValue value); // GL_POINT_SMOOTH
}
// Visit vertices
for(int i=0; i < rec->getNumChildren(); i++)
@@ -853,22 +936,22 @@ void ConvertFromFLT::visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord*
switch (op)
{
case VERTEX_LIST_OP:
pBuilder->setPrimType(osg::GeoSet::POINTS);
visitVertexList(pBuilder, (VertexListRecord*)child);
{
int vertices = visitVertexList(pBuilder, (VertexListRecord*)child);
for (int v=0; v<vertices; v++)
pBuilder->addPrimLen(1);
}
break;
case OLD_VERTEX_OP:
pBuilder->addVertex(child);
pBuilder->addPrimitive();
break;
case OLD_VERTEX_COLOR_OP:
case OLD_VERTEX_COLOR_NORMAL_OP:
pBuilder->setColorBinding(osg::GeoSet::BIND_PERVERTEX);
pBuilder->addVertex(child);
pBuilder->addPrimitive();
pBuilder->addPrimLen(1);
break;
}
}
}
pBuilder->addPrimitive();
}

View File

@@ -3,13 +3,15 @@
#ifndef __FLT_2_OSG_H
#define __FLT_2_OSG_H
#include <map>
#include <vector>
#include <string>
#include <osg/ref_ptr>
#include <osg/Vec4>
#include "Record.h"
#include "FltFile.h"
#include <map>
#include <vector>
#include <string>
namespace osg {
@@ -51,66 +53,64 @@ class VertexListRecord;
class LongIDRecord;
class GeoSetBuilder;
class FltFile;
struct SMaterial;
class ConvertFromFLT
{
public:
public:
ConvertFromFLT(FltFile* pFltFile);
virtual ~ConvertFromFLT();
ConvertFromFLT(FltFile* pFltFile);
virtual ~ConvertFromFLT();
osg::Node* convert(Record* rec);
osg::Node* convert(Record* rec);
osg::Node* visitNode(osg::Group* osgParent,Record* rec);
osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitNode(osg::Group* osgParent,Record* rec);
osg::Node* visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitPrimaryNode(osg::Group* osgParent, PrimNodeRecord* rec);
osg::Node* visitLongID(osg::Group* osgParent, LongIDRecord* rec);
osg::Node* visitLongID(osg::Group* osgParent, LongIDRecord* rec);
osg::Node* visitHeader(osg::Group* osgParent, HeaderRecord* rec);
osg::Node* visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec);
osg::Node* visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec);
osg::Node* visitOldMaterialPalette(osg::Group* osgParent, OldMaterialPaletteRecord* rec);
osg::Node* visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec);
osg::Node* visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec);
osg::Node* visitVertex(osg::Group* osgParent, VertexRecord* rec);
osg::Node* visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec);
osg::Node* visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec);
osg::Node* visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec);
osg::Node* visitGroup(osg::Group* osgParent, GroupRecord* rec);
osg::Node* visitLOD(osg::Group* osgParent, LodRecord* rec);
osg::Node* visitOldLOD(osg::Group* osgParent, OldLodRecord* rec);
osg::Node* visitDOF(osg::Group* osgParent, DofRecord* rec);
osg::Node* visitSwitch(osg::Group* osgParent, SwitchRecord* rec);
osg::Node* visitObject(osg::Group* osgParent, ObjectRecord* rec);
osg::Node* visitMatrix(osg::Group* osgParent, MatrixRecord* rec);
osg::Node* visitExternal(osg::Group* osgParent, ExternalRecord* rec);
osg::Node* visitHeader(osg::Group* osgParent, HeaderRecord* rec);
osg::Node* visitColorPalette(osg::Group* osgParent, ColorPaletteRecord* rec);
osg::Node* visitMaterialPalette(osg::Group* osgParent, MaterialPaletteRecord* rec);
osg::Node* visitOldMaterialPalette(osg::Group* osgParent, OldMaterialPaletteRecord* rec);
osg::Node* visitTexturePalette(osg::Group* osgParent, TexturePaletteRecord* rec);
osg::Node* visitVertexPalette(osg::Group* osgParent, VertexPaletteRecord* rec);
osg::Node* visitVertex(osg::Group* osgParent, VertexRecord* rec);
osg::Node* visitNormalVertex(osg::Group* osgParent, NormalVertexRecord* rec);
osg::Node* visitTextureVertex(osg::Group* osgParent, TextureVertexRecord* rec);
osg::Node* visitNormalTextureVertex(osg::Group* osgParent, NormalTextureVertexRecord* rec);
osg::Node* visitGroup(osg::Group* osgParent, GroupRecord* rec);
osg::Node* visitLOD(osg::Group* osgParent, LodRecord* rec);
osg::Node* visitOldLOD(osg::Group* osgParent, OldLodRecord* rec);
osg::Node* visitDOF(osg::Group* osgParent, DofRecord* rec);
osg::Node* visitSwitch(osg::Group* osgParent, SwitchRecord* rec);
osg::Node* visitObject(osg::Group* osgParent, ObjectRecord* rec);
osg::Node* visitMatrix(osg::Group* osgParent, MatrixRecord* rec);
osg::Node* visitExternal(osg::Group* osgParent, ExternalRecord* rec);
void visitFace(GeoSetBuilder* pParent, FaceRecord* rec);
void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec);
void visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec);
void visitFace(GeoSetBuilder* pParent, FaceRecord* rec);
void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec);
int visitVertexList(GeoSetBuilder* pParent, VertexListRecord* rec);
private:
private:
Record* getVertexFromPool(int nOffset);
void regisiterVertex(int nOffset, Record* pRec);
Record* getVertexFromPool(int nOffset);
void regisiterVertex(int nOffset, Record* pRec);
typedef std::map<int,Record*> VertexPaletteOffsetMap;
VertexPaletteOffsetMap _VertexPaletteOffsetMap;
typedef std::map<int,Record*> VertexPaletteOffsetMap;
VertexPaletteOffsetMap _VertexPaletteOffsetMap;
FltFile* _pFltFile;
int _diOpenFlightVersion;
int _diCurrentOffset;
unsigned short _wObjTransparency;
int _nSubfaceLevel;
float _sfHdrUnitScale; // iMultDivUnit
bool _bHdrRgbMode;
osg::ref_ptr<FltFile> _pFltFile;
int _diOpenFlightVersion;
int _diCurrentOffset;
unsigned short _wObjTransparency;
int _nSubfaceLevel;
float _sfHdrUnitScale; // iMultDivUnit
bool _bHdrRgbMode;
};