Cleanup RecordPtrT

This moves the index resolution into a separate post method instead of always
checking when access. As a result, it reduces the size of it down to the size
of a pointer, as opposed to 2 pointers + 1 int. The appropriate methods are
added to the various node types to make sure they're resolved.
actorid
Chris Robinson 13 years ago
parent efb95e2f83
commit 046e9686f9

@ -25,6 +25,7 @@
#define _NIF_CONTROLLED_H_ #define _NIF_CONTROLLED_H_
#include "extra.hpp" #include "extra.hpp"
#include "controller.hpp"
namespace Nif namespace Nif
{ {
@ -40,6 +41,12 @@ public:
Extra::read(nif); Extra::read(nif);
controller.read(nif); controller.read(nif);
} }
void post(NIFFile *nif)
{
Extra::post(nif);
controller.post(nif);
}
}; };
/// Has name, extra-data and controller /// Has name, extra-data and controller
@ -78,6 +85,12 @@ public:
Controlled::read(nif); Controlled::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controlled::post(nif);
data.post(nif);
}
}; };
class NiGravity : public Controlled class NiGravity : public Controlled

@ -53,6 +53,13 @@ public:
target.read(nif); target.read(nif);
} }
void post(NIFFile *nif)
{
Record::post(nif);
next.post(nif);
target.post(nif);
}
}; };
class NiBSPArrayController : public Controller class NiBSPArrayController : public Controller
@ -80,6 +87,12 @@ public:
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiPathController : public Controller class NiPathController : public Controller
@ -101,6 +114,14 @@ public:
posData.read(nif); posData.read(nif);
floatData.read(nif); floatData.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
posData.post(nif);
floatData.post(nif);
}
}; };
class NiUVController : public Controller class NiUVController : public Controller
@ -115,6 +136,12 @@ public:
nif->getShort(); // always 0 nif->getShort(); // always 0
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiKeyframeController : public Controller class NiKeyframeController : public Controller
@ -127,6 +154,12 @@ public:
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiAlphaController : public Controller class NiAlphaController : public Controller
@ -139,6 +172,12 @@ public:
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiGeomMorpherController : public Controller class NiGeomMorpherController : public Controller
@ -152,6 +191,12 @@ public:
data.read(nif); data.read(nif);
nif->getByte(); // always 0 nif->getByte(); // always 0
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
class NiVisController : public Controller class NiVisController : public Controller
@ -164,6 +209,12 @@ public:
Controller::read(nif); Controller::read(nif);
data.read(nif); data.read(nif);
} }
void post(NIFFile *nif)
{
Controller::post(nif);
data.post(nif);
}
}; };
} // Namespace } // Namespace

@ -34,7 +34,6 @@ namespace Nif
class NiSourceTexture : public Named class NiSourceTexture : public Named
{ {
public: public:
// Is this an external (references a separate texture file) or // Is this an external (references a separate texture file) or
// internal (data is inside the nif itself) texture? // internal (data is inside the nif itself) texture?
bool external; bool external;
@ -70,8 +69,8 @@ public:
Named::read(nif); Named::read(nif);
external = !!nif->getByte(); external = !!nif->getByte();
if(external)
if(external) filename = nif->getString(); filename = nif->getString();
else else
{ {
nif->getByte(); // always 1 nif->getByte(); // always 1
@ -84,6 +83,12 @@ public:
nif->getByte(); // always 1 nif->getByte(); // always 1
} }
void post(NIFFile *nif)
{
Named::post(nif);
data.post(nif);
}
}; };
// Common ancestor for several data classes // Common ancestor for several data classes
@ -173,9 +178,11 @@ public:
nif->getShort(); // Number of valid entries in the following arrays ? nif->getShort(); // Number of valid entries in the following arrays ?
if(nif->getInt()) if(nif->getInt())
{
// Particle sizes // Particle sizes
nif->getFloatLen(activeCount); nif->getFloatLen(activeCount);
} }
}
}; };
class NiRotatingParticlesData : public NiAutoNormalParticlesData class NiRotatingParticlesData : public NiAutoNormalParticlesData
@ -186,11 +193,13 @@ public:
NiAutoNormalParticlesData::read(nif); NiAutoNormalParticlesData::read(nif);
if(nif->getInt()) if(nif->getInt())
{
// Rotation quaternions. I THINK activeCount is correct here, // Rotation quaternions. I THINK activeCount is correct here,
// but verts (vertex number) might also be correct, if there is // but verts (vertex number) might also be correct, if there is
// any case where the two don't match. // any case where the two don't match.
nif->getArrayLen<Vector4>(activeCount); nif->getArrayLen<Vector4>(activeCount);
} }
}
}; };
class NiPosData : public Record class NiPosData : public Record
@ -228,11 +237,9 @@ public:
// also used in FloatData and KeyframeData. We could probably // also used in FloatData and KeyframeData. We could probably
// reuse and refactor a lot of this if we actually use it at some // reuse and refactor a lot of this if we actually use it at some
// point. // point.
for(int i=0; i<2; i++) for(int i=0; i<2; i++)
{ {
int count = nif->getInt(); int count = nif->getInt();
if(count) if(count)
{ {
nif->getInt(); // always 2 nif->getInt(); // always 2
@ -345,9 +352,6 @@ public:
data.read(nif); data.read(nif);
root.read(nif); root.read(nif);
bones.read(nif); bones.read(nif);
if(data.empty() || root.empty())
nif->fail("NiSkinInstance missing root or data");
} }
void post(NIFFile *nif); void post(NIFFile *nif);
@ -415,7 +419,6 @@ public:
nif->getInt(); // -1 nif->getInt(); // -1
bones.resize(boneNum); bones.resize(boneNum);
for(int i=0;i<boneNum;i++) for(int i=0;i<boneNum;i++)
{ {
BoneInfo &bi = bones[i]; BoneInfo &bi = bones[i];
@ -439,33 +442,25 @@ class NiMorphData : public Record
std::vector<std::vector<Ogre::Vector3> > relevantData; std::vector<std::vector<Ogre::Vector3> > relevantData;
std::vector<std::vector<Ogre::Vector3> > additionalVertices; std::vector<std::vector<Ogre::Vector3> > additionalVertices;
public: public:
float getStartTime(){ float getStartTime() const
return startTime; { return startTime; }
} float getStopTime() const
float getStopTime(){ { return stopTime; }
return stopTime;
} void setStartTime(float time)
void setStartTime(float time){ { startTime = time; }
startTime = time; void setStopTime(float time)
} { stopTime = time; }
void setStopTime(float time){ const std::vector<Ogre::Vector3>& getInitialVertices() const
stopTime = time; { return initialVertices; }
} const std::vector<std::vector<Ogre::Vector3> >& getRelevantData() const
std::vector<Ogre::Vector3> getInitialVertices(){ { return relevantData; }
return initialVertices; const std::vector<std::vector<float> >& getRelevantTimes() const
} { return relevantTimes; }
std::vector<std::vector<Ogre::Vector3> > getRelevantData(){ const std::vector<std::vector<Ogre::Vector3> >& getAdditionalVertices() const
return relevantData; { return additionalVertices; }
}
std::vector<std::vector<float> > getRelevantTimes(){
return relevantTimes;
}
std::vector<std::vector<Ogre::Vector3> > getAdditionalVertices(){
return additionalVertices;
}
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
@ -474,8 +469,9 @@ void read(NIFFile *nif)
nif->getByte(); nif->getByte();
int magic = nif->getInt(); int magic = nif->getInt();
/*int type =*/ nif->getInt(); /*int type =*/ nif->getInt();
for(int i = 0; i < vertCount; i++){
for(int i = 0; i < vertCount; i++)
{
float x = nif->getFloat(); float x = nif->getFloat();
float y = nif->getFloat(); float y = nif->getFloat();
float z = nif->getFloat(); float z = nif->getFloat();
@ -488,7 +484,8 @@ void read(NIFFile *nif)
/*type =*/ nif->getInt(); /*type =*/ nif->getInt();
std::vector<Ogre::Vector3> current; std::vector<Ogre::Vector3> current;
std::vector<float> currentTime; std::vector<float> currentTime;
for(int i = 0; i < magic; i++){ for(int i = 0; i < magic; i++)
{
// Time, data, forward, backward tangents // Time, data, forward, backward tangents
float time = nif->getFloat(); float time = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
@ -498,12 +495,16 @@ void read(NIFFile *nif)
currentTime.push_back(time); currentTime.push_back(time);
//nif->getFloatLen(4*magic); //nif->getFloatLen(4*magic);
} }
if(magic){
if(magic)
{
relevantData.push_back(current); relevantData.push_back(current);
relevantTimes.push_back(currentTime); relevantTimes.push_back(currentTime);
} }
std::vector<Ogre::Vector3> verts; std::vector<Ogre::Vector3> verts;
for(int i = 0; i < vertCount; i++){ for(int i = 0; i < vertCount; i++)
{
float x = nif->getFloat(); float x = nif->getFloat();
float y = nif->getFloat(); float y = nif->getFloat();
float z = nif->getFloat(); float z = nif->getFloat();
@ -535,7 +536,6 @@ class NiKeyframeData : public Record
int ttype; int ttype;
//Scalings //Scalings
std::vector<float> scalefactor; std::vector<float> scalefactor;
std::vector<float> scaletime; std::vector<float> scaletime;
std::vector<float> forwards; std::vector<float> forwards;
@ -543,10 +543,8 @@ class NiKeyframeData : public Record
std::vector<Ogre::Vector3> tbcscale; std::vector<Ogre::Vector3> tbcscale;
int stype; int stype;
public: public:
void clone(NiKeyframeData c) void clone(const NiKeyframeData &c)
{ {
quats = c.getQuat(); quats = c.getQuat();
tbc = c.getrTbc(); tbc = c.getrTbc();
@ -565,22 +563,15 @@ public:
transtime = c.gettTime(); transtime = c.gettTime();
bonename = c.getBonename(); bonename = c.getBonename();
} }
void setBonename(std::string bone) void setBonename(std::string bone)
{ { bonename = bone; }
bonename = bone;
}
void setStartTime(float start) void setStartTime(float start)
{ { startTime = start; }
startTime = start;
}
void setStopTime(float end) void setStopTime(float end)
{ { stopTime = end; }
stopTime = end;
}
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
// Rotations first // Rotations first
@ -589,7 +580,6 @@ public:
//std::vector<float> rottime(count); //std::vector<float> rottime(count);
if(count) if(count)
{ {
//TYPE1 LINEAR_KEY //TYPE1 LINEAR_KEY
//TYPE2 QUADRATIC_KEY //TYPE2 QUADRATIC_KEY
//TYPE3 TBC_KEY //TYPE3 TBC_KEY
@ -602,7 +592,8 @@ public:
{ {
//We need to actually read in these values instead of skipping them //We need to actually read in these values instead of skipping them
//nif->skip(count*4*5); // time + quaternion //nif->skip(count*4*5); // time + quaternion
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
{
float time = nif->getFloat(); float time = nif->getFloat();
float w = nif->getFloat(); float w = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
@ -616,8 +607,10 @@ public:
} }
} }
else if(rtype == 3) else if(rtype == 3)
{ //Example - node 116 in base_anim.nif {
for (int i = 0; i < count; i++) { //Example - node 116 in base_anim.nif
for (int i = 0; i < count; i++)
{
float time = nif->getFloat(); float time = nif->getFloat();
float w = nif->getFloat(); float w = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
@ -627,6 +620,7 @@ public:
float tbcx = nif->getFloat(); float tbcx = nif->getFloat();
float tbcy = nif->getFloat(); float tbcy = nif->getFloat();
float tbcz = nif->getFloat(); float tbcz = nif->getFloat();
Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
quats.push_back(quat); quats.push_back(quat);
@ -635,8 +629,6 @@ public:
//if(time == 0.0 || time > 355.5) //if(time == 0.0 || time > 355.5)
// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n"; // std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
} }
//nif->skip(count*4*8); // rot1 + tension+bias+continuity
} }
else if(rtype == 4) else if(rtype == 4)
{ {
@ -651,28 +643,32 @@ public:
nif->skip(cnt*4*2); // time + unknown nif->skip(cnt*4*2); // time + unknown
else if(type == 2) else if(type == 2)
nif->skip(cnt*4*4); // time + unknown vector nif->skip(cnt*4*4); // time + unknown vector
else nif->fail("Unknown sub-rotation type"); else
nif->fail("Unknown sub-rotation type");
} }
} }
} }
else nif->fail("Unknown rotation type in NiKeyframeData"); else
nif->fail("Unknown rotation type in NiKeyframeData");
} }
//first = false; //first = false;
// Then translation // Then translation
count = nif->getInt(); count = nif->getInt();
if(count) if(count)
{ {
ttype = nif->getInt(); ttype = nif->getInt();
//std::cout << "TransCount:" << count << " Type: " << type << "\n"; //std::cout << "TransCount:" << count << " Type: " << type << "\n";
if(ttype == 1) { if(ttype == 1)
for (int i = 0; i < count; i++) { {
for(int i = 0; i < count; i++)
{
float time = nif->getFloat(); float time = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
float y = nif->getFloat(); float y = nif->getFloat();
float z = nif->getFloat(); float z = nif->getFloat();
Ogre::Vector3 trans = Ogre::Vector3(x, y, z); Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
translist1.push_back(trans); translist1.push_back(trans);
transtime.push_back(time); transtime.push_back(time);
@ -680,8 +676,10 @@ public:
//nif->getFloatLen(count*4); // time + translation //nif->getFloatLen(count*4); // time + translation
} }
else if(ttype == 2) else if(ttype == 2)
{ //Example - node 116 in base_anim.nif {
for (int i = 0; i < count; i++) { //Example - node 116 in base_anim.nif
for(int i = 0; i < count; i++)
{
float time = nif->getFloat(); float time = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
float y = nif->getFloat(); float y = nif->getFloat();
@ -692,6 +690,7 @@ public:
float x3 = nif->getFloat(); float x3 = nif->getFloat();
float y3 = nif->getFloat(); float y3 = nif->getFloat();
float z3 = nif->getFloat(); float z3 = nif->getFloat();
Ogre::Vector3 trans = Ogre::Vector3(x, y, z); Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2); Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2);
Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3); Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3);
@ -703,8 +702,10 @@ public:
//nif->getFloatLen(count*10); // trans1 + forward + backward //nif->getFloatLen(count*10); // trans1 + forward + backward
} }
else if(ttype == 3){ else if(ttype == 3)
for (int i = 0; i < count; i++) { {
for(int i = 0; i < count; i++)
{
float time = nif->getFloat(); float time = nif->getFloat();
float x = nif->getFloat(); float x = nif->getFloat();
float y = nif->getFloat(); float y = nif->getFloat();
@ -729,10 +730,8 @@ public:
{ {
stype = nif->getInt(); stype = nif->getInt();
for(int i = 0; i < count; i++)
for(int i = 0; i < count; i++){ {
//int size = 0; //int size = 0;
if(stype >= 1 && stype < 4) if(stype >= 1 && stype < 4)
{ {
@ -742,86 +741,70 @@ public:
scalefactor.push_back(scale); scalefactor.push_back(scale);
//size = 2; // time+scale //size = 2; // time+scale
} }
else nif->fail("Unknown scaling type"); else
if(stype == 2){ nif->fail("Unknown scaling type");
if(stype == 2)
{
//size = 4; // 1 + forward + backward (floats) //size = 4; // 1 + forward + backward (floats)
float forward = nif->getFloat(); float forward = nif->getFloat();
float backward = nif->getFloat(); float backward = nif->getFloat();
forwards.push_back(forward); forwards.push_back(forward);
backwards.push_back(backward); backwards.push_back(backward);
} }
else if(stype == 3){ else if(stype == 3)
{
//size = 5; // 1 + tbc
float tbcx = nif->getFloat(); float tbcx = nif->getFloat();
float tbcy = nif->getFloat(); float tbcy = nif->getFloat();
float tbcz = nif->getFloat(); float tbcz = nif->getFloat();
Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
tbcscale.push_back(vec); tbcscale.push_back(vec);
//size = 5; // 1 + tbc
} }
} }
} }
else else
stype = 0; stype = 0;
} }
int getRtype(){
return rtype;
}
int getStype(){
return stype;
}
int getTtype(){
return ttype;
}
float getStartTime(){
return startTime;
}
float getStopTime(){
return stopTime;
}
std::vector<Ogre::Quaternion> getQuat(){
return quats;
}
std::vector<Ogre::Vector3> getrTbc(){
return tbc;
}
std::vector<float> getrTime(){
return rottime;
}
std::vector<Ogre::Vector3> getTranslist1(){
return translist1;
}
std::vector<Ogre::Vector3> getTranslist2(){
return translist2;
}
std::vector<Ogre::Vector3> getTranslist3(){
return translist3;
}
std::vector<float> gettTime(){
return transtime;
}
std::vector<float> getScalefactor(){
return scalefactor;
}
std::vector<float> getForwards(){
return forwards;
}
std::vector<float> getBackwards(){
return backwards;
}
std::vector<Ogre::Vector3> getScaleTbc(){
return tbcscale;
}
std::vector<float> getsTime(){
return scaletime;
}
std::string getBonename(){ return bonename;
}
int getRtype() const
{ return rtype; }
int getStype() const
{ return stype; }
int getTtype() const
{ return ttype; }
float getStartTime() const
{ return startTime; }
float getStopTime() const
{ return stopTime; }
const std::vector<Ogre::Quaternion>& getQuat() const
{ return quats; }
const std::vector<Ogre::Vector3>& getrTbc() const
{ return tbc; }
const std::vector<float>& getrTime() const
{ return rottime; }
const std::vector<Ogre::Vector3>& getTranslist1() const
{ return translist1; }
const std::vector<Ogre::Vector3>& getTranslist2() const
{ return translist2; }
const std::vector<Ogre::Vector3>& getTranslist3() const
{ return translist3; }
const std::vector<float>& gettTime() const
{ return transtime; }
const std::vector<float>& getScalefactor() const
{ return scalefactor; }
const std::vector<float>& getForwards() const
{ return forwards; }
const std::vector<float>& getBackwards() const
{ return backwards; }
const std::vector<Ogre::Vector3>& getScaleTbc() const
{ return tbcscale; }
const std::vector<float>& getsTime() const
{ return scaletime; }
const std::string& getBonename() const
{ return bonename; }
}; };
} // Namespace } // Namespace

@ -42,7 +42,6 @@ struct NiLight : Effect
Vector diffuse; Vector diffuse;
Vector specular; Vector specular;
}; };
const SLight *light; const SLight *light;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -86,6 +85,12 @@ struct NiTextureEffect : Effect
*/ */
nif->skip(23); nif->skip(23);
} }
void post(NIFFile *nif)
{
Effect::post(nif);
texture.post(nif);
}
}; };
} // Namespace } // Namespace

