mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-29 19:36:43 +00:00
Use Ogre types for Matrix and Vector objects
This commit is contained in:
parent
10072f74b4
commit
ca37706b34
10 changed files with 192 additions and 286 deletions
|
@ -97,7 +97,7 @@ class ShapeData : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<float> vertices, normals, colors, uvlist;
|
std::vector<float> vertices, normals, colors, uvlist;
|
||||||
Vector center;
|
Ogre::Vector3 center;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
|
@ -198,7 +198,7 @@ public:
|
||||||
// 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->skip(activeCount * 4*sizeof(float));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -244,7 +244,7 @@ public:
|
||||||
if(count)
|
if(count)
|
||||||
{
|
{
|
||||||
nif->getInt(); // always 2
|
nif->getInt(); // always 2
|
||||||
nif->getArrayLen<Vector4>(count); // Really one time float + one vector
|
nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Always 0
|
// Always 0
|
||||||
|
@ -260,7 +260,7 @@ public:
|
||||||
{
|
{
|
||||||
int count = nif->getInt();
|
int count = nif->getInt();
|
||||||
nif->getInt(); // always 2
|
nif->getInt(); // always 2
|
||||||
nif->getArrayLen<Vector4>(count); // Really one time float + one vector
|
nif->skip(count * (sizeof(float) + 3*sizeof(float))); // Really one time float + one vector
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ public:
|
||||||
struct ColorData
|
struct ColorData
|
||||||
{
|
{
|
||||||
float time;
|
float time;
|
||||||
Vector4 rgba;
|
Ogre::Vector4 rgba;
|
||||||
};
|
};
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
|
@ -318,25 +318,23 @@ public:
|
||||||
nif->getInt(); // always 1
|
nif->getInt(); // always 1
|
||||||
|
|
||||||
// Skip the data
|
// Skip the data
|
||||||
assert(sizeof(ColorData) == 4*5);
|
nif->skip(count * 5*sizeof(float));
|
||||||
nif->skip(sizeof(ColorData) * count);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NiVisData : public Record
|
class NiVisData : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct VisData {
|
||||||
|
float time;
|
||||||
|
char isSet;
|
||||||
|
};
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
int count = nif->getInt();
|
int count = nif->getInt();
|
||||||
/*
|
|
||||||
Each VisData consists of:
|
|
||||||
float time;
|
|
||||||
byte isSet;
|
|
||||||
|
|
||||||
If you implement this, make sure you use a packed struct
|
/* Skip VisData */
|
||||||
(sizeof==5), or read each element individually.
|
|
||||||
*/
|
|
||||||
nif->skip(count*5);
|
nif->skip(count*5);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -361,15 +359,10 @@ public:
|
||||||
class NiSkinData : public Record
|
class NiSkinData : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This is to make sure the structs are packed, ie. that the
|
|
||||||
// compiler doesn't mess them up with extra alignment bytes.
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
struct BoneTrafo
|
struct BoneTrafo
|
||||||
{
|
{
|
||||||
Matrix rotation; // Rotation offset from bone?
|
Ogre::Matrix3 rotation; // Rotation offset from bone?
|
||||||
Vector trans; // Translation
|
Ogre::Vector3 trans; // Translation
|
||||||
float scale; // Probably scale (always 1)
|
float scale; // Probably scale (always 1)
|
||||||
};
|
};
|
||||||
struct BoneTrafoCopy
|
struct BoneTrafoCopy
|
||||||
|
@ -384,12 +377,12 @@ public:
|
||||||
short vertex;
|
short vertex;
|
||||||
float weight;
|
float weight;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
struct BoneInfo
|
struct BoneInfo
|
||||||
{
|
{
|
||||||
BoneTrafo trafo;
|
BoneTrafo trafo;
|
||||||
Vector4 unknown;
|
Ogre::Vector4 unknown;
|
||||||
std::vector<VertWeight> weights;
|
std::vector<VertWeight> weights;
|
||||||
};
|
};
|
||||||
struct BoneInfoCopy
|
struct BoneInfoCopy
|
||||||
|
@ -397,7 +390,7 @@ public:
|
||||||
std::string bonename;
|
std::string bonename;
|
||||||
unsigned short bonehandle;
|
unsigned short bonehandle;
|
||||||
BoneTrafoCopy trafo;
|
BoneTrafoCopy trafo;
|
||||||
Vector4 unknown;
|
Ogre::Vector4 unknown;
|
||||||
//std::vector<VertWeight> weights;
|
//std::vector<VertWeight> weights;
|
||||||
};
|
};
|
||||||
struct IndividualWeight
|
struct IndividualWeight
|
||||||
|
@ -411,9 +404,6 @@ public:
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
assert(sizeof(BoneTrafo) == 4*(9+3+1));
|
|
||||||
assert(sizeof(VertWeight) == 6);
|
|
||||||
|
|
||||||
trafo.rotation = nif->getMatrix();
|
trafo.rotation = nif->getMatrix();
|
||||||
trafo.trans = nif->getVector();
|
trafo.trans = nif->getVector();
|
||||||
trafo.scale = nif->getFloat();
|
trafo.scale = nif->getFloat();
|
||||||
|
@ -432,8 +422,12 @@ public:
|
||||||
bi.unknown = nif->getVector4();
|
bi.unknown = nif->getVector4();
|
||||||
|
|
||||||
// Number of vertex weights
|
// Number of vertex weights
|
||||||
int count = nif->getShort();
|
bi.weights.resize(nif->getShort());
|
||||||
bi.weights = nif->getArrayLen<VertWeight>(count);
|
for(size_t j = 0;j < bi.weights.size();j++)
|
||||||
|
{
|
||||||
|
nif->load(bi.weights[j].vertex);
|
||||||
|
nif->load(bi.weights[j].weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,9 +38,9 @@ struct NiLight : Effect
|
||||||
struct SLight
|
struct SLight
|
||||||
{
|
{
|
||||||
float dimmer;
|
float dimmer;
|
||||||
Vector ambient;
|
Ogre::Vector3 ambient;
|
||||||
Vector diffuse;
|
Ogre::Vector3 diffuse;
|
||||||
Vector specular;
|
Ogre::Vector3 specular;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
#include <OgreResourceGroupManager.h>
|
#include <OgreResourceGroupManager.h>
|
||||||
#include <OgreDataStream.h>
|
#include <OgreDataStream.h>
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
#include <OgreVector4.h>
|
||||||
|
#include <OgreMatrix3.h>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -162,44 +165,31 @@ public:
|
||||||
|
|
||||||
|
|
||||||
template<typename X>
|
template<typename X>
|
||||||
std::vector<X> getArrayLen(size_t num)
|
std::vector<X> getArrayLen(size_t num);
|
||||||
{
|
|
||||||
std::vector<X> v(num);
|
|
||||||
if(inp->read(&v[0], num*sizeof(X)) != num*sizeof(X))
|
|
||||||
fail("Failed to read from NIF");
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename X>
|
|
||||||
std::vector<X> getArray()
|
|
||||||
{
|
|
||||||
size_t len = read_le32();
|
|
||||||
return getArrayLen<X>(len);
|
|
||||||
}
|
|
||||||
|
|
||||||
char getByte() { char c; return load(c); }
|
char getByte() { char c; return load(c); }
|
||||||
unsigned short getShort() { unsigned short s; return load(s); }
|
unsigned short getShort() { unsigned short s; return load(s); }
|
||||||
int getInt() { int i; return load(i); }
|
int getInt() { int i; return load(i); }
|
||||||
float getFloat() { float f; return load(f); }
|
float getFloat() { float f; return load(f); }
|
||||||
Vector getVector()
|
Ogre::Vector3 getVector()
|
||||||
{
|
{
|
||||||
Vector v;
|
float a[3];
|
||||||
load(v.array);
|
load(a);
|
||||||
return v;
|
return Ogre::Vector3(a);
|
||||||
}
|
}
|
||||||
Vector4 getVector4()
|
Ogre::Vector4 getVector4()
|
||||||
{
|
{
|
||||||
Vector4 v;
|
float a[4];
|
||||||
load(v.array);
|
load(a);
|
||||||
return v;
|
return Ogre::Vector4(a);
|
||||||
}
|
}
|
||||||
Matrix getMatrix()
|
Ogre::Matrix3 getMatrix()
|
||||||
{
|
{
|
||||||
Matrix m;
|
float a[3*3];
|
||||||
m.v[0] = getVector();
|
load(a);
|
||||||
m.v[1] = getVector();
|
return Ogre::Matrix3(Ogre::Real(a[0]), Ogre::Real(a[1]), Ogre::Real(a[2]),
|
||||||
m.v[2] = getVector();
|
Ogre::Real(a[3]), Ogre::Real(a[4]), Ogre::Real(a[5]),
|
||||||
return m;
|
Ogre::Real(a[6]), Ogre::Real(a[7]), Ogre::Real(a[8]));
|
||||||
}
|
}
|
||||||
Transformation getTrafo()
|
Transformation getTrafo()
|
||||||
{
|
{
|
||||||
|
@ -228,6 +218,15 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline std::vector<short> NIFFile::getArrayLen<short>(size_t num)
|
||||||
|
{
|
||||||
|
std::vector<short> v(num);
|
||||||
|
for(size_t i = 0;i < num;i++)
|
||||||
|
load(v[i]);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline std::vector<float> NIFFile::getArrayLen<float>(size_t num)
|
inline std::vector<float> NIFFile::getArrayLen<float>(size_t num)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,41 +24,20 @@
|
||||||
#ifndef _NIF_TYPES_H_
|
#ifndef _NIF_TYPES_H_
|
||||||
#define _NIF_TYPES_H_
|
#define _NIF_TYPES_H_
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
#include <OgreMatrix3.h>
|
||||||
|
|
||||||
// Common types used in NIF files
|
// Common types used in NIF files
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
/* These packing #pragmas aren't really necessary on 32 bit
|
|
||||||
machines. I haven't tested on 64 bit yet. In any case it doesn't
|
|
||||||
hurt to include them. We can't allow any compiler-generated padding
|
|
||||||
in any of these structs, since they are used to interface directly
|
|
||||||
with raw data from the NIF files.
|
|
||||||
*/
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
struct Vector
|
|
||||||
{
|
|
||||||
float array[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vector4
|
|
||||||
{
|
|
||||||
float array[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Matrix
|
|
||||||
{
|
|
||||||
Vector v[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Transformation
|
struct Transformation
|
||||||
{
|
{
|
||||||
Vector pos;
|
Ogre::Vector3 pos;
|
||||||
Matrix rotation;
|
Ogre::Matrix3 rotation;
|
||||||
float scale;
|
float scale;
|
||||||
Vector velocity;
|
Ogre::Vector3 velocity;
|
||||||
|
|
||||||
static const Transformation& getIdentity()
|
static const Transformation& getIdentity()
|
||||||
{
|
{
|
||||||
|
@ -67,16 +46,15 @@ struct Transformation
|
||||||
if (!iset)
|
if (!iset)
|
||||||
{
|
{
|
||||||
identity.scale = 1.0f;
|
identity.scale = 1.0f;
|
||||||
identity.rotation.v[0].array[0] = 1.0f;
|
identity.rotation[0][0] = 1.0f;
|
||||||
identity.rotation.v[1].array[1] = 1.0f;
|
identity.rotation[1][1] = 1.0f;
|
||||||
identity.rotation.v[2].array[2] = 1.0f;
|
identity.rotation[2][2] = 1.0f;
|
||||||
iset = true;
|
iset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,9 +47,9 @@ public:
|
||||||
|
|
||||||
// Bounding box info
|
// Bounding box info
|
||||||
bool hasBounds;
|
bool hasBounds;
|
||||||
Vector boundPos;
|
Ogre::Vector3 boundPos;
|
||||||
Matrix boundRot;
|
Ogre::Matrix3 boundRot;
|
||||||
Vector boundXYZ; // Box size
|
Ogre::Vector3 boundXYZ; // Box size
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,7 +167,7 @@ struct StructPropT : Property
|
||||||
struct S_MaterialProperty
|
struct S_MaterialProperty
|
||||||
{
|
{
|
||||||
// The vector components are R,G,B
|
// The vector components are R,G,B
|
||||||
Vector ambient, diffuse, specular, emissive;
|
Ogre::Vector3 ambient, diffuse, specular, emissive;
|
||||||
float glossiness, alpha;
|
float glossiness, alpha;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
|
|
|
@ -43,10 +43,6 @@ http://www.gnu.org/licenses/ .
|
||||||
|
|
||||||
typedef unsigned char ubyte;
|
typedef unsigned char ubyte;
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace Nif;
|
|
||||||
|
|
||||||
using namespace NifBullet;
|
using namespace NifBullet;
|
||||||
|
|
||||||
ManualBulletShapeLoader::~ManualBulletShapeLoader()
|
ManualBulletShapeLoader::~ManualBulletShapeLoader()
|
||||||
|
@ -55,18 +51,14 @@ ManualBulletShapeLoader::~ManualBulletShapeLoader()
|
||||||
|
|
||||||
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
|
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
|
||||||
{
|
{
|
||||||
Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2],
|
return tr->rotation;
|
||||||
tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2],
|
|
||||||
tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]);
|
|
||||||
return rot;
|
|
||||||
}
|
}
|
||||||
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
|
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]);
|
return tr->pos;
|
||||||
return vect3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m)
|
btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m)
|
||||||
{
|
{
|
||||||
Ogre::Quaternion oquat(m);
|
Ogre::Quaternion oquat(m);
|
||||||
btQuaternion quat;
|
btQuaternion quat;
|
||||||
|
@ -77,10 +69,9 @@ btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m)
|
||||||
return quat;
|
return quat;
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v)
|
btVector3 ManualBulletShapeLoader::getbtVector(Ogre::Vector3 &v)
|
||||||
{
|
{
|
||||||
btVector3 a(v.array[0],v.array[1],v.array[2]);
|
return btVector3(v[0], v[1], v[2]);
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
|
@ -108,7 +99,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
assert(r != NULL);
|
assert(r != NULL);
|
||||||
|
|
||||||
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
|
Nif::Node *node = dynamic_cast<Nif::Node*>(r);
|
||||||
|
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
warn("First record in file was not a node, but a " +
|
warn("First record in file was not a node, but a " +
|
||||||
|
|
|
@ -46,8 +46,6 @@ namespace Nif
|
||||||
class Node;
|
class Node;
|
||||||
class Transformation;
|
class Transformation;
|
||||||
class NiTriShape;
|
class NiTriShape;
|
||||||
class Vector;
|
|
||||||
class Matrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NifBullet
|
namespace NifBullet
|
||||||
|
@ -91,9 +89,9 @@ private:
|
||||||
|
|
||||||
Ogre::Vector3 getVector(Nif::Transformation* tr);
|
Ogre::Vector3 getVector(Nif::Transformation* tr);
|
||||||
|
|
||||||
btQuaternion getbtQuat(Ogre::Matrix3 m);
|
btQuaternion getbtQuat(Ogre::Matrix3 &m);
|
||||||
|
|
||||||
btVector3 getbtVector(Nif::Vector v);
|
btVector3 getbtVector(Ogre::Vector3 &v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Parse a node.
|
*Parse a node.
|
||||||
|
|
|
@ -39,9 +39,7 @@
|
||||||
typedef unsigned char ubyte;
|
typedef unsigned char ubyte;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Ogre;
|
|
||||||
using namespace Nif;
|
using namespace Nif;
|
||||||
using namespace Mangle::VFS;
|
|
||||||
using namespace Misc;
|
using namespace Misc;
|
||||||
using namespace NifOgre;
|
using namespace NifOgre;
|
||||||
|
|
||||||
|
@ -67,21 +65,6 @@ void NIFLoader::fail(string msg)
|
||||||
assert(1);
|
assert(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 NIFLoader::convertVector3(const Nif::Vector& vec)
|
|
||||||
{
|
|
||||||
return Ogre::Vector3(vec.array);
|
|
||||||
}
|
|
||||||
|
|
||||||
Quaternion NIFLoader::convertRotation(const Nif::Matrix& rot)
|
|
||||||
{
|
|
||||||
Real matrix[3][3];
|
|
||||||
|
|
||||||
for (int i=0; i<3; i++)
|
|
||||||
for (int j=0; j<3; j++)
|
|
||||||
matrix[i][j] = rot.v[i].array[j];
|
|
||||||
|
|
||||||
return Quaternion(Matrix3(matrix));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper class that computes the bounding box and of a mesh
|
// Helper class that computes the bounding box and of a mesh
|
||||||
class BoundsFinder
|
class BoundsFinder
|
||||||
|
@ -217,16 +200,16 @@ void NIFLoader::setOutputAnimFiles(bool output){
|
||||||
void NIFLoader::setVerbosePath(std::string path){
|
void NIFLoader::setVerbosePath(std::string path){
|
||||||
verbosePath = path;
|
verbosePath = path;
|
||||||
}
|
}
|
||||||
void NIFLoader::createMaterial(const String &name,
|
void NIFLoader::createMaterial(const Ogre::String &name,
|
||||||
const Vector &ambient,
|
const Ogre::Vector3 &ambient,
|
||||||
const Vector &diffuse,
|
const Ogre::Vector3 &diffuse,
|
||||||
const Vector &specular,
|
const Ogre::Vector3 &specular,
|
||||||
const Vector &emissive,
|
const Ogre::Vector3 &emissive,
|
||||||
float glossiness, float alpha,
|
float glossiness, float alpha,
|
||||||
int alphaFlags, float alphaTest,
|
int alphaFlags, float alphaTest,
|
||||||
const String &texName)
|
const Ogre::String &texName)
|
||||||
{
|
{
|
||||||
MaterialPtr material = MaterialManager::getSingleton().create(name, resourceGroup);
|
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(name, resourceGroup);
|
||||||
|
|
||||||
|
|
||||||
//Hardware Skinning code, textures may be the wrong color if enabled
|
//Hardware Skinning code, textures may be the wrong color if enabled
|
||||||
|
@ -249,11 +232,11 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
|
|
||||||
if (!texName.empty())
|
if (!texName.empty())
|
||||||
{
|
{
|
||||||
Pass *pass = material->getTechnique(0)->getPass(0);
|
Ogre::Pass *pass = material->getTechnique(0)->getPass(0);
|
||||||
/*TextureUnitState *txt =*/
|
/*TextureUnitState *txt =*/
|
||||||
pass->createTextureUnitState(texName);
|
pass->createTextureUnitState(texName);
|
||||||
|
|
||||||
pass->setVertexColourTracking(TVC_DIFFUSE);
|
pass->setVertexColourTracking(Ogre::TVC_DIFFUSE);
|
||||||
|
|
||||||
// As of yet UNTESTED code from Chris:
|
// As of yet UNTESTED code from Chris:
|
||||||
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
|
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
|
||||||
|
@ -294,13 +277,13 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
||||||
if (result.first)
|
if (result.first)
|
||||||
{
|
{
|
||||||
pass->setAlphaRejectFunction(CMPF_GREATER_EQUAL);
|
pass->setAlphaRejectFunction(Ogre::CMPF_GREATER_EQUAL);
|
||||||
pass->setAlphaRejectValue(result.second);
|
pass->setAlphaRejectValue(result.second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Enable transparency
|
// Enable transparency
|
||||||
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
|
||||||
|
|
||||||
//pass->setDepthCheckEnabled(false);
|
//pass->setDepthCheckEnabled(false);
|
||||||
pass->setDepthWriteEnabled(false);
|
pass->setDepthWriteEnabled(false);
|
||||||
|
@ -322,11 +305,11 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
const int numsplits = 3;
|
const int numsplits = 3;
|
||||||
for (int i = 0; i < (split ? numsplits : 1); ++i)
|
for (int i = 0; i < (split ? numsplits : 1); ++i)
|
||||||
{
|
{
|
||||||
TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState();
|
Ogre::TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState();
|
||||||
tu->setName("shadowMap" + StringConverter::toString(i));
|
tu->setName("shadowMap" + Ogre::StringConverter::toString(i));
|
||||||
tu->setContentType(TextureUnitState::CONTENT_SHADOW);
|
tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
|
||||||
tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
|
tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
|
||||||
tu->setTextureBorderColour(ColourValue::White);
|
tu->setTextureBorderColour(Ogre::ColourValue::White);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,11 +322,11 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a fallback technique without shadows and without mrt
|
// Create a fallback technique without shadows and without mrt
|
||||||
Technique* tech2 = material->createTechnique();
|
Ogre::Technique* tech2 = material->createTechnique();
|
||||||
tech2->setSchemeName("Fallback");
|
tech2->setSchemeName("Fallback");
|
||||||
Pass* pass2 = tech2->createPass();
|
Ogre::Pass* pass2 = tech2->createPass();
|
||||||
pass2->createTextureUnitState(texName);
|
pass2->createTextureUnitState(texName);
|
||||||
pass2->setVertexColourTracking(TVC_DIFFUSE);
|
pass2->setVertexColourTracking(Ogre::TVC_DIFFUSE);
|
||||||
if (Settings::Manager::getBool("shaders", "Objects"))
|
if (Settings::Manager::getBool("shaders", "Objects"))
|
||||||
{
|
{
|
||||||
pass2->setVertexProgram("main_fallback_vp");
|
pass2->setVertexProgram("main_fallback_vp");
|
||||||
|
@ -352,16 +335,16 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add material bells and whistles
|
// Add material bells and whistles
|
||||||
material->setAmbient(ambient.array[0], ambient.array[1], ambient.array[2]);
|
material->setAmbient(ambient[0], ambient[1], ambient[2]);
|
||||||
material->setDiffuse(diffuse.array[0], diffuse.array[1], diffuse.array[2], alpha);
|
material->setDiffuse(diffuse[0], diffuse[1], diffuse[2], alpha);
|
||||||
material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha);
|
material->setSpecular(specular[0], specular[1], specular[2], alpha);
|
||||||
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
|
material->setSelfIllumination(emissive[0], emissive[1], emissive[2]);
|
||||||
material->setShininess(glossiness);
|
material->setShininess(glossiness);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a name and adds a unique part to it. This is just used to
|
// Takes a name and adds a unique part to it. This is just used to
|
||||||
// make sure that all materials are given unique names.
|
// make sure that all materials are given unique names.
|
||||||
String NIFLoader::getUniqueName(const String &input)
|
Ogre::String NIFLoader::getUniqueName(const Ogre::String &input)
|
||||||
{
|
{
|
||||||
static int addon = 0;
|
static int addon = 0;
|
||||||
static char buf[8];
|
static char buf[8];
|
||||||
|
@ -377,13 +360,13 @@ String NIFLoader::getUniqueName(const String &input)
|
||||||
// does not, change the string IN PLACE to say .dds instead and try
|
// does not, change the string IN PLACE to say .dds instead and try
|
||||||
// that. The texture may still not exist, but no information of value
|
// that. The texture may still not exist, but no information of value
|
||||||
// is lost in that case.
|
// is lost in that case.
|
||||||
void NIFLoader::findRealTexture(String &texName)
|
void NIFLoader::findRealTexture(Ogre::String &texName)
|
||||||
{
|
{
|
||||||
if(Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
|
if(Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Change texture extension to .dds
|
// Change texture extension to .dds
|
||||||
String::size_type pos = texName.rfind('.');
|
Ogre::String::size_type pos = texName.rfind('.');
|
||||||
texName.replace(pos, texName.length(), ".dds");
|
texName.replace(pos, texName.length(), ".dds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,11 +374,11 @@ void NIFLoader::findRealTexture(String &texName)
|
||||||
|
|
||||||
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
|
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given
|
||||||
// mesh.
|
// mesh.
|
||||||
void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments)
|
void NIFLoader::createOgreSubMesh(NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments)
|
||||||
{
|
{
|
||||||
// cout << "s:" << shape << "\n";
|
// cout << "s:" << shape << "\n";
|
||||||
NiTriShapeData *data = shape->data.getPtr();
|
NiTriShapeData *data = shape->data.getPtr();
|
||||||
SubMesh *sub = mesh->createSubMesh(shape->name);
|
Ogre::SubMesh *sub = mesh->createSubMesh(shape->name);
|
||||||
|
|
||||||
int nextBuf = 0;
|
int nextBuf = 0;
|
||||||
|
|
||||||
|
@ -404,17 +387,17 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
// Add vertices
|
// Add vertices
|
||||||
int numVerts = data->vertices.size() / 3;
|
int numVerts = data->vertices.size() / 3;
|
||||||
sub->vertexData = new VertexData();
|
sub->vertexData = new Ogre::VertexData();
|
||||||
sub->vertexData->vertexCount = numVerts;
|
sub->vertexData->vertexCount = numVerts;
|
||||||
sub->useSharedVertices = false;
|
sub->useSharedVertices = false;
|
||||||
|
|
||||||
VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
|
Ogre::VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
|
||||||
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);
|
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
|
||||||
|
|
||||||
HardwareVertexBufferSharedPtr vbuf =
|
Ogre::HardwareVertexBufferSharedPtr vbuf =
|
||||||
HardwareBufferManager::getSingleton().createVertexBuffer(
|
Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
VertexElement::getTypeSize(VET_FLOAT3),
|
Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
|
||||||
numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
|
numVerts, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
|
@ -440,19 +423,19 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
|
Ogre::VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
|
|
||||||
if (data->normals.size())
|
if (data->normals.size())
|
||||||
{
|
{
|
||||||
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
|
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
|
||||||
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
|
vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
VertexElement::getTypeSize(VET_FLOAT3),
|
Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
|
||||||
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
|
numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
Quaternion rotation = mTransform.extractQuaternion();
|
Ogre::Quaternion rotation = mTransform.extractQuaternion();
|
||||||
rotation.normalise();
|
rotation.normalise();
|
||||||
|
|
||||||
float *datamod = new float[data->normals.size()];
|
float *datamod = new float[data->normals.size()];
|
||||||
|
@ -487,19 +470,19 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
if (data->colors.size())
|
if (data->colors.size())
|
||||||
{
|
{
|
||||||
const float *colors = &data->colors[0];
|
const float *colors = &data->colors[0];
|
||||||
RenderSystem* rs = Root::getSingleton().getRenderSystem();
|
Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
|
||||||
std::vector<RGBA> colorsRGB(numVerts);
|
std::vector<Ogre::RGBA> colorsRGB(numVerts);
|
||||||
RGBA *pColour = &colorsRGB.front();
|
Ogre::RGBA *pColour = &colorsRGB.front();
|
||||||
for (int i=0; i<numVerts; i++)
|
for (int i=0; i<numVerts; i++)
|
||||||
{
|
{
|
||||||
rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2],
|
rs->convertColourValue(Ogre::ColourValue(colors[0],colors[1],colors[2],
|
||||||
colors[3]),pColour++);
|
colors[3]),pColour++);
|
||||||
colors += 4;
|
colors += 4;
|
||||||
}
|
}
|
||||||
decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE);
|
decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
|
||||||
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
|
vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
VertexElement::getTypeSize(VET_COLOUR),
|
Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
|
||||||
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
|
||||||
vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true);
|
vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true);
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
}
|
}
|
||||||
|
@ -507,10 +490,10 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
if (data->uvlist.size())
|
if (data->uvlist.size())
|
||||||
{
|
{
|
||||||
|
|
||||||
decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
|
decl->addElement(nextBuf, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
|
||||||
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
|
vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
VertexElement::getTypeSize(VET_FLOAT2),
|
Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2),
|
||||||
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false);
|
numVerts, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,false);
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
|
@ -539,24 +522,23 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
sub->indexData->indexCount = numFaces;
|
sub->indexData->indexCount = numFaces;
|
||||||
sub->indexData->indexStart = 0;
|
sub->indexData->indexStart = 0;
|
||||||
HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
|
Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
|
||||||
createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
|
createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, numFaces,
|
||||||
numFaces,
|
Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
|
||||||
HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);
|
|
||||||
|
|
||||||
if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){
|
if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){
|
||||||
|
|
||||||
sub->indexData->indexBuffer = ibuf;
|
sub->indexData->indexBuffer = ibuf;
|
||||||
|
|
||||||
uint16 *datamod = new uint16[numFaces];
|
uint16_t *datamod = new uint16_t[numFaces];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (size_t i = 0; i < sub->indexData->indexCount; i+=3)
|
for (size_t i = 0; i < sub->indexData->indexCount; i+=3)
|
||||||
{
|
{
|
||||||
|
|
||||||
const short *pos = &data->triangles[index];
|
const short *pos = &data->triangles[index];
|
||||||
uint16 i0 = (uint16) *(pos+0);
|
uint16_t i0 = (uint16_t) *(pos+0);
|
||||||
uint16 i1 = (uint16) *(pos+1);
|
uint16_t i1 = (uint16_t) *(pos+1);
|
||||||
uint16 i2 = (uint16) *(pos+2);
|
uint16_t i2 = (uint16_t) *(pos+2);
|
||||||
|
|
||||||
//std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n";
|
//std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n";
|
||||||
|
|
||||||
|
@ -582,7 +564,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
//add vertex bone assignments
|
//add vertex bone assignments
|
||||||
|
|
||||||
for (std::list<VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin();
|
for (std::list<Ogre::VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin();
|
||||||
it != vertexBoneAssignments.end(); it++)
|
it != vertexBoneAssignments.end(); it++)
|
||||||
{
|
{
|
||||||
sub->addBoneAssignment(*it);
|
sub->addBoneAssignment(*it);
|
||||||
|
@ -593,23 +575,8 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
// Helper math functions. Reinventing linear algebra for the win!
|
// Helper math functions. Reinventing linear algebra for the win!
|
||||||
|
|
||||||
// Computes B = AxB (matrix*matrix)
|
|
||||||
static void matrixMul(const Matrix &A, Matrix &B)
|
|
||||||
{
|
|
||||||
for (int i=0;i<3;i++)
|
|
||||||
{
|
|
||||||
float a = B.v[0].array[i];
|
|
||||||
float b = B.v[1].array[i];
|
|
||||||
float c = B.v[2].array[i];
|
|
||||||
|
|
||||||
B.v[0].array[i] = a*A.v[0].array[0] + b*A.v[0].array[1] + c*A.v[0].array[2];
|
|
||||||
B.v[1].array[i] = a*A.v[1].array[0] + b*A.v[1].array[1] + c*A.v[1].array[2];
|
|
||||||
B.v[2].array[i] = a*A.v[2].array[0] + b*A.v[2].array[1] + c*A.v[2].array[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Computes C = B + AxC*scale
|
// Computes C = B + AxC*scale
|
||||||
static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale)
|
static void vectorMulAdd(const Ogre::Matrix3 &A, const Ogre::Vector3 &B, float *C, float scale)
|
||||||
{
|
{
|
||||||
// Keep the original values
|
// Keep the original values
|
||||||
float a = C[0];
|
float a = C[0];
|
||||||
|
@ -618,11 +585,11 @@ static void vectorMulAdd(const Matrix &A, const Vector &B, float *C, float scale
|
||||||
|
|
||||||
// Perform matrix multiplication, scaling and addition
|
// Perform matrix multiplication, scaling and addition
|
||||||
for (int i=0;i<3;i++)
|
for (int i=0;i<3;i++)
|
||||||
C[i] = B.array[i] + (a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2])*scale;
|
C[i] = B[i] + (a*A[i][0] + b*A[i][1] + c*A[i][2])*scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes B = AxB (matrix*vector)
|
// Computes B = AxB (matrix*vector)
|
||||||
static void vectorMul(const Matrix &A, float *C)
|
static void vectorMul(const Ogre::Matrix3 &A, float *C)
|
||||||
{
|
{
|
||||||
// Keep the original values
|
// Keep the original values
|
||||||
float a = C[0];
|
float a = C[0];
|
||||||
|
@ -631,7 +598,7 @@ static void vectorMul(const Matrix &A, float *C)
|
||||||
|
|
||||||
// Perform matrix multiplication, scaling and addition
|
// Perform matrix multiplication, scaling and addition
|
||||||
for (int i=0;i<3;i++)
|
for (int i=0;i<3;i++)
|
||||||
C[i] = a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2];
|
C[i] = a*A[i][0] + b*A[i][1] + c*A[i][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -666,7 +633,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Material name for this submesh, if any
|
// Material name for this submesh, if any
|
||||||
String material;
|
Ogre::String material;
|
||||||
|
|
||||||
// Skip the entire material phase for hidden nodes
|
// Skip the entire material phase for hidden nodes
|
||||||
if (!hidden)
|
if (!hidden)
|
||||||
|
@ -695,7 +662,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
}
|
}
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
String texName;
|
Ogre::String texName;
|
||||||
if (t && t->textures[0].inUse)
|
if (t && t->textures[0].inUse)
|
||||||
{
|
{
|
||||||
NiSourceTexture *st = t->textures[0].texture.getPtr();
|
NiSourceTexture *st = t->textures[0].texture.getPtr();
|
||||||
|
@ -768,14 +735,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
{
|
{
|
||||||
// We only have a texture name. Create a default
|
// We only have a texture name. Create a default
|
||||||
// material for it.
|
// material for it.
|
||||||
Vector zero, one;
|
const Ogre::Vector3 zero(0.0f), one(1.0f);
|
||||||
for (int i=0; i<3;i++)
|
createMaterial(material, one, one, zero, zero, 0.0f, 1.0f,
|
||||||
{
|
|
||||||
zero.array[i] = 0.0;
|
|
||||||
one.array[i] = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
createMaterial(material, one, one, zero, zero, 0.0, 1.0,
|
|
||||||
alphaFlags, alphaTest, texName);
|
alphaFlags, alphaTest, texName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,7 +754,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
float *ptr = (float*)&data->vertices[0];
|
float *ptr = (float*)&data->vertices[0];
|
||||||
float *optr = ptr;
|
float *optr = ptr;
|
||||||
|
|
||||||
std::list<VertexBoneAssignment> vertexBoneAssignments;
|
std::list<Ogre::VertexBoneAssignment> vertexBoneAssignments;
|
||||||
|
|
||||||
Nif::NiTriShapeCopy copy = shape->clone();
|
Nif::NiTriShapeCopy copy = shape->clone();
|
||||||
|
|
||||||
|
@ -826,9 +787,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
//the first one contains a link to the bone, the second vertex transformation
|
//the first one contains a link to the bone, the second vertex transformation
|
||||||
//relative to the bone
|
//relative to the bone
|
||||||
int boneIndex = 0;
|
int boneIndex = 0;
|
||||||
Bone *bonePtr;
|
Ogre::Bone *bonePtr;
|
||||||
Vector3 vecPos;
|
Ogre::Vector3 vecPos;
|
||||||
Quaternion vecRot;
|
Ogre::Quaternion vecRot;
|
||||||
|
|
||||||
std::vector<NiSkinData::BoneInfo> boneList = shape->skin->data->bones;
|
std::vector<NiSkinData::BoneInfo> boneList = shape->skin->data->bones;
|
||||||
|
|
||||||
|
@ -854,17 +815,17 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
|
|
||||||
Nif::NiSkinData::BoneInfoCopy boneinfocopy;
|
Nif::NiSkinData::BoneInfoCopy boneinfocopy;
|
||||||
boneinfocopy.trafo.rotation = convertRotation(it->trafo.rotation);
|
boneinfocopy.trafo.rotation = it->trafo.rotation;
|
||||||
boneinfocopy.trafo.trans = convertVector3(it->trafo.trans);
|
boneinfocopy.trafo.trans = it->trafo.trans;
|
||||||
boneinfocopy.bonename = shape->skin->bones[boneIndex].name;
|
boneinfocopy.bonename = shape->skin->bones[boneIndex].name;
|
||||||
boneinfocopy.bonehandle = bonePtr->getHandle();
|
boneinfocopy.bonehandle = bonePtr->getHandle();
|
||||||
copy.boneinfo.push_back(boneinfocopy);
|
copy.boneinfo.push_back(boneinfocopy);
|
||||||
for (unsigned int i=0; i<it->weights.size(); i++)
|
for (unsigned int i=0; i<it->weights.size(); i++)
|
||||||
{
|
{
|
||||||
vecPos = bonePtr->_getDerivedPosition() +
|
vecPos = bonePtr->_getDerivedPosition() +
|
||||||
bonePtr->_getDerivedOrientation() * convertVector3(it->trafo.trans);
|
bonePtr->_getDerivedOrientation() * it->trafo.trans;
|
||||||
|
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo.rotation);
|
vecRot = bonePtr->_getDerivedOrientation() * it->trafo.rotation;
|
||||||
unsigned int verIndex = it->weights[i].vertex;
|
unsigned int verIndex = it->weights[i].vertex;
|
||||||
//boneinfo.weights.push_back(*(it->weights.ptr + i));
|
//boneinfo.weights.push_back(*(it->weights.ptr + i));
|
||||||
Nif::NiSkinData::IndividualWeight ind;
|
Nif::NiSkinData::IndividualWeight ind;
|
||||||
|
@ -885,9 +846,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
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);
|
Ogre::Vector3 absVertPos = vecPos + vecRot * Ogre::Vector3(ptr + verIndex *3);
|
||||||
absVertPos = absVertPos * it->weights[i].weight;
|
absVertPos = absVertPos * it->weights[i].weight;
|
||||||
vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3);
|
vertexPosOriginal[verIndex] = Ogre::Vector3(ptr + verIndex *3);
|
||||||
|
|
||||||
mBoundingBox.merge(absVertPos);
|
mBoundingBox.merge(absVertPos);
|
||||||
//convert it back to float *
|
//convert it back to float *
|
||||||
|
@ -898,9 +859,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
//FIXME: I guessed that vertex[i] = normal[i], is that true?
|
//FIXME: I guessed that vertex[i] = normal[i], is that true?
|
||||||
if (verIndex < data->normals.size())
|
if (verIndex < data->normals.size())
|
||||||
{
|
{
|
||||||
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
|
Ogre::Vector3 absNormalsPos = vecRot * Ogre::Vector3(ptrNormals + verIndex *3);
|
||||||
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
||||||
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3);
|
vertexNormalOriginal[verIndex] = Ogre::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];
|
||||||
|
@ -910,9 +871,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
|
Ogre::Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
|
||||||
absVertPos = absVertPos * it->weights[i].weight;
|
absVertPos = absVertPos * it->weights[i].weight;
|
||||||
Vector3 old = Vector3(ptr + verIndex *3);
|
Ogre::Vector3 old = Ogre::Vector3(ptr + verIndex *3);
|
||||||
absVertPos = absVertPos + old;
|
absVertPos = absVertPos + old;
|
||||||
|
|
||||||
mBoundingBox.merge(absVertPos);
|
mBoundingBox.merge(absVertPos);
|
||||||
|
@ -924,9 +885,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
//FIXME: I guessed that vertex[i] = normal[i], is that true?
|
//FIXME: I guessed that vertex[i] = normal[i], is that true?
|
||||||
if (verIndex < data->normals.size())
|
if (verIndex < data->normals.size())
|
||||||
{
|
{
|
||||||
Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
|
Ogre::Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
|
||||||
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
||||||
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3);
|
Ogre::Vector3 oldNormal = Ogre::Vector3(ptrNormals + verIndex *3);
|
||||||
absNormalsPos = absNormalsPos + oldNormal;
|
absNormalsPos = absNormalsPos + oldNormal;
|
||||||
|
|
||||||
for (int j=0; j<3; j++)
|
for (int j=0; j<3; j++)
|
||||||
|
@ -935,7 +896,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexBoneAssignment vba;
|
Ogre::VertexBoneAssignment vba;
|
||||||
vba.boneIndex = bonePtr->getHandle();
|
vba.boneIndex = bonePtr->getHandle();
|
||||||
vba.vertexIndex = verIndex;
|
vba.vertexIndex = verIndex;
|
||||||
vba.weight = it->weights[i].weight;
|
vba.weight = it->weights[i].weight;
|
||||||
|
@ -955,12 +916,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
copy.boneSequence = boneSequence;
|
copy.boneSequence = boneSequence;
|
||||||
// Rotate, scale and translate all the vertices,
|
// Rotate, scale and translate all the vertices,
|
||||||
const Matrix &rot = shape->trafo.rotation;
|
const Ogre::Matrix3 &rot = shape->trafo.rotation;
|
||||||
const Vector &pos = shape->trafo.pos;
|
const Ogre::Vector3 &pos = shape->trafo.pos;
|
||||||
float scale = shape->trafo.scale;
|
float scale = shape->trafo.scale;
|
||||||
|
|
||||||
copy.trafo.trans = convertVector3(original.pos);
|
copy.trafo.trans = original.pos;
|
||||||
copy.trafo.rotation = convertRotation(original.rotation);
|
copy.trafo.rotation = original.rotation;
|
||||||
copy.trafo.scale = original.scale;
|
copy.trafo.scale = original.scale;
|
||||||
//We don't use velocity for anything yet, so it does not need to be saved
|
//We don't use velocity for anything yet, so it does not need to be saved
|
||||||
|
|
||||||
|
@ -988,7 +949,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
boneIndex = mSkel->getNumBones() - 1;
|
boneIndex = mSkel->getNumBones() - 1;
|
||||||
for(int i = 0; i < numVerts; i++){
|
for(int i = 0; i < numVerts; i++){
|
||||||
VertexBoneAssignment vba;
|
Ogre::VertexBoneAssignment vba;
|
||||||
vba.boneIndex = boneIndex;
|
vba.boneIndex = boneIndex;
|
||||||
vba.vertexIndex = i;
|
vba.vertexIndex = i;
|
||||||
vba.weight = 1;
|
vba.weight = 1;
|
||||||
|
@ -1012,15 +973,15 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
void NIFLoader::calculateTransform()
|
void NIFLoader::calculateTransform()
|
||||||
{
|
{
|
||||||
// Calculate transform
|
// Calculate transform
|
||||||
Matrix4 transform = Matrix4::IDENTITY;
|
Ogre::Matrix4 transform = Ogre::Matrix4::IDENTITY;
|
||||||
transform = Matrix4::getScale(vector) * transform;
|
transform = Ogre::Matrix4::getScale(vector) * transform;
|
||||||
|
|
||||||
// Check whether we have to flip vertex winding.
|
// Check whether we have to flip vertex winding.
|
||||||
// We do have to, if we changed our right hand base.
|
// We do have to, if we changed our right hand base.
|
||||||
// We can test it by using the cross product from X and Y and see, if it is a non-negative
|
// We can test it by using the cross product from X and Y and see, if it is a non-negative
|
||||||
// projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet,
|
// projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet,
|
||||||
// but the test is cheap either way.
|
// but the test is cheap either way.
|
||||||
Matrix3 m3;
|
Ogre::Matrix3 m3;
|
||||||
transform.extract3x3Matrix(m3);
|
transform.extract3x3Matrix(m3);
|
||||||
|
|
||||||
if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
|
if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
|
||||||
|
@ -1114,7 +1075,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bone *bone = 0;
|
Ogre::Bone *bone = 0;
|
||||||
|
|
||||||
// create skeleton or add bones
|
// create skeleton or add bones
|
||||||
if (node->recType == RC_NiNode)
|
if (node->recType == RC_NiNode)
|
||||||
|
@ -1124,7 +1085,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
{
|
{
|
||||||
inTheSkeletonTree = true;
|
inTheSkeletonTree = true;
|
||||||
|
|
||||||
mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
|
mSkel = Ogre::SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
|
||||||
}
|
}
|
||||||
else if (!mSkel.isNull() && !parentBone)
|
else if (!mSkel.isNull() && !parentBone)
|
||||||
inTheSkeletonTree = false;
|
inTheSkeletonTree = false;
|
||||||
|
@ -1144,8 +1105,8 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
parentBone->addChild(bone);
|
parentBone->addChild(bone);
|
||||||
|
|
||||||
bone->setInheritOrientation(true);
|
bone->setInheritOrientation(true);
|
||||||
bone->setPosition(convertVector3(node->trafo.pos));
|
bone->setPosition(node->trafo.pos);
|
||||||
bone->setOrientation(convertRotation(node->trafo.rotation));
|
bone->setOrientation(node->trafo.rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1160,14 +1121,13 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
|
|
||||||
// For both position and rotation we have that:
|
// For both position and rotation we have that:
|
||||||
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
||||||
vectorMulAdd(trafo->rotation, trafo->pos, final.pos.array, trafo->scale);
|
final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale;
|
||||||
vectorMulAdd(trafo->rotation, trafo->velocity, final.velocity.array, trafo->scale);
|
final.velocity = trafo->velocity + trafo->rotation*final.velocity*trafo->scale;
|
||||||
|
|
||||||
// Merge the rotations together
|
// Merge the rotations together
|
||||||
matrixMul(trafo->rotation, final.rotation);
|
final.rotation = trafo->rotation * final.rotation;
|
||||||
|
|
||||||
// Scalar values are so nice to deal with. Why can't everything
|
// Scale
|
||||||
// just be scalar?
|
|
||||||
final.scale *= trafo->scale;
|
final.scale *= trafo->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,7 +1160,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NIFLoader::loadResource(Resource *resource)
|
void NIFLoader::loadResource(Ogre::Resource *resource)
|
||||||
{
|
{
|
||||||
inTheSkeletonTree = false;
|
inTheSkeletonTree = false;
|
||||||
allanim.clear();
|
allanim.clear();
|
||||||
|
@ -1287,7 +1247,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
calculateTransform();
|
calculateTransform();
|
||||||
}
|
}
|
||||||
// Get the mesh
|
// Get the mesh
|
||||||
mesh = dynamic_cast<Mesh*>(resource);
|
mesh = dynamic_cast<Ogre::Mesh*>(resource);
|
||||||
assert(mesh);
|
assert(mesh);
|
||||||
|
|
||||||
// Look it up
|
// Look it up
|
||||||
|
@ -1352,7 +1312,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
// set the bounding value.
|
// set the bounding value.
|
||||||
if (bounds.isValid())
|
if (bounds.isValid())
|
||||||
{
|
{
|
||||||
mesh->_setBounds(AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(),
|
mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(),
|
||||||
bounds.maxX(), bounds.maxY(), bounds.maxZ()));
|
bounds.maxX(), bounds.maxY(), bounds.maxZ()));
|
||||||
mesh->_setBoundingSphereRadius(bounds.getRadius());
|
mesh->_setBoundingSphereRadius(bounds.getRadius());
|
||||||
}
|
}
|
||||||
|
@ -1375,7 +1335,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
for(std::vector<Ogre::SubMesh*>::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++)
|
for(std::vector<Ogre::SubMesh*>::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++)
|
||||||
{
|
{
|
||||||
int boneIndex = mSkel->getNumBones() - 1;
|
int boneIndex = mSkel->getNumBones() - 1;
|
||||||
VertexBoneAssignment vba;
|
Ogre::VertexBoneAssignment vba;
|
||||||
vba.boneIndex = boneIndex;
|
vba.boneIndex = boneIndex;
|
||||||
vba.vertexIndex = 0;
|
vba.vertexIndex = 0;
|
||||||
vba.weight = 1;
|
vba.weight = 1;
|
||||||
|
@ -1394,20 +1354,19 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MeshPtr NIFLoader::load(const std::string &name,
|
Ogre::MeshPtr NIFLoader::load(const std::string &name, const std::string &group)
|
||||||
const std::string &group)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
MeshManager *m = MeshManager::getSingletonPtr();
|
Ogre::MeshManager *m = Ogre::MeshManager::getSingletonPtr();
|
||||||
// Check if the resource already exists
|
// Check if the resource already exists
|
||||||
ResourcePtr ptr = m->getByName(name, group);
|
Ogre::ResourcePtr ptr = m->getByName(name, group);
|
||||||
MeshPtr themesh;
|
Ogre::MeshPtr themesh;
|
||||||
if (!ptr.isNull()){
|
if (!ptr.isNull()){
|
||||||
themesh = MeshPtr(ptr);
|
themesh = Ogre::MeshPtr(ptr);
|
||||||
}
|
}
|
||||||
else // Nope, create a new one.
|
else // Nope, create a new one.
|
||||||
{
|
{
|
||||||
themesh = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr());
|
themesh = Ogre::MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr());
|
||||||
}
|
}
|
||||||
return themesh;
|
return themesh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,17 +62,8 @@ namespace Nif
|
||||||
class Node;
|
class Node;
|
||||||
class Transformation;
|
class Transformation;
|
||||||
class NiTriShape;
|
class NiTriShape;
|
||||||
class Vector;
|
|
||||||
class Matrix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Mangle
|
|
||||||
{
|
|
||||||
namespace VFS
|
|
||||||
{
|
|
||||||
class OgreVFS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace NifOgre
|
namespace NifOgre
|
||||||
{
|
{
|
||||||
|
@ -110,9 +101,6 @@ class NIFLoader : Ogre::ManualResourceLoader
|
||||||
std::map<std::string, float>* getTextIndices(std::string name);
|
std::map<std::string, float>* getTextIndices(std::string name);
|
||||||
|
|
||||||
|
|
||||||
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
|
|
||||||
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
|
|
||||||
|
|
||||||
void setOutputAnimFiles(bool output);
|
void setOutputAnimFiles(bool output);
|
||||||
void setVerbosePath(std::string path);
|
void setVerbosePath(std::string path);
|
||||||
|
|
||||||
|
@ -136,10 +124,10 @@ class NIFLoader : Ogre::ManualResourceLoader
|
||||||
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);
|
||||||
|
|
||||||
void createMaterial(const Ogre::String &name,
|
void createMaterial(const Ogre::String &name,
|
||||||
const Nif::Vector &ambient,
|
const Ogre::Vector3 &ambient,
|
||||||
const Nif::Vector &diffuse,
|
const Ogre::Vector3 &diffuse,
|
||||||
const Nif::Vector &specular,
|
const Ogre::Vector3 &specular,
|
||||||
const Nif::Vector &emissive,
|
const Ogre::Vector3 &emissive,
|
||||||
float glossiness, float alpha,
|
float glossiness, float alpha,
|
||||||
int alphaFlags, float alphaTest,
|
int alphaFlags, float alphaTest,
|
||||||
const Ogre::String &texName);
|
const Ogre::String &texName);
|
||||||
|
|
Loading…
Reference in a new issue