mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-06 16:15:33 +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
|
||||
{
|
||||
// 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
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
using namespace std;
|
||||
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()
|
||||
{
|
||||
// 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
|
||||
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_
|
||||
|
||||
#include "controlled.h"
|
||||
#include "data.h"
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
@ -62,6 +63,33 @@ struct Node : Named
|
|||
boundRot = nif->getMatrix();
|
||||
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) {}
|
||||
|
||||
/// Parses the record from file
|
||||
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
|
||||
|
||||
|
|
|
@ -58,6 +58,15 @@ class RecordPtrT
|
|||
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
|
||||
X* getPtr()
|
||||
{
|
||||
|
@ -80,7 +89,7 @@ class RecordPtrT
|
|||
X& get() { return *getPtr(); }
|
||||
|
||||
/// Pointers are allowed to be empty
|
||||
bool empty() { return index == -1; }
|
||||
bool empty() { return index == -1 && ptr == NULL; }
|
||||
|
||||
int getIndex() { return index; }
|
||||
};
|
||||
|
|
|
@ -90,6 +90,15 @@ void doNode(Node *n)
|
|||
doMatrix(n->boundRot);
|
||||
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)
|
||||
|
@ -122,11 +131,11 @@ void doNiSkinData(NiSkinData *n)
|
|||
cout << "Weight number: " << bi.weights.length << endl;
|
||||
|
||||
if(verbose)
|
||||
for(int j=0; j<bi.weights.length; j++)
|
||||
{
|
||||
const NiSkinData::VertWeight &w = bi.weights.ptr[j];
|
||||
cout << " vert:" << w.vertex << " weight:" << w.weight << endl;
|
||||
}
|
||||
for(int j=0; j<bi.weights.length; j++)
|
||||
{
|
||||
const NiSkinData::VertWeight &w = bi.weights.ptr[j];
|
||||
cout << " vert:" << w.vertex << " weight:" << w.weight << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -521,7 +521,10 @@ void NIFLoader::loadResource(Resource *resource)
|
|||
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);
|
||||
|
||||
if(nif.numRecords() < 1)
|
||||
|
|
Loading…
Reference in a new issue