@ -41,6 +41,7 @@ public:
ExtraPtr extra; ExtraPtr extra;
void read(NIFFile *nif) { extra.read(nif); } void read(NIFFile *nif) { extra.read(nif); }
void post(NIFFile *nif) { extra.post(nif); }
}; };
class NiVertWeightsExtraData : public Extra class NiVertWeightsExtraData : public Extra
@ -67,7 +68,6 @@ public:
float time; float time;
Misc::SString text; Misc::SString text;
}; };
std::vector<TextKey> list; std::vector<TextKey> list;
void read(NIFFile *nif) void read(NIFFile *nif)

@ -190,8 +190,15 @@ void NIFFile::parse()
void NiSkinInstance::post(NIFFile *nif) void NiSkinInstance::post(NIFFile *nif)
{ {
int bnum = bones.length(); data.post(nif);
if(bnum != static_cast<int> (data->bones.size())) root.post(nif);
bones.post(nif);
if(data.empty() || root.empty())
nif->fail("NiSkinInstance missing root or data");
size_t bnum = bones.length();
if(bnum != data->bones.size())
nif->fail("Mismatch in NiSkinData bone count"); nif->fail("Mismatch in NiSkinData bone count");
root->makeRootBone(data->trafo); root->makeRootBone(data->trafo);
@ -200,7 +207,6 @@ void NiSkinInstance::post(NIFFile *nif)
{ {
if(!bones.has(i)) if(!bones.has(i))
nif->fail("Oops: Missing bone! Don't know how to handle this."); nif->fail("Oops: Missing bone! Don't know how to handle this.");
bones[i].makeBone(i, data->bones[i]); bones[i].makeBone(i, data->bones[i]);
} }
} }

@ -43,8 +43,7 @@ namespace Nif
class NIFFile class NIFFile
{ {
enum NIFVersion enum NIFVersion {
{
VER_MW = 0x04000002 // Morrowind NIFs VER_MW = 0x04000002 // Morrowind NIFs
}; };
@ -95,16 +94,13 @@ class NIFFile
~NIFFile() ~NIFFile()
{ {
for(std::size_t i=0; i<records.size(); i++) for(std::size_t i=0; i<records.size(); i++)
{
delete records[i]; delete records[i];
} }
}
/// Get a given record /// Get a given record
Record *getRecord(int index) Record *getRecord(size_t index)
{ {
assert(index >= 0 && index < static_cast<int> (records.size())); Record *res = records.at(index);
Record *res = records[index];
assert(res != NULL); assert(res != NULL);
return res; return res;
} }
@ -113,9 +109,7 @@ class NIFFile
int numRecords() { return records.size(); } int numRecords() { return records.size(); }
/************************************************* /*************************************************
Parser functions Parser functions
****************************************************/ ****************************************************/
void skip(size_t size) { inp->getPtr(size); } void skip(size_t size) { inp->getPtr(size); }

@ -26,6 +26,7 @@
#include "controlled.hpp" #include "controlled.hpp"
#include "data.hpp" #include "data.hpp"
#include "property.hpp"
namespace Nif namespace Nif
{ {
@ -69,6 +70,12 @@ public:
boneIndex = -1; boneIndex = -1;
} }
void post(NIFFile *nif)
{
Named::post(nif);
props.post(nif);
}
// Bone transformation. If set, node is a part of a skeleton. // Bone transformation. If set, node is a part of a skeleton.
const NiSkinData::BoneTrafo *boneTrafo; const NiSkinData::BoneTrafo *boneTrafo;
@ -113,7 +120,6 @@ struct NiNode : Node
NodeList effects; NodeList effects;
/* Known NiNode flags: /* Known NiNode flags:
0x01 hidden 0x01 hidden
0x02 use mesh for collision 0x02 use mesh for collision
0x04 use bounding box for collision (?) 0x04 use bounding box for collision (?)
@ -127,6 +133,13 @@ struct NiNode : Node
children.read(nif); children.read(nif);
effects.read(nif); effects.read(nif);
} }
void post(NIFFile *nif)
{
Node::post(nif);
children.post(nif);
effects.post(nif);
}
}; };
struct NiTriShape : Node struct NiTriShape : Node
@ -148,7 +161,15 @@ struct NiTriShape : Node
skin.read(nif); skin.read(nif);
} }
NiTriShapeCopy clone(){ void post(NIFFile *nif)
{
Node::post(nif);
data.post(nif);
skin.post(nif);
}
NiTriShapeCopy clone()
{
NiTriShapeCopy copy; NiTriShapeCopy copy;
copy.sname = name.toString(); copy.sname = name.toString();
float *ptr = (float*)data->vertices.ptr; float *ptr = (float*)data->vertices.ptr;
@ -159,13 +180,13 @@ struct NiTriShape : Node
float *current = (float*) (ptr + i * 3); float *current = (float*) (ptr + i * 3);
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2))); copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
if(ptrNormals){ if(ptrNormals)
{
float *currentNormals = (float*) (ptrNormals + i * 3); float *currentNormals = (float*) (ptrNormals + i * 3);
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2))); copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
} }
} }
return copy; return copy;
} }
}; };
@ -183,7 +204,6 @@ struct NiCamera : Node
// Level of detail modifier // Level of detail modifier
float LOD; float LOD;
}; };
const Camera *cam; const Camera *cam;
void read(NIFFile *nif) void read(NIFFile *nif)
@ -207,6 +227,12 @@ struct NiAutoNormalParticles : Node
data.read(nif); data.read(nif);
nif->getInt(); // -1 nif->getInt(); // -1
} }
void post(NIFFile *nif)
{
Node::post(nif);
data.post(nif);
}
}; };
struct NiRotatingParticles : Node struct NiRotatingParticles : Node
@ -219,9 +245,13 @@ struct NiRotatingParticles : Node
data.read(nif); data.read(nif);
nif->getInt(); // -1 nif->getInt(); // -1
} }
};
void post(NIFFile *nif)
{
Node::post(nif);
data.post(nif);
}
};
} // Namespace } // Namespace
#endif #endif

@ -82,6 +82,11 @@ public:
// short. // short.
nif->skip(6); nif->skip(6);
} }
void post(NIFFile *nif)
{
texture.post(nif);
}
}; };
/* Apply mode: /* Apply mode:
@ -130,6 +135,13 @@ public:
} }
textures[6].read(nif); // Decal textures[6].read(nif); // Decal
} }
void post(NIFFile *nif)
{
Property::post(nif);
for(int i = 0;i < 7;i++)
textures[i].post(nif);
}
}; };
// These contain no other data than the 'flags' field in Property // These contain no other data than the 'flags' field in Property
@ -140,15 +152,15 @@ typedef Property NiSpecularProperty;
typedef Property NiWireframeProperty; typedef Property NiWireframeProperty;
// The rest are all struct-based // The rest are all struct-based
template <typename Struct> template <typename T>
struct StructPropT : Property struct StructPropT : Property
{ {
const Struct* data; const T* data;
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
Property::read(nif); Property::read(nif);
data = nif->getPtr<Struct>(); data = nif->getPtr<T>();
} }
}; };

@ -104,7 +104,6 @@ struct Record
/* /*
Use these later if you want custom allocation of all NIF objects Use these later if you want custom allocation of all NIF objects
static void* operator new(size_t size); static void* operator new(size_t size);
static void operator delete(void *p); static void operator delete(void *p);
*/ */

@ -37,61 +37,51 @@ namespace Nif
template <class X> template <class X>
class RecordPtrT class RecordPtrT
{ {
int index; union {
intptr_t index;
X* ptr; X* ptr;
NIFFile *nif; };
public: public:
RecordPtrT() : index(-2) {}
RecordPtrT() : index(-2), ptr(NULL) {}
/// Read the index from the nif /// Read the index from the nif
void read(NIFFile *_nif) void read(NIFFile *nif)
{ {
// Can only read the index once // Can only read the index once
assert(index == -2); assert(index == -2);
// Store the NIFFile pointer for later // Store the index for later
nif = _nif;
// And the index, of course
index = nif->getInt(); index = nif->getInt();
} }
/** Set the pointer explicitly. May be used when you are pointing to /// Resolve index to pointer
records in another file, eg. when you have a .nif / .kf pair. void post(NIFFile *nif)
*/
void set(X *p)
{
ptr = p;
index = -1;
}
/// Look up the actual object from the index
X* getPtr()
{ {
// Have we found the pointer already? if(index < 0)
if(ptr == NULL) ptr = NULL;
else
{ {
// Get the record
assert(index >= 0);
Record *r = nif->getRecord(index); Record *r = nif->getRecord(index);
// And cast it // And cast it
ptr = dynamic_cast<X*>(r); ptr = dynamic_cast<X*>(r);
assert(ptr != NULL); assert(ptr != NULL);
} }
}
/// Look up the actual object from the index
X* getPtr()
{
assert(ptr != NULL);
return ptr; return ptr;
} }
X& get() { return *getPtr(); }
/// Syntactic sugar /// Syntactic sugar
X* operator->() { return getPtr(); } X* operator->() { return getPtr(); }
X& get() { return *getPtr(); }
/// Pointers are allowed to be empty /// Pointers are allowed to be empty
bool empty() { return index == -1 && ptr == NULL; } bool empty() { return ptr == NULL; }
int getIndex() { return index; }
}; };
/** A list of references to other records. These are read as a list, /** A list of references to other records. These are read as a list,
@ -105,36 +95,34 @@ class RecordListT
std::vector<Ptr> list; std::vector<Ptr> list;
public: public:
void read(NIFFile *nif) void read(NIFFile *nif)
{ {
int len = nif->getInt(); int len = nif->getInt();
list.resize(len); list.resize(len);
assert(len >= 0 && len < 1000); for(size_t i=0;i < list.size();i++)
for(int i=0;i<len;i++)
list[i].read(nif); list[i].read(nif);
} }
X& operator[](int index) void post(NIFFile *nif)
{ {
assert(index >= 0 && index < static_cast<int> (list.size())); for(size_t i=0;i < list.size();i++)
return list[index].get(); list[i].post(nif);
} }
bool has(int index) X& operator[](size_t index)
{ {
assert(index >= 0 && index < static_cast<int> (list.size())); return list.at(index).get();
return !list[index].empty();
} }
int getIndex(int index) bool has(size_t index)
{ {
if(has(index)) return list[index].getIndex(); assert(index >= 0 && index < static_cast<int> (list.size()));
else return -1; return !list.at(index).empty();
} }
int length() { return list.size(); } int length()
{ return list.size(); }
}; };

Loading…
Cancel
Save