Added support for node instances to Open Flight loader. Submitted by Yefei He.
This commit is contained in:
@@ -62,6 +62,9 @@ FltFile::FltFile(
|
||||
_useInternalMaterialPalette = true;
|
||||
setMaterialPool( new MaterialPool );
|
||||
}
|
||||
|
||||
// instances are always internally defined
|
||||
setInstancePool( new InstancePool );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,10 +34,12 @@ class FltFile : public osg::Referenced
|
||||
ColorPool* getColorPool() { return _colorPool.get(); }
|
||||
TexturePool* getTexturePool() { return _texturePool.get(); }
|
||||
MaterialPool* getMaterialPool() { return _materialPool.get(); }
|
||||
InstancePool* getInstancePool() { return _instancePool.get(); }
|
||||
|
||||
void setColorPool(ColorPool* colorPool) { _colorPool = colorPool; }
|
||||
void setTexturePool(TexturePool* texturePool) { _texturePool = texturePool; }
|
||||
void setMaterialPool(MaterialPool* materialPool){ _materialPool = materialPool; }
|
||||
void setInstancePool(InstancePool* instancePool){ _instancePool = instancePool; }
|
||||
|
||||
inline const bool useInternalColorPalette() const { return _useInternalColorPalette; }
|
||||
inline const bool useInternalTexturePalette() const { return _useInternalTexturePalette; }
|
||||
@@ -66,6 +68,7 @@ class FltFile : public osg::Referenced
|
||||
osg::ref_ptr<ColorPool> _colorPool;
|
||||
osg::ref_ptr<TexturePool> _texturePool;
|
||||
osg::ref_ptr<MaterialPool> _materialPool;
|
||||
osg::ref_ptr<InstancePool> _instancePool;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ InstanceDefinitionRecord::~InstanceDefinitionRecord()
|
||||
|
||||
void InstanceDefinitionRecord::endian()
|
||||
{
|
||||
SInstanceDefinition *pSInstDef = (SInstanceDefinition*)getData();
|
||||
|
||||
ENDIAN( pSInstDef->iInstDefNumber );
|
||||
}
|
||||
|
||||
|
||||
@@ -51,4 +54,7 @@ InstanceReferenceRecord::~InstanceReferenceRecord()
|
||||
|
||||
void InstanceReferenceRecord::endian()
|
||||
{
|
||||
SInstanceReference *pSInstRef = (SInstanceReference*)getData();
|
||||
|
||||
ENDIAN( pSInstRef->iInstDefNumber );
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace flt {
|
||||
typedef struct InstanceDefinitionTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int16 iSpare;
|
||||
int16 iInstDefNumber;
|
||||
}SInstanceDefinition;
|
||||
|
||||
|
||||
@@ -55,6 +57,8 @@ class InstanceDefinitionRecord : public PrimNodeRecord
|
||||
typedef struct InstanceReferenceTag
|
||||
{
|
||||
SRecHeader RecHeader;
|
||||
int16 iSpare;
|
||||
int16 iInstDefNumber;
|
||||
}SInstanceReference;
|
||||
|
||||
|
||||
|
||||
@@ -96,4 +96,18 @@ void MaterialPool::addMaterial(int nIndex, PoolMaterial* material)
|
||||
_MaterialMap[nIndex] = material;
|
||||
}
|
||||
|
||||
osg::Group* InstancePool::getInstance(int nIndex)
|
||||
{
|
||||
InstanceMap::iterator fitr = _instanceMap.find(nIndex);
|
||||
if (fitr != _instanceMap.end())
|
||||
return (*fitr).second.get();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void InstancePool::addInstance(int nIndex, osg::Group* instance)
|
||||
{
|
||||
_instanceMap[nIndex] = instance;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <osg/Texture>
|
||||
#include <osg/Material>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/Group>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
@@ -103,6 +104,25 @@ class MaterialPool : public osg::Referenced
|
||||
};
|
||||
|
||||
|
||||
class InstancePool : public osg::Referenced
|
||||
{
|
||||
public :
|
||||
|
||||
InstancePool() {}
|
||||
|
||||
osg::Group* getInstance(int nIndex);
|
||||
void addInstance(int nIndex, osg::Group* instance);
|
||||
|
||||
protected :
|
||||
|
||||
virtual ~InstancePool() {}
|
||||
|
||||
private :
|
||||
|
||||
typedef std::map<int,osg::ref_ptr<osg::Group> > InstanceMap;
|
||||
InstanceMap _instanceMap;
|
||||
};
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "Input.h"
|
||||
#include "GeoSetBuilder.h"
|
||||
#include "LongIDRecord.h"
|
||||
#include "InstanceRecords.h"
|
||||
|
||||
|
||||
|
||||
@@ -127,6 +128,8 @@ osg::Node* ConvertFromFLT::visitNode(osg::Group* osgParent, Record* rec)
|
||||
else if (rec->isOfType(DOF_OP)) return visitDOF(osgParent, (DofRecord*)rec);
|
||||
else if (rec->isOfType(SWITCH_OP)) return visitSwitch(osgParent, (SwitchRecord*)rec);
|
||||
else if (rec->isOfType(OBJECT_OP)) return visitObject(osgParent, (ObjectRecord*)rec);
|
||||
else if (rec->isOfType(INSTANCE_REFERENCE_OP)) return visitInstanceReference(osgParent, (InstanceReferenceRecord*)rec);
|
||||
else if (rec->isOfType(INSTANCE_DEFINITION_OP)) return visitInstanceDefinition(osgParent, (InstanceDefinitionRecord*)rec);
|
||||
else if (rec->isOfType(EXTERNAL_REFERENCE_OP)) return visitExternal(osgParent, (ExternalRecord*)rec);
|
||||
else if (rec->isOfType(MATRIX_OP)) return visitMatrix(osgParent, (MatrixRecord*)rec);
|
||||
else if (rec->isOfType(LONG_ID_OP)) return visitLongID(osgParent, (LongIDRecord*)rec);
|
||||
@@ -134,6 +137,39 @@ osg::Node* ConvertFromFLT::visitNode(osg::Group* osgParent, Record* rec)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osg::Node* ConvertFromFLT::visitInstanceDefinition(osg::Group* osgParent,InstanceDefinitionRecord* rec)
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
InstancePool* pInstancePool = rec->getFltFile()->getInstancePool();
|
||||
|
||||
if (group)
|
||||
{
|
||||
osg::Node* node = visitAncillary(osgParent, rec);
|
||||
if (node) osgParent = (osg::Group*)node;
|
||||
|
||||
pInstancePool->addInstance((int)rec->getData()->iInstDefNumber,group);
|
||||
visitPrimaryNode(group, (PrimNodeRecord*)rec);
|
||||
}
|
||||
|
||||
return (osg::Node*)group;
|
||||
}
|
||||
|
||||
osg::Node* ConvertFromFLT::visitInstanceReference(osg::Group* osgParent,InstanceReferenceRecord* rec)
|
||||
{
|
||||
osg::Group* group;
|
||||
InstancePool* pInstancePool = rec->getFltFile()->getInstancePool();
|
||||
|
||||
group = pInstancePool->getInstance((int)rec->getData()->iInstDefNumber);
|
||||
if (group)
|
||||
{
|
||||
osgParent->addChild( group );
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::INFO) << "Warning: cannot find the instance definition in flt file."<<std::endl;
|
||||
}
|
||||
return (osg::Node*)group;
|
||||
}
|
||||
|
||||
osg::Node* ConvertFromFLT::visitAncillary(osg::Group* osgParent, PrimNodeRecord* rec)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,8 @@ class ExternalRecord;
|
||||
class LightPointRecord;
|
||||
class VertexListRecord;
|
||||
class LongIDRecord;
|
||||
class InstanceDefinitionRecord;
|
||||
class InstanceReferenceRecord;
|
||||
|
||||
//class GeoSetBuilder;
|
||||
|
||||
@@ -132,6 +134,8 @@ class ConvertFromFLT
|
||||
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* visitInstanceDefinition(osg::Group* osgParent,InstanceDefinitionRecord* rec);
|
||||
osg::Node* visitInstanceReference(osg::Group* osgParent,InstanceReferenceRecord* rec);
|
||||
|
||||
void visitFace(GeoSetBuilder* pParent, FaceRecord* rec);
|
||||
void visitLightPoint(GeoSetBuilder* pBuilder, LightPointRecord* rec);
|
||||
|
||||
Reference in New Issue
Block a user