|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
#include "niffile.hpp"
|
|
|
|
|
#include "effect.hpp"
|
|
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
#include <OgreResourceGroupManager.h>
|
|
|
|
|
|
|
|
|
|
namespace Nif
|
|
|
|
@ -16,8 +18,10 @@ NIFFile::NIFFile(const std::string &name)
|
|
|
|
|
|
|
|
|
|
NIFFile::~NIFFile()
|
|
|
|
|
{
|
|
|
|
|
for(std::size_t i=0; i<records.size(); i++)
|
|
|
|
|
delete records[i];
|
|
|
|
|
for (std::vector<Record*>::iterator it = records.begin() ; it != records.end(); it++)
|
|
|
|
|
{
|
|
|
|
|
delete *it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename NodeType> static Record* construct() { return new NodeType; }
|
|
|
|
@ -26,100 +30,84 @@ struct RecordFactoryEntry {
|
|
|
|
|
|
|
|
|
|
typedef Record* (*create_t) ();
|
|
|
|
|
|
|
|
|
|
char const * mName;
|
|
|
|
|
create_t mCreate;
|
|
|
|
|
RecordType mType;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* These are all the record types we know how to read.
|
|
|
|
|
|
|
|
|
|
This can be heavily optimized later if needed. For example, a
|
|
|
|
|
hash table or a FSM-based parser could be used to look up
|
|
|
|
|
node names.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static const RecordFactoryEntry recordFactories [] = {
|
|
|
|
|
|
|
|
|
|
{ "NiNode", &construct <NiNode >, RC_NiNode },
|
|
|
|
|
{ "AvoidNode", &construct <NiNode >, RC_AvoidNode },
|
|
|
|
|
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
|
|
|
|
|
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
|
|
|
|
|
{ "NiBillboardNode", &construct <NiNode >, RC_NiBillboardNode },
|
|
|
|
|
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
|
|
|
|
|
{ "NiRotatingParticles", &construct <NiRotatingParticles >, RC_NiRotatingParticles },
|
|
|
|
|
{ "NiAutoNormalParticles", &construct <NiAutoNormalParticles >, RC_NiAutoNormalParticles },
|
|
|
|
|
{ "NiCamera", &construct <NiCamera >, RC_NiCamera },
|
|
|
|
|
{ "RootCollisionNode", &construct <NiNode >, RC_RootCollisionNode },
|
|
|
|
|
{ "NiTexturingProperty", &construct <NiTexturingProperty >, RC_NiTexturingProperty },
|
|
|
|
|
{ "NiMaterialProperty", &construct <NiMaterialProperty >, RC_NiMaterialProperty },
|
|
|
|
|
{ "NiZBufferProperty", &construct <NiZBufferProperty >, RC_NiZBufferProperty },
|
|
|
|
|
{ "NiAlphaProperty", &construct <NiAlphaProperty >, RC_NiAlphaProperty },
|
|
|
|
|
{ "NiVertexColorProperty", &construct <NiVertexColorProperty >, RC_NiVertexColorProperty },
|
|
|
|
|
{ "NiShadeProperty", &construct <NiShadeProperty >, RC_NiShadeProperty },
|
|
|
|
|
{ "NiDitherProperty", &construct <NiDitherProperty >, RC_NiDitherProperty },
|
|
|
|
|
{ "NiWireframeProperty", &construct <NiWireframeProperty >, RC_NiWireframeProperty },
|
|
|
|
|
{ "NiSpecularProperty", &construct <NiSpecularProperty >, RC_NiSpecularProperty },
|
|
|
|
|
{ "NiStencilProperty", &construct <NiStencilProperty >, RC_NiStencilProperty },
|
|
|
|
|
{ "NiVisController", &construct <NiVisController >, RC_NiVisController },
|
|
|
|
|
{ "NiGeomMorpherController", &construct <NiGeomMorpherController >, RC_NiGeomMorpherController },
|
|
|
|
|
{ "NiKeyframeController", &construct <NiKeyframeController >, RC_NiKeyframeController },
|
|
|
|
|
{ "NiAlphaController", &construct <NiAlphaController >, RC_NiAlphaController },
|
|
|
|
|
{ "NiUVController", &construct <NiUVController >, RC_NiUVController },
|
|
|
|
|
{ "NiPathController", &construct <NiPathController >, RC_NiPathController },
|
|
|
|
|
{ "NiMaterialColorController", &construct <NiMaterialColorController >, RC_NiMaterialColorController },
|
|
|
|
|
{ "NiBSPArrayController", &construct <NiBSPArrayController >, RC_NiBSPArrayController },
|
|
|
|
|
{ "NiParticleSystemController", &construct <NiParticleSystemController >, RC_NiParticleSystemController },
|
|
|
|
|
{ "NiFlipController", &construct <NiFlipController >, RC_NiFlipController },
|
|
|
|
|
{ "NiAmbientLight", &construct <NiLight >, RC_NiLight },
|
|
|
|
|
{ "NiDirectionalLight", &construct <NiLight >, RC_NiLight },
|
|
|
|
|
{ "NiTextureEffect", &construct <NiTextureEffect >, RC_NiTextureEffect },
|
|
|
|
|
{ "NiVertWeightsExtraData", &construct <NiVertWeightsExtraData >, RC_NiVertWeightsExtraData },
|
|
|
|
|
{ "NiTextKeyExtraData", &construct <NiTextKeyExtraData >, RC_NiTextKeyExtraData },
|
|
|
|
|
{ "NiStringExtraData", &construct <NiStringExtraData >, RC_NiStringExtraData },
|
|
|
|
|
{ "NiGravity", &construct <NiGravity >, RC_NiGravity },
|
|
|
|
|
{ "NiPlanarCollider", &construct <NiPlanarCollider >, RC_NiPlanarCollider },
|
|
|
|
|
{ "NiParticleGrowFade", &construct <NiParticleGrowFade >, RC_NiParticleGrowFade },
|
|
|
|
|
{ "NiParticleColorModifier", &construct <NiParticleColorModifier >, RC_NiParticleColorModifier },
|
|
|
|
|
{ "NiParticleRotation", &construct <NiParticleRotation >, RC_NiParticleRotation },
|
|
|
|
|
{ "NiFloatData", &construct <NiFloatData >, RC_NiFloatData },
|
|
|
|
|
{ "NiTriShapeData", &construct <NiTriShapeData >, RC_NiTriShapeData },
|
|
|
|
|
{ "NiVisData", &construct <NiVisData >, RC_NiVisData },
|
|
|
|
|
{ "NiColorData", &construct <NiColorData >, RC_NiColorData },
|
|
|
|
|
{ "NiPixelData", &construct <NiPixelData >, RC_NiPixelData },
|
|
|
|
|
{ "NiMorphData", &construct <NiMorphData >, RC_NiMorphData },
|
|
|
|
|
{ "NiKeyframeData", &construct <NiKeyframeData >, RC_NiKeyframeData },
|
|
|
|
|
{ "NiSkinData", &construct <NiSkinData >, RC_NiSkinData },
|
|
|
|
|
{ "NiUVData", &construct <NiUVData >, RC_NiUVData },
|
|
|
|
|
{ "NiPosData", &construct <NiPosData >, RC_NiPosData },
|
|
|
|
|
{ "NiRotatingParticlesData", &construct <NiRotatingParticlesData >, RC_NiRotatingParticlesData },
|
|
|
|
|
{ "NiAutoNormalParticlesData", &construct <NiAutoNormalParticlesData >, RC_NiAutoNormalParticlesData },
|
|
|
|
|
{ "NiSequenceStreamHelper", &construct <NiSequenceStreamHelper >, RC_NiSequenceStreamHelper },
|
|
|
|
|
{ "NiSourceTexture", &construct <NiSourceTexture >, RC_NiSourceTexture },
|
|
|
|
|
{ "NiSkinInstance", &construct <NiSkinInstance >, RC_NiSkinInstance },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static RecordFactoryEntry const * recordFactories_begin = &recordFactories [0];
|
|
|
|
|
static RecordFactoryEntry const * recordFactories_end = &recordFactories [sizeof (recordFactories) / sizeof (recordFactories[0])];
|
|
|
|
|
|
|
|
|
|
RecordFactoryEntry const * lookupRecordFactory (char const * name)
|
|
|
|
|
///Helper function for adding records to the factory map
|
|
|
|
|
static std::pair<std::string,RecordFactoryEntry> makeEntry(std::string recName, Record* (*create_t) (), RecordType type)
|
|
|
|
|
{
|
|
|
|
|
RecordFactoryEntry const * i;
|
|
|
|
|
|
|
|
|
|
for (i = recordFactories_begin; i != recordFactories_end; ++i)
|
|
|
|
|
if (strcmp (name, i->mName) == 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (i == recordFactories_end)
|
|
|
|
|
return NULL;
|
|
|
|
|
RecordFactoryEntry anEntry = {create_t,type};
|
|
|
|
|
return std::make_pair<std::string,RecordFactoryEntry>(recName, anEntry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return i;
|
|
|
|
|
///These are all the record types we know how to read.
|
|
|
|
|
static std::map<std::string,RecordFactoryEntry> makeFactory()
|
|
|
|
|
{
|
|
|
|
|
std::map<std::string,RecordFactoryEntry> newFactory;
|
|
|
|
|
newFactory.insert(makeEntry("NiNode", &construct <NiNode> , RC_NiNode ));
|
|
|
|
|
newFactory.insert(makeEntry("AvoidNode", &construct <NiNode> , RC_AvoidNode ));
|
|
|
|
|
newFactory.insert(makeEntry("NiBSParticleNode", &construct <NiNode> , RC_NiBSParticleNode ));
|
|
|
|
|
newFactory.insert(makeEntry("NiBSAnimationNode", &construct <NiNode> , RC_NiBSAnimationNode ));
|
|
|
|
|
newFactory.insert(makeEntry("NiBillboardNode", &construct <NiNode> , RC_NiBillboardNode ));
|
|
|
|
|
newFactory.insert(makeEntry("NiTriShape", &construct <NiTriShape> , RC_NiTriShape ));
|
|
|
|
|
newFactory.insert(makeEntry("NiRotatingParticles", &construct <NiRotatingParticles> , RC_NiRotatingParticles ));
|
|
|
|
|
newFactory.insert(makeEntry("NiAutoNormalParticles", &construct <NiAutoNormalParticles> , RC_NiAutoNormalParticles ));
|
|
|
|
|
newFactory.insert(makeEntry("NiCamera", &construct <NiCamera> , RC_NiCamera ));
|
|
|
|
|
newFactory.insert(makeEntry("RootCollisionNode", &construct <NiNode> , RC_RootCollisionNode ));
|
|
|
|
|
newFactory.insert(makeEntry("NiTexturingProperty", &construct <NiTexturingProperty> , RC_NiTexturingProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiMaterialProperty", &construct <NiMaterialProperty> , RC_NiMaterialProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiZBufferProperty", &construct <NiZBufferProperty> , RC_NiZBufferProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiAlphaProperty", &construct <NiAlphaProperty> , RC_NiAlphaProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiVertexColorProperty", &construct <NiVertexColorProperty> , RC_NiVertexColorProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiShadeProperty", &construct <NiShadeProperty> , RC_NiShadeProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiDitherProperty", &construct <NiDitherProperty> , RC_NiDitherProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiWireframeProperty", &construct <NiWireframeProperty> , RC_NiWireframeProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiSpecularProperty", &construct <NiSpecularProperty> , RC_NiSpecularProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiStencilProperty", &construct <NiStencilProperty> , RC_NiStencilProperty ));
|
|
|
|
|
newFactory.insert(makeEntry("NiVisController", &construct <NiVisController> , RC_NiVisController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiGeomMorpherController", &construct <NiGeomMorpherController> , RC_NiGeomMorpherController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiKeyframeController", &construct <NiKeyframeController> , RC_NiKeyframeController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiAlphaController", &construct <NiAlphaController> , RC_NiAlphaController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiUVController", &construct <NiUVController> , RC_NiUVController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiPathController", &construct <NiPathController> , RC_NiPathController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiMaterialColorController", &construct <NiMaterialColorController> , RC_NiMaterialColorController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiBSPArrayController", &construct <NiBSPArrayController> , RC_NiBSPArrayController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiParticleSystemController", &construct <NiParticleSystemController> , RC_NiParticleSystemController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiFlipController", &construct <NiFlipController> , RC_NiFlipController ));
|
|
|
|
|
newFactory.insert(makeEntry("NiAmbientLight", &construct <NiLight> , RC_NiLight ));
|
|
|
|
|
newFactory.insert(makeEntry("NiDirectionalLight", &construct <NiLight> , RC_NiLight ));
|
|
|
|
|
newFactory.insert(makeEntry("NiTextureEffect", &construct <NiTextureEffect> , RC_NiTextureEffect ));
|
|
|
|
|
newFactory.insert(makeEntry("NiVertWeightsExtraData", &construct <NiVertWeightsExtraData> , RC_NiVertWeightsExtraData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiTextKeyExtraData", &construct <NiTextKeyExtraData> , RC_NiTextKeyExtraData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiStringExtraData", &construct <NiStringExtraData> , RC_NiStringExtraData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiGravity", &construct <NiGravity> , RC_NiGravity ));
|
|
|
|
|
newFactory.insert(makeEntry("NiPlanarCollider", &construct <NiPlanarCollider> , RC_NiPlanarCollider ));
|
|
|
|
|
newFactory.insert(makeEntry("NiParticleGrowFade", &construct <NiParticleGrowFade> , RC_NiParticleGrowFade ));
|
|
|
|
|
newFactory.insert(makeEntry("NiParticleColorModifier", &construct <NiParticleColorModifier> , RC_NiParticleColorModifier ));
|
|
|
|
|
newFactory.insert(makeEntry("NiParticleRotation", &construct <NiParticleRotation> , RC_NiParticleRotation ));
|
|
|
|
|
newFactory.insert(makeEntry("NiFloatData", &construct <NiFloatData> , RC_NiFloatData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiTriShapeData", &construct <NiTriShapeData> , RC_NiTriShapeData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiVisData", &construct <NiVisData> , RC_NiVisData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiColorData", &construct <NiColorData> , RC_NiColorData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiPixelData", &construct <NiPixelData> , RC_NiPixelData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiMorphData", &construct <NiMorphData> , RC_NiMorphData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiKeyframeData", &construct <NiKeyframeData> , RC_NiKeyframeData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiSkinData", &construct <NiSkinData> , RC_NiSkinData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiUVData", &construct <NiUVData> , RC_NiUVData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiPosData", &construct <NiPosData> , RC_NiPosData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiRotatingParticlesData", &construct <NiRotatingParticlesData> , RC_NiRotatingParticlesData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiAutoNormalParticlesData", &construct <NiAutoNormalParticlesData> , RC_NiAutoNormalParticlesData ));
|
|
|
|
|
newFactory.insert(makeEntry("NiSequenceStreamHelper", &construct <NiSequenceStreamHelper> , RC_NiSequenceStreamHelper ));
|
|
|
|
|
newFactory.insert(makeEntry("NiSourceTexture", &construct <NiSourceTexture> , RC_NiSourceTexture ));
|
|
|
|
|
newFactory.insert(makeEntry("NiSkinInstance", &construct <NiSkinInstance> , RC_NiSkinInstance ));
|
|
|
|
|
return newFactory;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This file implements functions from the NIFFile class. It is also
|
|
|
|
|
where we stash all the functions we couldn't add as inline
|
|
|
|
|
definitions in the record types.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
///Make the factory map used for parsing the file
|
|
|
|
|
static const std::map<std::string,RecordFactoryEntry> factories = makeFactory();
|
|
|
|
|
|
|
|
|
|
void NIFFile::parse()
|
|
|
|
|
{
|
|
|
|
@ -156,12 +144,13 @@ void NIFFile::parse()
|
|
|
|
|
if(rec.empty())
|
|
|
|
|
fail("Record number " + Ogre::StringConverter::toString(i) + " out of " + Ogre::StringConverter::toString(recNum) + " is blank.");
|
|
|
|
|
|
|
|
|
|
RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ());
|
|
|
|
|
|
|
|
|
|
if (entry != NULL)
|
|
|
|
|
std::map<std::string,RecordFactoryEntry>::const_iterator entry = factories.find(rec);
|
|
|
|
|
|
|
|
|
|
if (entry != factories.end())
|
|
|
|
|
{
|
|
|
|
|
r = entry->mCreate ();
|
|
|
|
|
r->recType = entry->mType;
|
|
|
|
|
r = entry->second.mCreate ();
|
|
|
|
|
r->recType = entry->second.mType;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
fail("Unknown record type " + rec);
|
|
|
|
@ -177,10 +166,19 @@ void NIFFile::parse()
|
|
|
|
|
size_t rootNum = nif.getUInt();
|
|
|
|
|
roots.resize(rootNum);
|
|
|
|
|
|
|
|
|
|
//Determine which records are roots
|
|
|
|
|
for(size_t i = 0;i < rootNum;i++)
|
|
|
|
|
{
|
|
|
|
|
intptr_t idx = nif.getInt();
|
|
|
|
|
roots[i] = ((idx >= 0) ? records.at(idx) : NULL);
|
|
|
|
|
int idx = nif.getInt();
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
{
|
|
|
|
|
roots[i] = records.at(idx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
roots[i] = NULL;
|
|
|
|
|
warn("Null Root found");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Once parsing is done, do post-processing.
|
|
|
|
|