forked from mirror/openmw-tes3mp
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_
|
||||
|
||||
#include "extra.hpp"
|
||||
#include "controller.hpp"
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
@ -40,6 +41,12 @@ public:
|
|||
Extra::read(nif);
|
||||
controller.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Extra::post(nif);
|
||||
controller.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
/// Has name, extra-data and controller
|
||||
|
@ -78,6 +85,12 @@ public:
|
|||
Controlled::read(nif);
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controlled::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiGravity : public Controlled
|
||||
|
|
|
@ -53,6 +53,13 @@ public:
|
|||
|
||||
target.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Record::post(nif);
|
||||
next.post(nif);
|
||||
target.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiBSPArrayController : public Controller
|
||||
|
@ -80,6 +87,12 @@ public:
|
|||
Controller::read(nif);
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiPathController : public Controller
|
||||
|
@ -101,6 +114,14 @@ public:
|
|||
posData.read(nif);
|
||||
floatData.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
|
||||
posData.post(nif);
|
||||
floatData.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiUVController : public Controller
|
||||
|
@ -115,6 +136,12 @@ public:
|
|||
nif->getShort(); // always 0
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiKeyframeController : public Controller
|
||||
|
@ -127,6 +154,12 @@ public:
|
|||
Controller::read(nif);
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiAlphaController : public Controller
|
||||
|
@ -139,6 +172,12 @@ public:
|
|||
Controller::read(nif);
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiGeomMorpherController : public Controller
|
||||
|
@ -152,6 +191,12 @@ public:
|
|||
data.read(nif);
|
||||
nif->getByte(); // always 0
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
class NiVisController : public Controller
|
||||
|
@ -164,6 +209,12 @@ public:
|
|||
Controller::read(nif);
|
||||
data.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Controller::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace Nif
|
|||
class NiSourceTexture : public Named
|
||||
{
|
||||
public:
|
||||
|
||||
// Is this an external (references a separate texture file) or
|
||||
// internal (data is inside the nif itself) texture?
|
||||
bool external;
|
||||
|
@ -70,8 +69,8 @@ public:
|
|||
Named::read(nif);
|
||||
|
||||
external = !!nif->getByte();
|
||||
|
||||
if(external) filename = nif->getString();
|
||||
if(external)
|
||||
filename = nif->getString();
|
||||
else
|
||||
{
|
||||
nif->getByte(); // always 1
|
||||
|
@ -84,6 +83,12 @@ public:
|
|||
|
||||
nif->getByte(); // always 1
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Named::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
// Common ancestor for several data classes
|
||||
|
@ -173,9 +178,11 @@ public:
|
|||
nif->getShort(); // Number of valid entries in the following arrays ?
|
||||
|
||||
if(nif->getInt())
|
||||
{
|
||||
// Particle sizes
|
||||
nif->getFloatLen(activeCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class NiRotatingParticlesData : public NiAutoNormalParticlesData
|
||||
|
@ -186,11 +193,13 @@ public:
|
|||
NiAutoNormalParticlesData::read(nif);
|
||||
|
||||
if(nif->getInt())
|
||||
{
|
||||
// Rotation quaternions. I THINK activeCount is correct here,
|
||||
// but verts (vertex number) might also be correct, if there is
|
||||
// any case where the two don't match.
|
||||
nif->getArrayLen<Vector4>(activeCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class NiPosData : public Record
|
||||
|
@ -228,11 +237,9 @@ public:
|
|||
// also used in FloatData and KeyframeData. We could probably
|
||||
// reuse and refactor a lot of this if we actually use it at some
|
||||
// point.
|
||||
|
||||
for(int i=0; i<2; i++)
|
||||
{
|
||||
int count = nif->getInt();
|
||||
|
||||
if(count)
|
||||
{
|
||||
nif->getInt(); // always 2
|
||||
|
@ -345,9 +352,6 @@ public:
|
|||
data.read(nif);
|
||||
root.read(nif);
|
||||
bones.read(nif);
|
||||
|
||||
if(data.empty() || root.empty())
|
||||
nif->fail("NiSkinInstance missing root or data");
|
||||
}
|
||||
|
||||
void post(NIFFile *nif);
|
||||
|
@ -415,7 +419,6 @@ public:
|
|||
nif->getInt(); // -1
|
||||
|
||||
bones.resize(boneNum);
|
||||
|
||||
for(int i=0;i<boneNum;i++)
|
||||
{
|
||||
BoneInfo &bi = bones[i];
|
||||
|
@ -439,43 +442,36 @@ class NiMorphData : public Record
|
|||
std::vector<std::vector<Ogre::Vector3> > relevantData;
|
||||
std::vector<std::vector<Ogre::Vector3> > additionalVertices;
|
||||
|
||||
|
||||
public:
|
||||
float getStartTime(){
|
||||
return startTime;
|
||||
}
|
||||
float getStopTime(){
|
||||
return stopTime;
|
||||
}
|
||||
void setStartTime(float time){
|
||||
startTime = time;
|
||||
}
|
||||
float getStartTime() const
|
||||
{ return startTime; }
|
||||
float getStopTime() const
|
||||
{ return stopTime; }
|
||||
|
||||
void setStopTime(float time){
|
||||
stopTime = time;
|
||||
}
|
||||
std::vector<Ogre::Vector3> getInitialVertices(){
|
||||
return initialVertices;
|
||||
}
|
||||
std::vector<std::vector<Ogre::Vector3> > getRelevantData(){
|
||||
return relevantData;
|
||||
}
|
||||
std::vector<std::vector<float> > getRelevantTimes(){
|
||||
return relevantTimes;
|
||||
}
|
||||
std::vector<std::vector<Ogre::Vector3> > getAdditionalVertices(){
|
||||
return additionalVertices;
|
||||
}
|
||||
void setStartTime(float time)
|
||||
{ startTime = time; }
|
||||
void setStopTime(float time)
|
||||
{ stopTime = time; }
|
||||
|
||||
void read(NIFFile *nif)
|
||||
const std::vector<Ogre::Vector3>& getInitialVertices() const
|
||||
{ return initialVertices; }
|
||||
const std::vector<std::vector<Ogre::Vector3> >& getRelevantData() const
|
||||
{ return relevantData; }
|
||||
const std::vector<std::vector<float> >& getRelevantTimes() const
|
||||
{ return relevantTimes; }
|
||||
const std::vector<std::vector<Ogre::Vector3> >& getAdditionalVertices() const
|
||||
{ return additionalVertices; }
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
int morphCount = nif->getInt();
|
||||
int vertCount = nif->getInt();
|
||||
nif->getByte();
|
||||
int magic = 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 y = nif->getFloat();
|
||||
float z = nif->getFloat();
|
||||
|
@ -488,7 +484,8 @@ void read(NIFFile *nif)
|
|||
/*type =*/ nif->getInt();
|
||||
std::vector<Ogre::Vector3> current;
|
||||
std::vector<float> currentTime;
|
||||
for(int i = 0; i < magic; i++){
|
||||
for(int i = 0; i < magic; i++)
|
||||
{
|
||||
// Time, data, forward, backward tangents
|
||||
float time = nif->getFloat();
|
||||
float x = nif->getFloat();
|
||||
|
@ -498,12 +495,16 @@ void read(NIFFile *nif)
|
|||
currentTime.push_back(time);
|
||||
//nif->getFloatLen(4*magic);
|
||||
}
|
||||
if(magic){
|
||||
|
||||
if(magic)
|
||||
{
|
||||
relevantData.push_back(current);
|
||||
relevantTimes.push_back(currentTime);
|
||||
}
|
||||
|
||||
std::vector<Ogre::Vector3> verts;
|
||||
for(int i = 0; i < vertCount; i++){
|
||||
for(int i = 0; i < vertCount; i++)
|
||||
{
|
||||
float x = nif->getFloat();
|
||||
float y = nif->getFloat();
|
||||
float z = nif->getFloat();
|
||||
|
@ -535,7 +536,6 @@ class NiKeyframeData : public Record
|
|||
int ttype;
|
||||
|
||||
//Scalings
|
||||
|
||||
std::vector<float> scalefactor;
|
||||
std::vector<float> scaletime;
|
||||
std::vector<float> forwards;
|
||||
|
@ -543,10 +543,8 @@ class NiKeyframeData : public Record
|
|||
std::vector<Ogre::Vector3> tbcscale;
|
||||
int stype;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
void clone(NiKeyframeData c)
|
||||
void clone(const NiKeyframeData &c)
|
||||
{
|
||||
quats = c.getQuat();
|
||||
tbc = c.getrTbc();
|
||||
|
@ -565,22 +563,15 @@ public:
|
|||
transtime = c.gettTime();
|
||||
|
||||
bonename = c.getBonename();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void setBonename(std::string bone)
|
||||
{
|
||||
bonename = bone;
|
||||
}
|
||||
{ bonename = bone; }
|
||||
void setStartTime(float start)
|
||||
{
|
||||
startTime = start;
|
||||
}
|
||||
{ startTime = start; }
|
||||
void setStopTime(float end)
|
||||
{
|
||||
stopTime = end;
|
||||
}
|
||||
{ stopTime = end; }
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
// Rotations first
|
||||
|
@ -589,7 +580,6 @@ public:
|
|||
//std::vector<float> rottime(count);
|
||||
if(count)
|
||||
{
|
||||
|
||||
//TYPE1 LINEAR_KEY
|
||||
//TYPE2 QUADRATIC_KEY
|
||||
//TYPE3 TBC_KEY
|
||||
|
@ -602,7 +592,8 @@ public:
|
|||
{
|
||||
//We need to actually read in these values instead of skipping them
|
||||
//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 w = nif->getFloat();
|
||||
float x = nif->getFloat();
|
||||
|
@ -616,8 +607,10 @@ public:
|
|||
}
|
||||
}
|
||||
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 w = nif->getFloat();
|
||||
float x = nif->getFloat();
|
||||
|
@ -627,6 +620,7 @@ public:
|
|||
float tbcx = nif->getFloat();
|
||||
float tbcy = nif->getFloat();
|
||||
float tbcz = nif->getFloat();
|
||||
|
||||
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);
|
||||
quats.push_back(quat);
|
||||
|
@ -635,8 +629,6 @@ public:
|
|||
//if(time == 0.0 || time > 355.5)
|
||||
// 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)
|
||||
{
|
||||
|
@ -651,28 +643,32 @@ public:
|
|||
nif->skip(cnt*4*2); // time + unknown
|
||||
else if(type == 2)
|
||||
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;
|
||||
|
||||
// Then translation
|
||||
count = nif->getInt();
|
||||
|
||||
if(count)
|
||||
{
|
||||
ttype = nif->getInt();
|
||||
|
||||
//std::cout << "TransCount:" << count << " Type: " << type << "\n";
|
||||
if(ttype == 1) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if(ttype == 1)
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
float time = nif->getFloat();
|
||||
float x = nif->getFloat();
|
||||
float y = nif->getFloat();
|
||||
float z = nif->getFloat();
|
||||
|
||||
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
|
||||
translist1.push_back(trans);
|
||||
transtime.push_back(time);
|
||||
|
@ -680,8 +676,10 @@ public:
|
|||
//nif->getFloatLen(count*4); // time + translation
|
||||
}
|
||||
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 x = nif->getFloat();
|
||||
float y = nif->getFloat();
|
||||
|
@ -692,6 +690,7 @@ public:
|
|||
float x3 = nif->getFloat();
|
||||
float y3 = nif->getFloat();
|
||||
float z3 = nif->getFloat();
|
||||
|
||||
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
|
||||
Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2);
|
||||
Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3);
|
||||
|
@ -703,8 +702,10 @@ public:
|
|||
|
||||
//nif->getFloatLen(count*10); // trans1 + forward + backward
|
||||
}
|
||||
else if(ttype == 3){
|
||||
for (int i = 0; i < count; i++) {
|
||||
else if(ttype == 3)
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
float time = nif->getFloat();
|
||||
float x = nif->getFloat();
|
||||
float y = nif->getFloat();
|
||||
|
@ -729,10 +730,8 @@ public:
|
|||
{
|
||||
stype = nif->getInt();
|
||||
|
||||
|
||||
for(int i = 0; i < count; i++){
|
||||
|
||||
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
//int size = 0;
|
||||
if(stype >= 1 && stype < 4)
|
||||
{
|
||||
|
@ -742,86 +741,70 @@ public:
|
|||
scalefactor.push_back(scale);
|
||||
//size = 2; // time+scale
|
||||
}
|
||||
else nif->fail("Unknown scaling type");
|
||||
if(stype == 2){
|
||||
else
|
||||
nif->fail("Unknown scaling type");
|
||||
|
||||
if(stype == 2)
|
||||
{
|
||||
//size = 4; // 1 + forward + backward (floats)
|
||||
float forward = nif->getFloat();
|
||||
float backward = nif->getFloat();
|
||||
forwards.push_back(forward);
|
||||
backwards.push_back(backward);
|
||||
}
|
||||
else if(stype == 3){
|
||||
else if(stype == 3)
|
||||
{
|
||||
//size = 5; // 1 + tbc
|
||||
float tbcx = nif->getFloat();
|
||||
float tbcy = nif->getFloat();
|
||||
float tbcz = nif->getFloat();
|
||||
Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
|
||||
tbcscale.push_back(vec);
|
||||
|
||||
//size = 5; // 1 + tbc
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
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
|
||||
|
|
|
@ -42,7 +42,6 @@ struct NiLight : Effect
|
|||
Vector diffuse;
|
||||
Vector specular;
|
||||
};
|
||||
|
||||
const SLight *light;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
|
@ -86,6 +85,12 @@ struct NiTextureEffect : Effect
|
|||
*/
|
||||
nif->skip(23);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Effect::post(nif);
|
||||
texture.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
ExtraPtr extra;
|
||||
|
||||
void read(NIFFile *nif) { extra.read(nif); }
|
||||
void post(NIFFile *nif) { extra.post(nif); }
|
||||
};
|
||||
|
||||
class NiVertWeightsExtraData : public Extra
|
||||
|
@ -67,7 +68,6 @@ public:
|
|||
float time;
|
||||
Misc::SString text;
|
||||
};
|
||||
|
||||
std::vector<TextKey> list;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
|
|
|
@ -190,8 +190,15 @@ void NIFFile::parse()
|
|||
|
||||
void NiSkinInstance::post(NIFFile *nif)
|
||||
{
|
||||
int bnum = bones.length();
|
||||
if(bnum != static_cast<int> (data->bones.size()))
|
||||
data.post(nif);
|
||||
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");
|
||||
|
||||
root->makeRootBone(data->trafo);
|
||||
|
@ -200,7 +207,6 @@ void NiSkinInstance::post(NIFFile *nif)
|
|||
{
|
||||
if(!bones.has(i))
|
||||
nif->fail("Oops: Missing bone! Don't know how to handle this.");
|
||||
|
||||
bones[i].makeBone(i, data->bones[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ namespace Nif
|
|||
|
||||
class NIFFile
|
||||
{
|
||||
enum NIFVersion
|
||||
{
|
||||
enum NIFVersion {
|
||||
VER_MW = 0x04000002 // Morrowind NIFs
|
||||
};
|
||||
|
||||
|
@ -63,7 +62,7 @@ class NIFFile
|
|||
/// Parse the file
|
||||
void parse();
|
||||
|
||||
public:
|
||||
public:
|
||||
/// Used for error handling
|
||||
void fail(const std::string &msg)
|
||||
{
|
||||
|
@ -95,16 +94,13 @@ class NIFFile
|
|||
~NIFFile()
|
||||
{
|
||||
for(std::size_t i=0; i<records.size(); i++)
|
||||
{
|
||||
delete records[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// 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[index];
|
||||
Record *res = records.at(index);
|
||||
assert(res != NULL);
|
||||
return res;
|
||||
}
|
||||
|
@ -112,10 +108,8 @@ class NIFFile
|
|||
/// Number of records
|
||||
int numRecords() { return records.size(); }
|
||||
|
||||
/* ************************************************
|
||||
|
||||
/*************************************************
|
||||
Parser functions
|
||||
|
||||
****************************************************/
|
||||
|
||||
void skip(size_t size) { inp->getPtr(size); }
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "controlled.hpp"
|
||||
#include "data.hpp"
|
||||
#include "property.hpp"
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
@ -69,6 +70,12 @@ public:
|
|||
boneIndex = -1;
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Named::post(nif);
|
||||
props.post(nif);
|
||||
}
|
||||
|
||||
// Bone transformation. If set, node is a part of a skeleton.
|
||||
const NiSkinData::BoneTrafo *boneTrafo;
|
||||
|
||||
|
@ -113,7 +120,6 @@ struct NiNode : Node
|
|||
NodeList effects;
|
||||
|
||||
/* Known NiNode flags:
|
||||
|
||||
0x01 hidden
|
||||
0x02 use mesh for collision
|
||||
0x04 use bounding box for collision (?)
|
||||
|
@ -127,6 +133,13 @@ struct NiNode : Node
|
|||
children.read(nif);
|
||||
effects.read(nif);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Node::post(nif);
|
||||
children.post(nif);
|
||||
effects.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
struct NiTriShape : Node
|
||||
|
@ -148,7 +161,15 @@ struct NiTriShape : Node
|
|||
skin.read(nif);
|
||||
}
|
||||
|
||||
NiTriShapeCopy clone(){
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Node::post(nif);
|
||||
data.post(nif);
|
||||
skin.post(nif);
|
||||
}
|
||||
|
||||
NiTriShapeCopy clone()
|
||||
{
|
||||
NiTriShapeCopy copy;
|
||||
copy.sname = name.toString();
|
||||
float *ptr = (float*)data->vertices.ptr;
|
||||
|
@ -159,13 +180,13 @@ struct NiTriShape : Node
|
|||
float *current = (float*) (ptr + i * 3);
|
||||
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
|
||||
|
||||
if(ptrNormals){
|
||||
if(ptrNormals)
|
||||
{
|
||||
float *currentNormals = (float*) (ptrNormals + i * 3);
|
||||
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return copy;
|
||||
}
|
||||
};
|
||||
|
@ -183,7 +204,6 @@ struct NiCamera : Node
|
|||
// Level of detail modifier
|
||||
float LOD;
|
||||
};
|
||||
|
||||
const Camera *cam;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
|
@ -207,6 +227,12 @@ struct NiAutoNormalParticles : Node
|
|||
data.read(nif);
|
||||
nif->getInt(); // -1
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Node::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
struct NiRotatingParticles : Node
|
||||
|
@ -219,9 +245,13 @@ struct NiRotatingParticles : Node
|
|||
data.read(nif);
|
||||
nif->getInt(); // -1
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
Node::post(nif);
|
||||
data.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // Namespace
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,11 @@ public:
|
|||
// short.
|
||||
nif->skip(6);
|
||||
}
|
||||
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
texture.post(nif);
|
||||
}
|
||||
};
|
||||
|
||||
/* Apply mode:
|
||||
|
@ -130,6 +135,13 @@ public:
|
|||
}
|
||||
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
|
||||
|
@ -140,15 +152,15 @@ typedef Property NiSpecularProperty;
|
|||
typedef Property NiWireframeProperty;
|
||||
|
||||
// The rest are all struct-based
|
||||
template <typename Struct>
|
||||
template <typename T>
|
||||
struct StructPropT : Property
|
||||
{
|
||||
const Struct* data;
|
||||
const T* data;
|
||||
|
||||
void read(NIFFile *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
|
||||
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void *p);
|
||||
*/
|
||||
|
|
|
@ -37,61 +37,51 @@ namespace Nif
|
|||
template <class X>
|
||||
class RecordPtrT
|
||||
{
|
||||
int index;
|
||||
union {
|
||||
intptr_t index;
|
||||
X* ptr;
|
||||
NIFFile *nif;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
RecordPtrT() : index(-2), ptr(NULL) {}
|
||||
public:
|
||||
RecordPtrT() : index(-2) {}
|
||||
|
||||
/// Read the index from the nif
|
||||
void read(NIFFile *_nif)
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
// Can only read the index once
|
||||
assert(index == -2);
|
||||
|
||||
// Store the NIFFile pointer for later
|
||||
nif = _nif;
|
||||
|
||||
// And the index, of course
|
||||
// Store the index for later
|
||||
index = nif->getInt();
|
||||
}
|
||||
|
||||
/** Set the pointer explicitly. May be used when you are pointing to
|
||||
records in another file, eg. when you have a .nif / .kf pair.
|
||||
*/
|
||||
void set(X *p)
|
||||
/// Resolve index to pointer
|
||||
void post(NIFFile *nif)
|
||||
{
|
||||
ptr = p;
|
||||
index = -1;
|
||||
if(index < 0)
|
||||
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
|
||||
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);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
X& get() { return *getPtr(); }
|
||||
|
||||
/// Syntactic sugar
|
||||
X* operator->() { return getPtr(); }
|
||||
X& get() { return *getPtr(); }
|
||||
|
||||
/// Pointers are allowed to be empty
|
||||
bool empty() { return index == -1 && ptr == NULL; }
|
||||
|
||||
int getIndex() { return index; }
|
||||
bool empty() { return ptr == NULL; }
|
||||
};
|
||||
|
||||
/** A list of references to other records. These are read as a list,
|
||||
|
@ -104,37 +94,35 @@ class RecordListT
|
|||
typedef RecordPtrT<X> Ptr;
|
||||
std::vector<Ptr> list;
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
int len = nif->getInt();
|
||||
list.resize(len);
|
||||
|
||||
assert(len >= 0 && len < 1000);
|
||||
for(int i=0;i<len;i++)
|
||||
for(size_t i=0;i < list.size();i++)
|
||||
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()));
|
||||
return list[index].get();
|
||||
return !list.at(index).empty();
|
||||
}
|
||||
|
||||
bool has(int index)
|
||||
{
|
||||
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(); }
|
||||
int length()
|
||||
{ return list.size(); }
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue