mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-05 05:11:32 +00:00
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.
This commit is contained in:
parent
efb95e2f83
commit
046e9686f9
11 changed files with 1364 additions and 1283 deletions
|
@ -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){
|
|
||||||
startTime = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStopTime(float time){
|
void setStartTime(float time)
|
||||||
stopTime = time;
|
{ startTime = time; }
|
||||||
}
|
void setStopTime(float time)
|
||||||
std::vector<Ogre::Vector3> getInitialVertices(){
|
{ stopTime = time; }
|
||||||
return initialVertices;
|
|
||||||
}
|
const std::vector<Ogre::Vector3>& getInitialVertices() const
|
||||||
std::vector<std::vector<Ogre::Vector3> > getRelevantData(){
|
{ return initialVertices; }
|
||||||
return relevantData;
|
const std::vector<std::vector<Ogre::Vector3> >& getRelevantData() const
|
||||||
}
|
{ return relevantData; }
|
||||||
std::vector<std::vector<float> > getRelevantTimes(){
|
const std::vector<std::vector<float> >& getRelevantTimes() const
|
||||||
return relevantTimes;
|
{ return relevantTimes; }
|
||||||
}
|
const std::vector<std::vector<Ogre::Vector3> >& getAdditionalVertices() const
|
||||||
std::vector<std::vector<Ogre::Vector3> > getAdditionalVertices(){
|
{ return additionalVertices; }
|
||||||
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(){
|
int getRtype() const
|
||||||
return translist1;
|
{ return rtype; }
|
||||||
}
|
int getStype() const
|
||||||
std::vector<Ogre::Vector3> getTranslist2(){
|
{ return stype; }
|
||||||
return translist2;
|
int getTtype() const
|
||||||
}
|
{ return ttype; }
|
||||||
std::vector<Ogre::Vector3> getTranslist3(){
|
float getStartTime() const
|
||||||
return translist3;
|
{ return startTime; }
|
||||||
}
|
float getStopTime() const
|
||||||
std::vector<float> gettTime(){
|
{ return stopTime; }
|
||||||
return transtime;
|
const std::vector<Ogre::Quaternion>& getQuat() const
|
||||||
}
|
{ return quats; }
|
||||||
std::vector<float> getScalefactor(){
|
const std::vector<Ogre::Vector3>& getrTbc() const
|
||||||
return scalefactor;
|
{ return tbc; }
|
||||||
}
|
const std::vector<float>& getrTime() const
|
||||||
std::vector<float> getForwards(){
|
{ return rottime; }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
if(index < 0)
|
||||||
index = -1;
|
ptr = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Record *r = nif->getRecord(index);
|
||||||
|
// And cast it
|
||||||
|
ptr = dynamic_cast<X*>(r);
|
||||||
|
assert(ptr != NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look up the actual object from the index
|
/// Look up the actual object from the index
|
||||||
X* getPtr()
|
X* getPtr()
|
||||||
{
|
{
|
||||||
// Have we found the pointer already?
|
|
||||||
if(ptr == NULL)
|
|
||||||
{
|
|
||||||
// Get the record
|
|
||||||
assert(index >= 0);
|
|
||||||
Record *r = nif->getRecord(index);
|
|
||||||
|
|
||||||
// And cast it
|
|
||||||
ptr = dynamic_cast<X*>(r);
|
|
||||||
assert(ptr != NULL);
|
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)
|
||||||
|
{
|
||||||
|
for(size_t i=0;i < list.size();i++)
|
||||||
|
list[i].post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
X& operator[](size_t index)
|
||||||
|
{
|
||||||
|
return list.at(index).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(size_t index)
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < static_cast<int> (list.size()));
|
assert(index >= 0 && index < static_cast<int> (list.size()));
|
||||||
return list[index].get();
|
return !list.at(index).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has(int index)
|
int length()
|
||||||
{
|
{ return list.size(); }
|
||||||
assert(index >= 0 && index < static_cast<int> (list.size()));
|
|
||||||
return !list[index].empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
int getIndex(int index)
|
|
||||||
{
|
|
||||||
if(has(index)) return list[index].getIndex();
|
|
||||||
else return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int length() { return list.size(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue