mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
Set up a small post-processing layer to ease NIF animation handling
This commit is contained in:
parent
ef69584793
commit
aeec73806d
7 changed files with 108 additions and 21 deletions
33
nif/data.h
33
nif/data.h
|
@ -319,6 +319,25 @@ struct NiVisData : Record
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NiSkinInstance : Record
|
||||||
|
{
|
||||||
|
NiSkinDataPtr data;
|
||||||
|
NodePtr root;
|
||||||
|
NodeList bones;
|
||||||
|
|
||||||
|
void read(NIFFile *nif)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
struct NiSkinData : Record
|
struct NiSkinData : Record
|
||||||
{
|
{
|
||||||
// This is to make sure the structs are packed, ie. that the
|
// This is to make sure the structs are packed, ie. that the
|
||||||
|
@ -461,19 +480,5 @@ struct NiKeyframeData : Record
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiSkinInstance : Record
|
|
||||||
{
|
|
||||||
NiSkinDataPtr data;
|
|
||||||
NodePtr root;
|
|
||||||
NodeList bones;
|
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
|
||||||
{
|
|
||||||
data.read(nif);
|
|
||||||
root.read(nif);
|
|
||||||
bones.read(nif);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,11 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Nif;
|
using namespace Nif;
|
||||||
|
|
||||||
|
/* This file implements functions from the NIFFile class. It is also
|
||||||
|
where we stash all the functions we couldn't add as inline
|
||||||
|
definitions in the record types.
|
||||||
|
*/
|
||||||
|
|
||||||
void NIFFile::parse()
|
void NIFFile::parse()
|
||||||
{
|
{
|
||||||
// Check the header string
|
// Check the header string
|
||||||
|
@ -161,4 +166,28 @@ void NIFFile::parse()
|
||||||
ints following it. This might be a list of the root nodes in the
|
ints following it. This might be a list of the root nodes in the
|
||||||
tree, but for the moment we ignore it.
|
tree, but for the moment we ignore it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: Set up kf file here first, if applicable. It needs its own
|
||||||
|
// code to link it up with the main NIF structure.
|
||||||
|
|
||||||
|
// Once parsing is done, do post-processing.
|
||||||
|
for(int i=0; i<recNum; i++)
|
||||||
|
records[i]->post(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NiSkinInstance::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
int bnum = bones.length();
|
||||||
|
if(bnum != data->bones.size())
|
||||||
|
nif->fail("Mismatch in NiSkinData bone count");
|
||||||
|
|
||||||
|
root->makeRootBone(data->trafo);
|
||||||
|
|
||||||
|
for(int i=0; i<bnum; i++)
|
||||||
|
{
|
||||||
|
if(!bones.has(i))
|
||||||
|
nif->fail("Oops: Missing bone! Don't know how to handle this.");
|
||||||
|
|
||||||
|
bones[i].makeBone(i, data->bones[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
28
nif/node.h
28
nif/node.h
|
@ -25,6 +25,7 @@
|
||||||
#define _NIF_NODE_H_
|
#define _NIF_NODE_H_
|
||||||
|
|
||||||
#include "controlled.h"
|
#include "controlled.h"
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
@ -62,6 +63,33 @@ struct Node : Named
|
||||||
boundRot = nif->getMatrix();
|
boundRot = nif->getMatrix();
|
||||||
boundXYZ = nif->getVector();
|
boundXYZ = nif->getVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boneTrafo = NULL;
|
||||||
|
boneIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bone transformation. If set, node is a part of a skeleton.
|
||||||
|
const NiSkinData::BoneTrafo *boneTrafo;
|
||||||
|
|
||||||
|
// Bone weight info, from NiSkinData
|
||||||
|
const NiSkinData::BoneInfo *boneInfo;
|
||||||
|
|
||||||
|
// Bone index. If -1, this node is either not a bone, or the root
|
||||||
|
// bone in the skeleton.
|
||||||
|
short boneIndex;
|
||||||
|
|
||||||
|
// Make this the root animation bone
|
||||||
|
void makeRootBone(const NiSkinData::BoneTrafo *tr)
|
||||||
|
{
|
||||||
|
boneTrafo = tr;
|
||||||
|
boneIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeBone(short ind, const NiSkinData::BoneInfo &bi)
|
||||||
|
{
|
||||||
|
boneInfo = &bi;
|
||||||
|
boneTrafo = bi.trafo;
|
||||||
|
boneIndex = ind;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,12 @@ struct Record
|
||||||
|
|
||||||
Record() : recType(RC_NONE) {}
|
Record() : recType(RC_NONE) {}
|
||||||
|
|
||||||
|
/// Parses the record from file
|
||||||
virtual void read(NIFFile *nif) = 0;
|
virtual void read(NIFFile *nif) = 0;
|
||||||
|
|
||||||
|
/// Does post-processing, after the entire tree is loaded
|
||||||
|
virtual void post(NIFFile *nif) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use these later if you want custom allocation of all NIF objects
|
Use these later if you want custom allocation of all NIF objects
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,15 @@ class RecordPtrT
|
||||||
index = nif->getInt();
|
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)
|
||||||
|
{
|
||||||
|
ptr = p;
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/// Look up the actual object from the index
|
/// Look up the actual object from the index
|
||||||
X* getPtr()
|
X* getPtr()
|
||||||
{
|
{
|
||||||
|
@ -80,7 +89,7 @@ class RecordPtrT
|
||||||
X& get() { return *getPtr(); }
|
X& get() { return *getPtr(); }
|
||||||
|
|
||||||
/// Pointers are allowed to be empty
|
/// Pointers are allowed to be empty
|
||||||
bool empty() { return index == -1; }
|
bool empty() { return index == -1 && ptr == NULL; }
|
||||||
|
|
||||||
int getIndex() { return index; }
|
int getIndex() { return index; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,6 +90,15 @@ void doNode(Node *n)
|
||||||
doMatrix(n->boundRot);
|
doMatrix(n->boundRot);
|
||||||
doVector(n->boundXYZ);
|
doVector(n->boundXYZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(n->boneTrafo)
|
||||||
|
{
|
||||||
|
cout << "This is a bone: ";
|
||||||
|
if(n->boneIndex == -1)
|
||||||
|
cout << "root bone\n";
|
||||||
|
else
|
||||||
|
cout << "index " << n->boneIndex << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void doNiTriShape(NiTriShape *n)
|
void doNiTriShape(NiTriShape *n)
|
||||||
|
|
|
@ -521,7 +521,10 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the NIF
|
// Load the NIF. TODO: Wrap this in a try-catch block once we're out
|
||||||
|
// of the early stages of development. Right now we WANT to catch
|
||||||
|
// every error as early and intrusively as possible, as it's most
|
||||||
|
// likely a sign of incomplete code rather than faulty input.
|
||||||
NIFFile nif(vfs->open(name), name);
|
NIFFile nif(vfs->open(name), name);
|
||||||
|
|
||||||
if(nif.numRecords() < 1)
|
if(nif.numRecords() < 1)
|
||||||
|
|
Loading…
Reference in a new issue