mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-19 19:53:53 +00:00
Use proper strings and vectors instead of slice arrays for NIF files
Slice arrays use pre-allocated pointers whose memory is managed externally. This is unnecessary and ultimately detrimental since it prevents any kind of data fixup (e.g. little endian to big endian, p[adding handling), and it also makes it difficult to use Ogre data streams.
This commit is contained in:
parent
d8d00123ea
commit
d3a31a24ce
9 changed files with 86 additions and 77 deletions
|
@ -53,7 +53,7 @@ public:
|
||||||
class Named : public Controlled
|
class Named : public Controlled
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Misc::SString name;
|
std::string name;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,8 +39,8 @@ public:
|
||||||
// internal (data is inside the nif itself) texture?
|
// internal (data is inside the nif itself) texture?
|
||||||
bool external;
|
bool external;
|
||||||
|
|
||||||
Misc::SString filename; // In case of external textures
|
std::string filename; // In case of external textures
|
||||||
NiPixelDataPtr data; // In case of internal textures
|
NiPixelDataPtr data; // In case of internal textures
|
||||||
|
|
||||||
/* Pixel layout
|
/* Pixel layout
|
||||||
0 - Palettised
|
0 - Palettised
|
||||||
|
@ -96,7 +96,7 @@ public:
|
||||||
class ShapeData : public Record
|
class ShapeData : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Misc::FloatArray vertices, normals, colors, uvlist;
|
std::vector<float> vertices, normals, colors, uvlist;
|
||||||
const Vector *center;
|
const Vector *center;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ class NiTriShapeData : public ShapeData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Triangles, three vertex indices per triangle
|
// Triangles, three vertex indices per triangle
|
||||||
Misc::SliceArray<short> triangles;
|
std::vector<short> triangles;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
|
@ -390,7 +390,7 @@ public:
|
||||||
{
|
{
|
||||||
const BoneTrafo *trafo;
|
const BoneTrafo *trafo;
|
||||||
const Vector4 *unknown;
|
const Vector4 *unknown;
|
||||||
Misc::SliceArray<VertWeight> weights;
|
std::vector<VertWeight> weights;
|
||||||
};
|
};
|
||||||
struct BoneInfoCopy
|
struct BoneInfoCopy
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
struct TextKey
|
struct TextKey
|
||||||
{
|
{
|
||||||
float time;
|
float time;
|
||||||
Misc::SString text;
|
std::string text;
|
||||||
};
|
};
|
||||||
std::vector<TextKey> list;
|
std::vector<TextKey> list;
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public:
|
||||||
"MRK" - marker, only visible in the editor, not rendered in-game
|
"MRK" - marker, only visible in the editor, not rendered in-game
|
||||||
"NCO" - no collision
|
"NCO" - no collision
|
||||||
*/
|
*/
|
||||||
Misc::SString string;
|
std::string string;
|
||||||
|
|
||||||
void read(NIFFile *nif)
|
void read(NIFFile *nif)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,8 +46,8 @@ using namespace Misc;
|
||||||
void NIFFile::parse()
|
void NIFFile::parse()
|
||||||
{
|
{
|
||||||
// Check the header string
|
// Check the header string
|
||||||
const char* head = getString(40);
|
std::string head = getString(40);
|
||||||
if(!begins(head, "NetImmerse File Format"))
|
if(head.compare(0, 22, "NetImmerse File Format") != 0)
|
||||||
fail("Invalid NIF header");
|
fail("Invalid NIF header");
|
||||||
|
|
||||||
// Get BCD version
|
// Get BCD version
|
||||||
|
@ -70,7 +70,7 @@ void NIFFile::parse()
|
||||||
|
|
||||||
for(int i=0;i<recNum;i++)
|
for(int i=0;i<recNum;i++)
|
||||||
{
|
{
|
||||||
SString rec = getString();
|
std::string rec = getString();
|
||||||
//cout << i << ": " << rec.toString() << endl;
|
//cout << i << ": " << rec.toString() << endl;
|
||||||
|
|
||||||
Record *r = NULL;
|
Record *r = NULL;
|
||||||
|
@ -155,7 +155,7 @@ void NIFFile::parse()
|
||||||
|
|
||||||
// Failure
|
// Failure
|
||||||
else
|
else
|
||||||
fail("Unknown record type " + rec.toString());
|
fail("Unknown record type " + rec);
|
||||||
|
|
||||||
assert(r != NULL);
|
assert(r != NULL);
|
||||||
assert(r->recType != RC_MISSING);
|
assert(r->recType != RC_MISSING);
|
||||||
|
|
|
@ -122,29 +122,41 @@ public:
|
||||||
char getByte() { return getType<char>(); }
|
char getByte() { return getType<char>(); }
|
||||||
|
|
||||||
template<class X>
|
template<class X>
|
||||||
Misc::SliceArray<X> getArrayLen(int num)
|
std::vector<X> getArrayLen(int num)
|
||||||
{ return Misc::SliceArray<X>((const X*)inp->getPtr(num*sizeof(X)),num); }
|
{
|
||||||
|
std::vector<X> v(num);
|
||||||
|
memcpy(&v[0], inp->getPtr(num*sizeof(X)), num*sizeof(X));
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
template<class X>
|
template<class X>
|
||||||
Misc::SliceArray<X> getArray()
|
std::vector<X> getArray()
|
||||||
{
|
{
|
||||||
int len = getInt();
|
int len = getInt();
|
||||||
return getArrayLen<X>(len);
|
return getArrayLen<X>(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
Misc::SString getString() { return getArray<char>(); }
|
|
||||||
|
|
||||||
const Vector *getVector() { return getPtr<Vector>(); }
|
const Vector *getVector() { return getPtr<Vector>(); }
|
||||||
const Matrix *getMatrix() { return getPtr<Matrix>(); }
|
const Matrix *getMatrix() { return getPtr<Matrix>(); }
|
||||||
const Transformation *getTrafo() { return getPtr<Transformation>(); }
|
const Transformation *getTrafo() { return getPtr<Transformation>(); }
|
||||||
const Vector4 *getVector4() { return getPtr<Vector4>(); }
|
const Vector4 *getVector4() { return getPtr<Vector4>(); }
|
||||||
|
|
||||||
Misc::FloatArray getFloatLen(int num)
|
std::vector<float> getFloatLen(int num)
|
||||||
{ return getArrayLen<float>(num); }
|
{ return getArrayLen<float>(num); }
|
||||||
|
|
||||||
// For fixed-size strings where you already know the size
|
// For fixed-size strings where you already know the size
|
||||||
const char *getString(int size)
|
std::string getString(size_t size)
|
||||||
{ return (const char*)inp->getPtr(size); }
|
{
|
||||||
|
std::string str;
|
||||||
|
str.resize(size);
|
||||||
|
memcpy(&str[0], inp->getPtr(size), size);
|
||||||
|
return str.substr(0, str.find('\0'));
|
||||||
|
}
|
||||||
|
std::string getString()
|
||||||
|
{
|
||||||
|
size_t size = getInt();
|
||||||
|
return getString(size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace
|
} // Namespace
|
||||||
|
|
|
@ -186,10 +186,10 @@ struct NiTriShape : Node
|
||||||
NiTriShapeCopy clone()
|
NiTriShapeCopy clone()
|
||||||
{
|
{
|
||||||
NiTriShapeCopy copy;
|
NiTriShapeCopy copy;
|
||||||
copy.sname = name.toString();
|
copy.sname = name;
|
||||||
float *ptr = (float*)data->vertices.ptr;
|
float *ptr = (float*)&data->vertices[0];
|
||||||
float *ptrNormals = (float*)data->normals.ptr;
|
float *ptrNormals = (float*)&data->normals[0];
|
||||||
int numVerts = data->vertices.length / 3;
|
int numVerts = data->vertices.size() / 3;
|
||||||
for(int i = 0; i < numVerts; i++)
|
for(int i = 0; i < numVerts; i++)
|
||||||
{
|
{
|
||||||
float *current = (float*) (ptr + i * 3);
|
float *current = (float*) (ptr + i * 3);
|
||||||
|
|
|
@ -90,7 +90,7 @@ struct Record
|
||||||
{
|
{
|
||||||
// Record type and type name
|
// Record type and type name
|
||||||
int recType;
|
int recType;
|
||||||
Misc::SString recName;
|
std::string recName;
|
||||||
|
|
||||||
Record() : recType(RC_MISSING) {}
|
Record() : recType(RC_MISSING) {}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
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 " +
|
||||||
r->recName.toString() + ". Skipping file.");
|
r->recName + ". Skipping file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,10 +292,10 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags
|
||||||
|
|
||||||
Nif::NiTriShapeData *data = shape->data.getPtr();
|
Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
|
|
||||||
float* vertices = (float*)data->vertices.ptr;
|
float* vertices = (float*)&data->vertices[0];
|
||||||
unsigned short* triangles = (unsigned short*)data->triangles.ptr;
|
unsigned short* triangles = (unsigned short*)&data->triangles[0];
|
||||||
|
|
||||||
for(unsigned int i=0; i < data->triangles.length; i = i+3)
|
for(unsigned int i=0; i < data->triangles.size(); i = i+3)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
|
Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
|
||||||
Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
|
Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
|
||||||
|
|
|
@ -399,7 +399,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
{
|
{
|
||||||
// cout << "s:" << shape << "\n";
|
// cout << "s:" << shape << "\n";
|
||||||
NiTriShapeData *data = shape->data.getPtr();
|
NiTriShapeData *data = shape->data.getPtr();
|
||||||
SubMesh *sub = mesh->createSubMesh(shape->name.toString());
|
SubMesh *sub = mesh->createSubMesh(shape->name);
|
||||||
|
|
||||||
int nextBuf = 0;
|
int nextBuf = 0;
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
// great.
|
// great.
|
||||||
|
|
||||||
// Add vertices
|
// Add vertices
|
||||||
int numVerts = data->vertices.length / 3;
|
int numVerts = data->vertices.size() / 3;
|
||||||
sub->vertexData = new VertexData();
|
sub->vertexData = new VertexData();
|
||||||
sub->vertexData->vertexCount = numVerts;
|
sub->vertexData->vertexCount = numVerts;
|
||||||
sub->useSharedVertices = false;
|
sub->useSharedVertices = false;
|
||||||
|
@ -422,12 +422,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
float *datamod = new float[data->vertices.length];
|
float *datamod = new float[data->vertices.size()];
|
||||||
//std::cout << "Shape" << shape->name.toString() << "\n";
|
//std::cout << "Shape" << shape->name.toString() << "\n";
|
||||||
for(int i = 0; i < numVerts; i++)
|
for(int i = 0; i < numVerts; i++)
|
||||||
{
|
{
|
||||||
int index = i * 3;
|
int index = i * 3;
|
||||||
const float *pos = data->vertices.ptr + index;
|
const float *pos = &data->vertices[index];
|
||||||
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
|
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
|
||||||
original = mTransform * original;
|
original = mTransform * original;
|
||||||
mBoundingBox.merge(original);
|
mBoundingBox.merge(original);
|
||||||
|
@ -440,14 +440,14 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false);
|
vbuf->writeData(0, vbuf->getSizeInBytes(), &data->vertices[0], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
|
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
|
|
||||||
if (data->normals.length)
|
if (data->normals.size())
|
||||||
{
|
{
|
||||||
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
|
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
|
||||||
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
|
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
|
||||||
|
@ -459,11 +459,11 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
Quaternion rotation = mTransform.extractQuaternion();
|
Quaternion rotation = mTransform.extractQuaternion();
|
||||||
rotation.normalise();
|
rotation.normalise();
|
||||||
|
|
||||||
float *datamod = new float[data->normals.length];
|
float *datamod = new float[data->normals.size()];
|
||||||
for(int i = 0; i < numVerts; i++)
|
for(int i = 0; i < numVerts; i++)
|
||||||
{
|
{
|
||||||
int index = i * 3;
|
int index = i * 3;
|
||||||
const float *pos = data->normals.ptr + index;
|
const float *pos = &data->normals[index];
|
||||||
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
|
Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2));
|
||||||
original = rotation * original;
|
original = rotation * original;
|
||||||
if (mNormaliseNormals)
|
if (mNormaliseNormals)
|
||||||
|
@ -481,16 +481,16 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false);
|
vbuf->writeData(0, vbuf->getSizeInBytes(), &data->normals[0], false);
|
||||||
}
|
}
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Vertex colors
|
// Vertex colors
|
||||||
if (data->colors.length)
|
if (data->colors.size())
|
||||||
{
|
{
|
||||||
const float *colors = data->colors.ptr;
|
const float *colors = &data->colors[0];
|
||||||
RenderSystem* rs = Root::getSingleton().getRenderSystem();
|
RenderSystem* rs = Root::getSingleton().getRenderSystem();
|
||||||
std::vector<RGBA> colorsRGB(numVerts);
|
std::vector<RGBA> colorsRGB(numVerts);
|
||||||
RGBA *pColour = &colorsRGB.front();
|
RGBA *pColour = &colorsRGB.front();
|
||||||
|
@ -508,7 +508,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->uvlist.length)
|
if (data->uvlist.size())
|
||||||
{
|
{
|
||||||
|
|
||||||
decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
|
decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
|
||||||
|
@ -518,12 +518,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
{
|
{
|
||||||
float *datamod = new float[data->uvlist.length];
|
float *datamod = new float[data->uvlist.size()];
|
||||||
|
|
||||||
for(unsigned int i = 0; i < data->uvlist.length; i+=2){
|
for(unsigned int i = 0; i < data->uvlist.size(); i+=2){
|
||||||
float x = *(data->uvlist.ptr + i);
|
float x = data->uvlist[i];
|
||||||
|
|
||||||
float y = *(data->uvlist.ptr + i + 1);
|
float y = data->uvlist[i + 1];
|
||||||
|
|
||||||
datamod[i] =x;
|
datamod[i] =x;
|
||||||
datamod[i + 1] =y;
|
datamod[i + 1] =y;
|
||||||
|
@ -532,13 +532,12 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
delete [] datamod;
|
delete [] datamod;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false);
|
vbuf->writeData(0, vbuf->getSizeInBytes(), &data->uvlist[0], false);
|
||||||
bind->setBinding(nextBuf++, vbuf);
|
bind->setBinding(nextBuf++, vbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triangle faces - The total number of triangle points
|
// Triangle faces - The total number of triangle points
|
||||||
int numFaces = data->triangles.length;
|
int numFaces = data->triangles.size();
|
||||||
|
|
||||||
if (numFaces)
|
if (numFaces)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -558,7 +557,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
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.ptr + index;
|
const short *pos = &data->triangles[index];
|
||||||
uint16 i0 = (uint16) *(pos+0);
|
uint16 i0 = (uint16) *(pos+0);
|
||||||
uint16 i1 = (uint16) *(pos+1);
|
uint16 i1 = (uint16) *(pos+1);
|
||||||
uint16 i2 = (uint16) *(pos+2);
|
uint16 i2 = (uint16) *(pos+2);
|
||||||
|
@ -578,7 +577,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false);
|
ibuf->writeData(0, ibuf->getSizeInBytes(), &data->triangles[0], false);
|
||||||
sub->indexData->indexBuffer = ibuf;
|
sub->indexData->indexBuffer = ibuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,8 +705,6 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
NiSourceTexture *st = t->textures[0].texture.getPtr();
|
NiSourceTexture *st = t->textures[0].texture.getPtr();
|
||||||
if (st->external)
|
if (st->external)
|
||||||
{
|
{
|
||||||
SString tname = st->filename;
|
|
||||||
|
|
||||||
/* findRealTexture checks if the file actually
|
/* findRealTexture checks if the file actually
|
||||||
exists. If it doesn't, and the name ends in .tga, it
|
exists. If it doesn't, and the name ends in .tga, it
|
||||||
will try replacing the extension with .dds instead
|
will try replacing the extension with .dds instead
|
||||||
|
@ -721,7 +718,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
problem since all the nif data is stored in a local
|
problem since all the nif data is stored in a local
|
||||||
throwaway buffer.
|
throwaway buffer.
|
||||||
*/
|
*/
|
||||||
texName = "textures\\" + tname.toString();
|
texName = "textures\\" + st->filename;
|
||||||
findRealTexture(texName);
|
findRealTexture(texName);
|
||||||
}
|
}
|
||||||
else warn("Found internal texture, ignoring.");
|
else warn("Found internal texture, ignoring.");
|
||||||
|
@ -795,9 +792,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
level.
|
level.
|
||||||
*/
|
*/
|
||||||
NiTriShapeData *data = shape->data.getPtr();
|
NiTriShapeData *data = shape->data.getPtr();
|
||||||
int numVerts = data->vertices.length / 3;
|
int numVerts = data->vertices.size() / 3;
|
||||||
|
|
||||||
float *ptr = (float*)data->vertices.ptr;
|
float *ptr = (float*)&data->vertices[0];
|
||||||
float *optr = ptr;
|
float *optr = ptr;
|
||||||
|
|
||||||
std::list<VertexBoneAssignment> vertexBoneAssignments;
|
std::list<VertexBoneAssignment> vertexBoneAssignments;
|
||||||
|
@ -828,7 +825,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO);
|
std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO);
|
||||||
std::vector<Ogre::Vector3> vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO);
|
std::vector<Ogre::Vector3> vertexNormalOriginal(numVerts, Ogre::Vector3::ZERO);
|
||||||
|
|
||||||
float *ptrNormals = (float*)data->normals.ptr;
|
float *ptrNormals = (float*)&data->normals[0];
|
||||||
//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]
|
||||||
//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
|
||||||
|
@ -849,13 +846,13 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
{
|
{
|
||||||
if(mSkel.isNull())
|
if(mSkel.isNull())
|
||||||
{
|
{
|
||||||
std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name.toString() << std::endl;
|
std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name << std::endl;
|
||||||
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()))
|
if(!mSkel->hasBone(shape->skin->bones[boneIndex].name))
|
||||||
std::cout << "We don't have this bone";
|
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);
|
||||||
|
|
||||||
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
// final_vector = old_vector + old_rotation*new_vector*old_scale
|
||||||
|
|
||||||
|
@ -863,19 +860,19 @@ 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 = convertRotation(it->trafo->rotation);
|
||||||
boneinfocopy.trafo.trans = convertVector3(it->trafo->trans);
|
boneinfocopy.trafo.trans = convertVector3(it->trafo->trans);
|
||||||
boneinfocopy.bonename = shape->skin->bones[boneIndex].name.toString();
|
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.length; 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() * convertVector3(it->trafo->trans);
|
||||||
|
|
||||||
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation);
|
vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation);
|
||||||
unsigned int verIndex = (it->weights.ptr + 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;
|
||||||
ind.weight = (it->weights.ptr + i)->weight;
|
ind.weight = it->weights[i].weight;
|
||||||
ind.boneinfocopyindex = copy.boneinfo.size() - 1;
|
ind.boneinfocopyindex = copy.boneinfo.size() - 1;
|
||||||
if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end())
|
if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end())
|
||||||
{
|
{
|
||||||
|
@ -893,7 +890,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
{
|
{
|
||||||
//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;
|
absVertPos = absVertPos * it->weights[i].weight;
|
||||||
vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3);
|
vertexPosOriginal[verIndex] = Vector3(ptr + verIndex *3);
|
||||||
|
|
||||||
mBoundingBox.merge(absVertPos);
|
mBoundingBox.merge(absVertPos);
|
||||||
|
@ -903,10 +900,10 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
//apply rotation to the normals (not every vertex has a normal)
|
//apply rotation to the normals (not every vertex has a normal)
|
||||||
//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.length)
|
if (verIndex < data->normals.size())
|
||||||
{
|
{
|
||||||
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
|
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
|
||||||
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
|
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
||||||
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3);
|
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3);
|
||||||
|
|
||||||
for (int j=0; j<3; j++)
|
for (int j=0; j<3; j++)
|
||||||
|
@ -918,7 +915,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
|
Vector3 absVertPos = vecPos + vecRot * vertexPosOriginal[verIndex];
|
||||||
absVertPos = absVertPos * (it->weights.ptr + i)->weight;
|
absVertPos = absVertPos * it->weights[i].weight;
|
||||||
Vector3 old = Vector3(ptr + verIndex *3);
|
Vector3 old = Vector3(ptr + verIndex *3);
|
||||||
absVertPos = absVertPos + old;
|
absVertPos = absVertPos + old;
|
||||||
|
|
||||||
|
@ -929,10 +926,10 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
|
|
||||||
//apply rotation to the normals (not every vertex has a normal)
|
//apply rotation to the normals (not every vertex has a normal)
|
||||||
//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.length)
|
if (verIndex < data->normals.size())
|
||||||
{
|
{
|
||||||
Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
|
Vector3 absNormalsPos = vecRot * vertexNormalOriginal[verIndex];
|
||||||
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
|
absNormalsPos = absNormalsPos * it->weights[i].weight;
|
||||||
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3);
|
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3);
|
||||||
absNormalsPos = absNormalsPos + oldNormal;
|
absNormalsPos = absNormalsPos + oldNormal;
|
||||||
|
|
||||||
|
@ -945,7 +942,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
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[i].weight;
|
||||||
|
|
||||||
|
|
||||||
vertexBoneAssignments.push_back(vba);
|
vertexBoneAssignments.push_back(vba);
|
||||||
|
@ -981,9 +978,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.size())
|
||||||
{
|
{
|
||||||
ptr = (float*)data->normals.ptr;
|
ptr = (float*)&data->normals[0];
|
||||||
for (int i=0; i<numVerts; i++)
|
for (int i=0; i<numVerts; i++)
|
||||||
{
|
{
|
||||||
vectorMul(rot, ptr);
|
vectorMul(rot, ptr);
|
||||||
|
@ -1090,7 +1087,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
|
|
||||||
for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++)
|
for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++)
|
||||||
{
|
{
|
||||||
std::string text = textiter->text.toString();
|
std::string text = textiter->text;
|
||||||
|
|
||||||
replace(text.begin(), text.end(), '\n', '/');
|
replace(text.begin(), text.end(), '\n', '/');
|
||||||
|
|
||||||
|
@ -1138,7 +1135,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;
|
||||||
|
|
||||||
// Quick-n-dirty workaround for the fact that several
|
// Quick-n-dirty workaround for the fact that several
|
||||||
// bones may have the same name.
|
// bones may have the same name.
|
||||||
|
@ -1192,7 +1189,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
|
||||||
}
|
}
|
||||||
else if (node->recType == RC_NiTriShape && bNiTri)
|
else if (node->recType == RC_NiTriShape && bNiTri)
|
||||||
{
|
{
|
||||||
std::string nodename = node->name.toString();
|
std::string nodename = node->name;
|
||||||
|
|
||||||
if (triname == "")
|
if (triname == "")
|
||||||
{
|
{
|
||||||
|
@ -1334,7 +1331,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
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 " +
|
||||||
r->recName.toString() + ". Skipping file.");
|
r->recName + ". Skipping file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,7 +1355,7 @@ void NIFLoader::loadResource(Resource *resource)
|
||||||
|
|
||||||
if (f->timeStart >= 10000000000000000.0f)
|
if (f->timeStart >= 10000000000000000.0f)
|
||||||
continue;
|
continue;
|
||||||
data->setBonename(o->name.toString());
|
data->setBonename(o->name);
|
||||||
data->setStartTime(f->timeStart);
|
data->setStartTime(f->timeStart);
|
||||||
data->setStopTime(f->timeStop);
|
data->setStopTime(f->timeStop);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue