mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 18:29:55 +00:00
More NIFLoader code
This commit is contained in:
parent
828a3904a5
commit
e8ec9093f8
4 changed files with 655 additions and 101 deletions
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "controlled.hpp"
|
#include "controlled.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Ogre.h>
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
@ -366,6 +367,12 @@ public:
|
||||||
Vector trans; // Translation
|
Vector trans; // Translation
|
||||||
float scale; // Probably scale (always 1)
|
float scale; // Probably scale (always 1)
|
||||||
};
|
};
|
||||||
|
struct BoneTrafoCopy
|
||||||
|
{
|
||||||
|
Ogre::Quaternion rotation;
|
||||||
|
Ogre::Vector3 trans;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
|
||||||
struct VertWeight
|
struct VertWeight
|
||||||
{
|
{
|
||||||
|
@ -380,6 +387,13 @@ public:
|
||||||
const Vector4 *unknown;
|
const Vector4 *unknown;
|
||||||
Misc::SliceArray<VertWeight> weights;
|
Misc::SliceArray<VertWeight> weights;
|
||||||
};
|
};
|
||||||
|
struct BoneInfoCopy
|
||||||
|
{
|
||||||
|
std::string bonename;
|
||||||
|
BoneTrafoCopy trafo;
|
||||||
|
Vector4 unknown;
|
||||||
|
std::vector<VertWeight> weights;
|
||||||
|
};
|
||||||
|
|
||||||
const BoneTrafo *trafo;
|
const BoneTrafo *trafo;
|
||||||
std::vector<BoneInfo> bones;
|
std::vector<BoneInfo> bones;
|
||||||
|
@ -412,92 +426,397 @@ public:
|
||||||
|
|
||||||
class NiMorphData : public Record
|
class NiMorphData : public Record
|
||||||
{
|
{
|
||||||
|
float startTime;
|
||||||
|
float stopTime;
|
||||||
|
std::vector<Ogre::Vector3> initialVertices;
|
||||||
|
std::vector<std::vector<float>> relevantTimes;
|
||||||
|
std::vector<std::vector<Ogre::Vector3>> relevantData;
|
||||||
|
std::vector<std::vector<Ogre::Vector3>> additionalVertices;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read(NIFFile *nif)
|
float getStartTime(){
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
float getStopTime(){
|
||||||
|
return stopTime;
|
||||||
|
}
|
||||||
|
void setStartTime(float time){
|
||||||
|
startTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
int morphCount = nif->getInt();
|
int morphCount = nif->getInt();
|
||||||
int vertCount = nif->getInt();
|
int vertCount = nif->getInt();
|
||||||
nif->getByte();
|
nif->getByte();
|
||||||
|
int magic = nif->getInt();
|
||||||
|
int type = nif->getInt();
|
||||||
|
for(int i = 0; i < vertCount; i++){
|
||||||
|
|
||||||
for(int i=0; i<morphCount; i++)
|
float x = nif->getFloat();
|
||||||
{
|
float y = nif->getFloat();
|
||||||
int magic = nif->getInt();
|
float z = nif->getFloat();
|
||||||
nif->getInt();
|
initialVertices.push_back(Ogre::Vector3(x, y, z));
|
||||||
if(magic)
|
}
|
||||||
// Time, data, forward, backward tangents
|
|
||||||
nif->getFloatLen(4*magic);
|
for(int i=1; i<morphCount; i++)
|
||||||
|
{
|
||||||
nif->getFloatLen(vertCount*3);
|
magic = nif->getInt();
|
||||||
|
type = nif->getInt();
|
||||||
|
std::vector<Ogre::Vector3> current;
|
||||||
|
std::vector<float> currentTime;
|
||||||
|
for(int i = 0; i < magic; i++){
|
||||||
|
// Time, data, forward, backward tangents
|
||||||
|
float time = nif->getFloat();
|
||||||
|
float x = nif->getFloat();
|
||||||
|
float y = nif->getFloat();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
current.push_back(Ogre::Vector3(x,y,z));
|
||||||
|
currentTime.push_back(time);
|
||||||
|
//nif->getFloatLen(4*magic);
|
||||||
|
}
|
||||||
|
if(magic){
|
||||||
|
relevantData.push_back(current);
|
||||||
|
relevantTimes.push_back(currentTime);
|
||||||
|
}
|
||||||
|
std::vector<Ogre::Vector3> verts;
|
||||||
|
for(int i = 0; i < vertCount; i++){
|
||||||
|
float x = nif->getFloat();
|
||||||
|
float y = nif->getFloat();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
verts.push_back(Ogre::Vector3(x, y, z));
|
||||||
|
}
|
||||||
|
additionalVertices.push_back(verts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class NiKeyframeData : public Record
|
class NiKeyframeData : public Record
|
||||||
{
|
{
|
||||||
public:
|
std::string bonename;
|
||||||
|
//Rotations
|
||||||
|
std::vector<Ogre::Quaternion> quats;
|
||||||
|
std::vector<Ogre::Vector3> tbc;
|
||||||
|
std::vector<float> rottime;
|
||||||
|
float startTime;
|
||||||
|
float stopTime;
|
||||||
|
int rtype;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
//Translations
|
||||||
{
|
std::vector<Ogre::Vector3> translist1;
|
||||||
// Rotations first
|
std::vector<Ogre::Vector3> translist2;
|
||||||
int count = nif->getInt();
|
std::vector<Ogre::Vector3> translist3;
|
||||||
if(count)
|
std::vector<Ogre::Vector3> transtbc;
|
||||||
{
|
std::vector<float> transtime;
|
||||||
int type = nif->getInt();
|
int ttype;
|
||||||
|
|
||||||
if(type == 1)
|
//Scalings
|
||||||
nif->skip(count*4*5); // time + quaternion
|
|
||||||
else if(type == 3)
|
|
||||||
nif->skip(count*4*8); // rot1 + tension+bias+continuity
|
|
||||||
else if(type == 4)
|
|
||||||
{
|
|
||||||
for(int j=0;j<count;j++)
|
|
||||||
{
|
|
||||||
nif->getFloat(); // time
|
|
||||||
for(int i=0; i<3; i++)
|
|
||||||
{
|
|
||||||
int cnt = nif->getInt();
|
|
||||||
int type = nif->getInt();
|
|
||||||
if(type == 1)
|
|
||||||
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 rotation type in NiKeyframeData");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then translation
|
std::vector<float> scalefactor;
|
||||||
count = nif->getInt();
|
std::vector<float> scaletime;
|
||||||
|
std::vector<float> forwards;
|
||||||
|
std::vector<float> backwards;
|
||||||
|
std::vector<Ogre::Vector3> tbcscale;
|
||||||
|
int stype;
|
||||||
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
int type = nif->getInt();
|
public:
|
||||||
|
void clone(NiKeyframeData c)
|
||||||
|
{
|
||||||
|
quats = c.getQuat();
|
||||||
|
tbc = c.getrTbc();
|
||||||
|
rottime = c.getrTime();
|
||||||
|
|
||||||
if(type == 1)
|
//types
|
||||||
nif->getFloatLen(count*4); // time + translation
|
ttype = c.getTtype();
|
||||||
else if(type == 2)
|
rtype = c.getRtype();
|
||||||
nif->getFloatLen(count*10); // trans1 + forward + backward
|
stype = c.getStype();
|
||||||
else if(type == 3)
|
|
||||||
nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
|
|
||||||
else nif->fail("Unknown translation type");
|
translist1 = c.getTranslist1();
|
||||||
}
|
translist2 = c.getTranslist2();
|
||||||
|
translist3 = c.getTranslist3();
|
||||||
|
|
||||||
|
transtime = c.gettTime();
|
||||||
|
|
||||||
|
bonename = c.getBonename();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBonename(std::string bone)
|
||||||
|
{
|
||||||
|
bonename = bone;
|
||||||
|
}
|
||||||
|
void setStartTime(float start)
|
||||||
|
{
|
||||||
|
startTime = start;
|
||||||
|
}
|
||||||
|
void setStopTime(float end)
|
||||||
|
{
|
||||||
|
stopTime = end;
|
||||||
|
}
|
||||||
|
void read(NIFFile *nif)
|
||||||
|
{
|
||||||
|
// Rotations first
|
||||||
|
int count = nif->getInt();
|
||||||
|
//std::vector<Ogre::Quaternion> quat(count);
|
||||||
|
//std::vector<float> rottime(count);
|
||||||
|
std::cout << "r";
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
|
||||||
|
//TYPE1 LINEAR_KEY
|
||||||
|
//TYPE2 QUADRATIC_KEY
|
||||||
|
//TYPE3 TBC_KEY
|
||||||
|
//TYPE4 XYZ_ROTATION_KEY
|
||||||
|
//TYPE5 UNKNOWN_KEY
|
||||||
|
rtype = nif->getInt();
|
||||||
|
//std::cout << "Count: " << count << "Type: " << type << "\n";
|
||||||
|
|
||||||
|
if(rtype == 1)
|
||||||
|
{
|
||||||
|
//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++) {
|
||||||
|
float time = nif->getFloat();
|
||||||
|
float w = nif->getFloat();
|
||||||
|
float x = nif->getFloat();
|
||||||
|
float y = nif->getFloat();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
|
||||||
|
quats.push_back(quat);
|
||||||
|
rottime.push_back(time);
|
||||||
|
//if(time == 0.0 || time > 355.5)
|
||||||
|
// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(rtype == 3)
|
||||||
|
{ //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();
|
||||||
|
float y = nif->getFloat();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
|
||||||
|
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);
|
||||||
|
rottime.push_back(time);
|
||||||
|
tbc.push_back(vec);
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
for(int j=0;j<count;j++)
|
||||||
|
{
|
||||||
|
nif->getFloat(); // time
|
||||||
|
for(int i=0; i<3; i++)
|
||||||
|
{
|
||||||
|
int cnt = nif->getInt();
|
||||||
|
int type = nif->getInt();
|
||||||
|
if(type == 1)
|
||||||
|
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 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++) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
//nif->getFloatLen(count*4); // time + translation
|
||||||
|
}
|
||||||
|
else if(ttype == 2)
|
||||||
|
{ //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();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
float x2 = nif->getFloat();
|
||||||
|
float y2 = nif->getFloat();
|
||||||
|
float z2 = nif->getFloat();
|
||||||
|
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);
|
||||||
|
transtime.push_back(time);
|
||||||
|
translist1.push_back(trans);
|
||||||
|
translist2.push_back(trans2);
|
||||||
|
translist3.push_back(trans3);
|
||||||
|
}
|
||||||
|
|
||||||
|
//nif->getFloatLen(count*10); // trans1 + forward + backward
|
||||||
|
}
|
||||||
|
else if(ttype == 3){
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
float time = nif->getFloat();
|
||||||
|
float x = nif->getFloat();
|
||||||
|
float y = nif->getFloat();
|
||||||
|
float z = nif->getFloat();
|
||||||
|
float t = nif->getFloat();
|
||||||
|
float b = nif->getFloat();
|
||||||
|
float c = nif->getFloat();
|
||||||
|
Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
|
||||||
|
Ogre::Vector3 tbc = Ogre::Vector3(t, b, c);
|
||||||
|
translist1.push_back(trans);
|
||||||
|
transtbc.push_back(tbc);
|
||||||
|
transtime.push_back(time);
|
||||||
|
}
|
||||||
|
//nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
|
||||||
|
}
|
||||||
|
else nif->fail("Unknown translation type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, scalings
|
||||||
|
count = nif->getInt();
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
stype = nif->getInt();
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++){
|
||||||
|
|
||||||
|
|
||||||
|
//int size = 0;
|
||||||
|
if(stype >= 1 && stype < 4)
|
||||||
|
{
|
||||||
|
float time = nif->getFloat();
|
||||||
|
float scale = nif->getFloat();
|
||||||
|
scaletime.push_back(time);
|
||||||
|
scalefactor.push_back(scale);
|
||||||
|
//size = 2; // time+scale
|
||||||
|
}
|
||||||
|
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){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, scalings
|
|
||||||
count = nif->getInt();
|
|
||||||
if(count)
|
|
||||||
{
|
|
||||||
int type = nif->getInt();
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
if(type == 1) size = 2; // time+scale
|
|
||||||
else if(type == 2) size = 4; // 1 + forward + backward (floats)
|
|
||||||
else if(type == 3) size = 5; // 1 + tbc
|
|
||||||
else nif->fail("Unknown scaling type");
|
|
||||||
nif->getFloatLen(count*size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
|
|
|
@ -93,6 +93,19 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NiTriShapeCopy
|
||||||
|
{
|
||||||
|
std::string sname;
|
||||||
|
std::vector<std::string> boneSequence;
|
||||||
|
Nif::NiSkinData::BoneTrafoCopy trafo;
|
||||||
|
//Ogre::Quaternion initialBoneRotation;
|
||||||
|
//Ogre::Vector3 initialBoneTranslation;
|
||||||
|
std::vector<Ogre::Vector3> vertices;
|
||||||
|
std::vector<Ogre::Vector3> normals;
|
||||||
|
std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo;
|
||||||
|
Nif::NiMorphData morph;
|
||||||
|
};
|
||||||
|
|
||||||
struct NiNode : Node
|
struct NiNode : Node
|
||||||
{
|
{
|
||||||
NodeList children;
|
NodeList children;
|
||||||
|
@ -133,6 +146,27 @@ struct NiTriShape : Node
|
||||||
data.read(nif);
|
data.read(nif);
|
||||||
skin.read(nif);
|
skin.read(nif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NiTriShapeCopy clone(){
|
||||||
|
NiTriShapeCopy copy;
|
||||||
|
copy.sname = name.toString();
|
||||||
|
float *ptr = (float*)data->vertices.ptr;
|
||||||
|
float *ptrNormals = (float*)data->normals.ptr;
|
||||||
|
int numVerts = data->vertices.length / 3;
|
||||||
|
for(int i = 0; i < numVerts; i++)
|
||||||
|
{
|
||||||
|
float *current = (float*) (ptr + i * 3);
|
||||||
|
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
|
||||||
|
|
||||||
|
if(ptrNormals){
|
||||||
|
float *currentNormals = (float*) (ptrNormals + i * 3);
|
||||||
|
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NiCamera : Node
|
struct NiCamera : Node
|
||||||
|
@ -186,5 +220,7 @@ struct NiRotatingParticles : Node
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,25 +24,7 @@
|
||||||
//loadResource->handleNode->handleNiTriShape->createSubMesh
|
//loadResource->handleNode->handleNiTriShape->createSubMesh
|
||||||
|
|
||||||
#include "ogre_nif_loader.hpp"
|
#include "ogre_nif_loader.hpp"
|
||||||
#include <Ogre.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <libs/mangle/vfs/servers/ogre_vfs.hpp>
|
|
||||||
#include "../nif/nif_file.hpp"
|
|
||||||
#include "../nif/node.hpp"
|
|
||||||
#include "../nif/data.hpp"
|
|
||||||
#include "../nif/property.hpp"
|
|
||||||
#include "../nif/controller.hpp"
|
|
||||||
#include "../nif/extra.hpp"
|
|
||||||
#include <libs/platform/strings.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
// For warning messages
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// float infinity
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
typedef unsigned char ubyte;
|
typedef unsigned char ubyte;
|
||||||
|
|
||||||
|
@ -583,7 +565,7 @@ static void vectorMul(const Matrix &A, float *C)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds)
|
void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds, Transformation original, std::vector<std::string> boneSequence)
|
||||||
{
|
{
|
||||||
assert(shape != NULL);
|
assert(shape != NULL);
|
||||||
|
|
||||||
|
@ -744,11 +726,39 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
std::list<VertexBoneAssignment> vertexBoneAssignments;
|
std::list<VertexBoneAssignment> vertexBoneAssignments;
|
||||||
|
|
||||||
|
Nif::NiTriShapeCopy copy = shape->clone();
|
||||||
|
if(!shape->controller.empty())
|
||||||
|
{
|
||||||
|
//Nif::NiGeomMorpherController* cont = dynamic_cast<Nif::NiGeomMorpherController*> (shape->controller.getPtr());
|
||||||
|
Nif::Controller* cont = shape->controller.getPtr();
|
||||||
|
if(cont->recType == RC_NiGeomMorpherController)
|
||||||
|
{
|
||||||
|
Nif::NiGeomMorpherController* morph = dynamic_cast<Nif::NiGeomMorpherController*> (cont);
|
||||||
|
copy.morph = morph->data.get();
|
||||||
|
copy.morph.setStartTime(morph->timeStart);
|
||||||
|
copy.morph.setStopTime(morph->timeStop);
|
||||||
|
//std::cout << "Size" << morph->data->getInitialVertices().size() << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::cout << "We have a controller";
|
||||||
|
}
|
||||||
//use niskindata for the position of vertices.
|
//use niskindata for the position of vertices.
|
||||||
if (!shape->skin.empty())
|
if (!shape->skin.empty())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//std::cout << "Skin is not empty\n";
|
||||||
|
//Bone assignments are stored in submeshes, so we don't need to copy them
|
||||||
|
//std::string triname
|
||||||
|
//std::vector<Ogre::Vector3> vertices;
|
||||||
|
//std::vector<Ogre::Vector3> normals;
|
||||||
|
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo;
|
||||||
|
|
||||||
|
|
||||||
// vector that stores if the position if a vertex is absolute
|
// vector that stores if the position if a vertex is absolute
|
||||||
std::vector<bool> vertexPosAbsolut(numVerts,false);
|
std::vector<bool> vertexPosAbsolut(numVerts,false);
|
||||||
|
std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO);
|
||||||
|
std::vector<Ogre::Vector3> vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO);
|
||||||
|
|
||||||
float *ptrNormals = (float*)data->normals.ptr;
|
float *ptrNormals = (float*)data->normals.ptr;
|
||||||
//the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex]
|
//the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex]
|
||||||
|
@ -775,24 +785,34 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//get the bone from bones array of skindata
|
//get the bone from bones array of skindata
|
||||||
|
if(!mSkel->hasBone(shape->skin->bones[boneIndex].name.toString()))
|
||||||
|
std::cout << "We don't have this bone";
|
||||||
bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString());
|
bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString());
|
||||||
|
|
||||||
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
||||||
vecPos = bonePtr->_getDerivedPosition() +
|
|
||||||
|
|
||||||
|
Nif::NiSkinData::BoneInfoCopy boneinfo;
|
||||||
|
boneinfo.trafo.rotation = convertRotation(it->trafo->rotation);
|
||||||
|
boneinfo.trafo.trans = convertVector3(it->trafo->trans);
|
||||||
|
boneinfo.bonename = shape->skin->bones[boneIndex].name.toString();
|
||||||
|
for (unsigned int i=0; i<it->weights.length; i++)
|
||||||
|
{
|
||||||
|
vecPos = bonePtr->_getDerivedPosition() +
|
||||||
bonePtr->_getDerivedOrientation() * convertVector3(it->trafo->trans);
|
bonePtr->_getDerivedOrientation() * convertVector3(it->trafo->trans);
|
||||||
|
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation);
|
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation);
|
||||||
|
|
||||||
for (unsigned int i=0; i<it->weights.length; i++)
|
|
||||||
{
|
|
||||||
unsigned int verIndex = (it->weights.ptr + i)->vertex;
|
unsigned int verIndex = (it->weights.ptr + i)->vertex;
|
||||||
|
boneinfo.weights.push_back(*(it->weights.ptr + i));
|
||||||
//Check if the vertex is relativ, FIXME: Is there a better solution?
|
//Check if the vertex is relativ, FIXME: Is there a better solution?
|
||||||
if (vertexPosAbsolut[verIndex] == false)
|
if (vertexPosAbsolut[verIndex] == false)
|
||||||
{
|
{
|
||||||
//apply transformation to the vertices
|
//apply transformation to the vertices
|
||||||
Vector3 absVertPos = vecPos + vecRot * Vector3(ptr + verIndex *3);
|
Vector3 absVertPos = vecPos + vecRot * Vector3(ptr + verIndex *3);
|
||||||
|
absVertPos = absVertPos * (it->weights.ptr + i)->weight;
|
||||||
|
vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3);
|
||||||
|
|
||||||
|
mBoundingBox.merge(absVertPos);
|
||||||
//convert it back to float *
|
//convert it back to float *
|
||||||
for (int j=0; j<3; j++)
|
for (int j=0; j<3; j++)
|
||||||
(ptr + verIndex*3)[j] = absVertPos[j];
|
(ptr + verIndex*3)[j] = absVertPos[j];
|
||||||
|
@ -802,37 +822,79 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
if (verIndex < data->normals.length)
|
if (verIndex < data->normals.length)
|
||||||
{
|
{
|
||||||
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
|
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
|
||||||
|
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
|
||||||
|
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3);
|
||||||
|
|
||||||
for (int j=0; j<3; j++)
|
for (int j=0; j<3; j++)
|
||||||
(ptrNormals + verIndex*3)[j] = absNormalsPos[j];
|
(ptrNormals + verIndex*3)[j] = absNormalsPos[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexPosAbsolut[verIndex] = true;
|
vertexPosAbsolut[verIndex] = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
|
||||||
|
absVertPos = absVertPos * (it->weights.ptr + i)->weight;
|
||||||
|
Vector3 old = Vector3(ptr + verIndex *3);
|
||||||
|
absVertPos = absVertPos + old;
|
||||||
|
|
||||||
|
mBoundingBox.merge(absVertPos);
|
||||||
|
//convert it back to float *
|
||||||
|
for (int j=0; j<3; j++)
|
||||||
|
(ptr + verIndex*3)[j] = absVertPos[j];
|
||||||
|
|
||||||
|
//apply rotation to the normals (not every vertex has a normal)
|
||||||
|
//FIXME: I guessed that vertex[i] = normal[i], is that true?
|
||||||
|
if (verIndex < data->normals.length)
|
||||||
|
{
|
||||||
|
Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
|
||||||
|
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
|
||||||
|
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3);
|
||||||
|
absNormalsPos = absNormalsPos + oldNormal;
|
||||||
|
|
||||||
|
for (int j=0; j<3; j++)
|
||||||
|
(ptrNormals + verIndex*3)[j] = absNormalsPos[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexBoneAssignment vba;
|
VertexBoneAssignment vba;
|
||||||
vba.boneIndex = bonePtr->getHandle();
|
vba.boneIndex = bonePtr->getHandle();
|
||||||
vba.vertexIndex = verIndex;
|
vba.vertexIndex = verIndex;
|
||||||
vba.weight = (it->weights.ptr + i)->weight;
|
vba.weight = (it->weights.ptr + i)->weight;
|
||||||
|
|
||||||
|
|
||||||
vertexBoneAssignments.push_back(vba);
|
vertexBoneAssignments.push_back(vba);
|
||||||
}
|
}
|
||||||
|
copy.boneinfo.push_back(boneinfo);
|
||||||
|
|
||||||
boneIndex++;
|
boneIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
copy.boneSequence = boneSequence;
|
||||||
// Rotate, scale and translate all the vertices,
|
// Rotate, scale and translate all the vertices,
|
||||||
const Matrix &rot = shape->trafo->rotation;
|
const Matrix &rot = shape->trafo->rotation;
|
||||||
const Vector &pos = shape->trafo->pos;
|
const Vector &pos = shape->trafo->pos;
|
||||||
float scale = shape->trafo->scale;
|
float scale = shape->trafo->scale;
|
||||||
|
|
||||||
|
copy.trafo.trans = convertVector3(original.pos);
|
||||||
|
copy.trafo.rotation = convertRotation(original.rotation);
|
||||||
|
copy.trafo.scale = original.scale;
|
||||||
|
//We don't use velocity for anything yet, so it does not need to be saved
|
||||||
|
|
||||||
|
// Computes C = B + AxC*scale
|
||||||
for (int i=0; i<numVerts; i++)
|
for (int i=0; i<numVerts; i++)
|
||||||
{
|
{
|
||||||
vectorMulAdd(rot, pos, ptr, scale);
|
vectorMulAdd(rot, pos, ptr, scale);
|
||||||
|
Ogre::Vector3 absVertPos = Ogre::Vector3(*(ptr + 3 * i), *(ptr + 3 * i + 1), *(ptr + 3 * i + 2));
|
||||||
|
mBoundingBox.merge(absVertPos);
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember to rotate all the vertex normals as well
|
// Remember to rotate all the vertex normals as well
|
||||||
if (data->normals.length)
|
if (data->normals.length)
|
||||||
{
|
{
|
||||||
|
@ -843,12 +905,28 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!mSkel.isNull() ){
|
||||||
|
int boneIndex;
|
||||||
|
Ogre::Bone *parentBone = mSkel->getBone(boneSequence[boneSequence.size() - 1]);
|
||||||
|
if(parentBone)
|
||||||
|
boneIndex = parentBone->getHandle();
|
||||||
|
else
|
||||||
|
boneIndex = mSkel->getNumBones() - 1;
|
||||||
|
for(int i = 0; i < numVerts; i++){
|
||||||
|
VertexBoneAssignment vba;
|
||||||
|
vba.boneIndex = boneIndex;
|
||||||
|
vba.vertexIndex = i;
|
||||||
|
vba.weight = 1;
|
||||||
|
vertexBoneAssignments.push_back(vba);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hidden)
|
if (!hidden)
|
||||||
{
|
{
|
||||||
// Add this vertex set to the bounding box
|
// Add this vertex set to the bounding box
|
||||||
bounds.add(optr, numVerts);
|
bounds.add(optr, numVerts);
|
||||||
|
shapes.push_back(copy);
|
||||||
|
|
||||||
// Create the submesh
|
// Create the submesh
|
||||||
createOgreSubMesh(shape, material, vertexBoneAssignments);
|
createOgreSubMesh(shape, material, vertexBoneAssignments);
|
||||||
|
@ -877,7 +955,7 @@ void NIFLoader::calculateTransform()
|
||||||
|
|
||||||
}
|
}
|
||||||
void NIFLoader::handleNode(Nif::Node *node, int flags,
|
void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
const Transformation *trafo, BoundsFinder &bounds, Bone *parentBone)
|
const Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone, std::vector<std::string> boneSequence)
|
||||||
{
|
{
|
||||||
//if( MWClass::isChest)
|
//if( MWClass::isChest)
|
||||||
// cout << "u:" << node << "\n";
|
// cout << "u:" << node << "\n";
|
||||||
|
@ -908,6 +986,48 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
// the engine, just skip this entire node.
|
// the engine, just skip this entire node.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e->recType == RC_NiTextKeyExtraData){
|
||||||
|
Nif::NiTextKeyExtraData* extra = dynamic_cast<Nif::NiTextKeyExtraData*> (e);
|
||||||
|
|
||||||
|
std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin();
|
||||||
|
//std::ofstream File("Indices" + name + ".txt");
|
||||||
|
|
||||||
|
//std::string sample = "uy";
|
||||||
|
|
||||||
|
std::string cut = "";
|
||||||
|
for(int i = 0; i < name.length(); i++)
|
||||||
|
{
|
||||||
|
if(!(name.at(i) == '\\' || name.at(i) == '/' || name.at(i) == '>' || name.at(i) == '<' || name.at(i) == '?' || name.at(i) == '*' || name.at(i) == '|' || name.at(i) == ':' || name.at(i) == '"'))
|
||||||
|
{
|
||||||
|
cut += name.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//std::cout << "End" << end;
|
||||||
|
|
||||||
|
std::cout << "Outputting " << cut << "\n";
|
||||||
|
|
||||||
|
std::ofstream File("Indices" + cut + ".txt");
|
||||||
|
|
||||||
|
/*if(File.is_open())
|
||||||
|
std::cout << "We could open\n";
|
||||||
|
else
|
||||||
|
std::cout << "We could not\n";*/
|
||||||
|
for(; textiter != extra->list.end(); textiter++)
|
||||||
|
{
|
||||||
|
//if(textiter->text.toString().find("Torch") < textiter->text.toString().length())
|
||||||
|
//std::cout << "Time: " << textiter->time << " " << textiter->text.toString() << "\n";
|
||||||
|
std::string text = textiter->text.toString();
|
||||||
|
|
||||||
|
replace(text.begin(), text.end(), '\n', '/');
|
||||||
|
|
||||||
|
text.erase(std::remove(text.begin(), text.end(), '\r'), text.end());
|
||||||
|
File << "Time: " << textiter->time << "|" << text << "\n";
|
||||||
|
|
||||||
|
textmappings[text] = textiter->time;
|
||||||
|
}
|
||||||
|
File.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bone *bone = 0;
|
Bone *bone = 0;
|
||||||
|
@ -930,6 +1050,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
if (!mSkel.isNull()) //if there is a skeleton
|
if (!mSkel.isNull()) //if there is a skeleton
|
||||||
{
|
{
|
||||||
std::string name = node->name.toString();
|
std::string name = node->name.toString();
|
||||||
|
boneSequence.push_back(name);
|
||||||
//if (isBeast && isChest)
|
//if (isBeast && isChest)
|
||||||
// std::cout << "NAME: " << name << "\n";
|
// std::cout << "NAME: " << name << "\n";
|
||||||
// Quick-n-dirty workaround for the fact that several
|
// Quick-n-dirty workaround for the fact that several
|
||||||
|
@ -947,7 +1068,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Transformation original = *(node->trafo);
|
||||||
// Apply the parent transformation to this node. We overwrite the
|
// Apply the parent transformation to this node. We overwrite the
|
||||||
// existing data with the final transformation.
|
// existing data with the final transformation.
|
||||||
if (trafo)
|
if (trafo)
|
||||||
|
@ -978,12 +1099,23 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
{
|
{
|
||||||
|
|
||||||
if (list.has(i))
|
if (list.has(i))
|
||||||
handleNode(&list[i], flags, node->trafo, bounds, bone);
|
handleNode(&list[i], flags, node->trafo, bounds, bone, boneSequence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node->recType == RC_NiTriShape)
|
else if (node->recType == RC_NiTriShape)
|
||||||
{
|
{
|
||||||
handleNiTriShape(dynamic_cast<NiTriShape*>(node), flags, bounds);
|
std::string nodename = node->name.toString();
|
||||||
|
|
||||||
|
if (triname == "")
|
||||||
|
{
|
||||||
|
handleNiTriShape(dynamic_cast<NiTriShape*>(node), flags, bounds, original, boneSequence);
|
||||||
|
}
|
||||||
|
else if(name.length() >= triname.length())
|
||||||
|
{
|
||||||
|
std::transform(nodename.begin(), nodename.end(), nodename.begin(), std::tolower);
|
||||||
|
if(triname == name.substr(0, triname.length()))
|
||||||
|
handleNiTriShape(dynamic_cast<NiTriShape*>(node), flags, bounds, original, boneSequence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +1125,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
mesh = 0;
|
mesh = 0;
|
||||||
mSkel.setNull();
|
mSkel.setNull();
|
||||||
flip = false;
|
flip = false;
|
||||||
std::string name = resource->getName();
|
name = resource->getName();
|
||||||
char suffix = name.at(name.length() - 2);
|
char suffix = name.at(name.length() - 2);
|
||||||
|
|
||||||
if(suffix == '*')
|
if(suffix == '*')
|
||||||
|
@ -1019,6 +1151,31 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
// addAnim = false;
|
// addAnim = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(name.at(name.length() - 1))
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
triname = "tri chest";
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
triname = "tri tail";
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
triname = "tri left foot";
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
triname = "tri right foot";
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
triname = "tri left hand";
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
triname = "tri right hand";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
triname = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
//std::cout << "Flipping";
|
//std::cout << "Flipping";
|
||||||
|
@ -1070,7 +1227,11 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the node
|
// Handle the node
|
||||||
handleNode(node, 0, NULL, bounds, 0);
|
std::vector<std::string> boneSequence;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
handleNode(node, 0, NULL, bounds, 0, boneSequence);
|
||||||
|
|
||||||
// set the bounding value.
|
// set the bounding value.
|
||||||
if (bounds.isValid())
|
if (bounds.isValid())
|
||||||
|
|
|
@ -28,10 +28,39 @@
|
||||||
#include <OgreMesh.h>
|
#include <OgreMesh.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <Ogre.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <libs/mangle/vfs/servers/ogre_vfs.hpp>
|
||||||
|
#include "../nif/nif_file.hpp"
|
||||||
|
#include "../nif/node.hpp"
|
||||||
|
#include "../nif/data.hpp"
|
||||||
|
#include "../nif/property.hpp"
|
||||||
|
#include "../nif/controller.hpp"
|
||||||
|
#include "../nif/extra.hpp"
|
||||||
|
#include <libs/platform/strings.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
// For warning messages
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// float infinity
|
||||||
|
#include <limits>
|
||||||
|
using namespace boost::algorithm;
|
||||||
|
|
||||||
|
|
||||||
class BoundsFinder;
|
class BoundsFinder;
|
||||||
|
|
||||||
|
struct ciLessBoost : std::binary_function<std::string, std::string, bool>
|
||||||
|
{
|
||||||
|
bool operator() (const std::string & s1, const std::string & s2) const {
|
||||||
|
//case insensitive version of is_less
|
||||||
|
return lexicographical_compare(s1, s2, is_iless());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
class Node;
|
class Node;
|
||||||
|
@ -51,6 +80,7 @@ namespace Mangle
|
||||||
|
|
||||||
namespace NifOgre
|
namespace NifOgre
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/** Manual resource loader for NIF meshes. This is the main class
|
/** Manual resource loader for NIF meshes. This is the main class
|
||||||
responsible for translating the internal NIF mesh structure into
|
responsible for translating the internal NIF mesh structure into
|
||||||
|
@ -94,9 +124,9 @@ class NIFLoader : Ogre::ManualResourceLoader
|
||||||
void fail(std::string msg);
|
void fail(std::string msg);
|
||||||
|
|
||||||
void handleNode( Nif::Node *node, int flags,
|
void handleNode( Nif::Node *node, int flags,
|
||||||
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone);
|
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone, std::vector<std::string> boneSequence);
|
||||||
|
|
||||||
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds);
|
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds, Nif::Transformation original, std::vector<std::string> boneSequence);
|
||||||
|
|
||||||
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments);
|
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments);
|
||||||
|
|
||||||
|
@ -139,6 +169,14 @@ class NIFLoader : Ogre::ManualResourceLoader
|
||||||
Ogre::Mesh *mesh;
|
Ogre::Mesh *mesh;
|
||||||
Ogre::SkeletonPtr mSkel;
|
Ogre::SkeletonPtr mSkel;
|
||||||
Ogre::Vector3 vector;
|
Ogre::Vector3 vector;
|
||||||
|
std::vector<Nif::NiTriShapeCopy> shapes;
|
||||||
|
std::string name;
|
||||||
|
std::string triname;
|
||||||
|
std::vector<Nif::NiKeyframeData> allanim;
|
||||||
|
std::map<std::string,float> textmappings;
|
||||||
|
std::map<std::string,std::map<std::string,float>,ciLessBoost> alltextmappings;
|
||||||
|
std::map<std::string,std::vector<Nif::NiKeyframeData>,ciLessBoost> allanimmap;
|
||||||
|
std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost> allshapesmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue