Improved MD2, MD5 and PCX loader code
Former-commit-id: ab715a3d52030f1e514c1b0d250b8e6cb3883ad5
This commit is contained in:
parent
7ccac02bfd
commit
8c6c58c677
|
|
@ -8,7 +8,7 @@
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
||||||
struct md2_header
|
struct MD2_Header
|
||||||
{
|
{
|
||||||
nzUInt32 ident; // nombre magique : "IDP2"
|
nzUInt32 ident; // nombre magique : "IDP2"
|
||||||
nzUInt32 version; // version du format : 8
|
nzUInt32 version; // version du format : 8
|
||||||
|
|
@ -33,28 +33,30 @@ struct md2_header
|
||||||
nzUInt32 offset_end; // offset fin de fichier
|
nzUInt32 offset_end; // offset fin de fichier
|
||||||
};
|
};
|
||||||
|
|
||||||
struct md2_vertex
|
static_assert(sizeof(MD2_Header) == 17*sizeof(nzUInt32), "MD2_Header must be packed");
|
||||||
|
|
||||||
|
struct MD2_Vertex
|
||||||
{
|
{
|
||||||
nzUInt8 x, y, z;
|
nzUInt8 x, y, z;
|
||||||
nzUInt8 n;
|
nzUInt8 n;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(md2_vertex) == 4*sizeof(nzUInt8), "md2_vertex must be packed");
|
static_assert(sizeof(MD2_Vertex) == 4*sizeof(nzUInt8), "MD2_Vertex must be packed");
|
||||||
|
|
||||||
struct md2_texCoord
|
struct MD2_TexCoord
|
||||||
{
|
{
|
||||||
nzInt16 u, v;
|
nzInt16 u, v;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(md2_texCoord) == 2*sizeof(nzUInt16), "md2_texCoord must be packed");
|
static_assert(sizeof(MD2_TexCoord) == 2*sizeof(nzInt16), "MD2_TexCoord must be packed");
|
||||||
|
|
||||||
struct md2_triangle
|
struct MD2_Triangle
|
||||||
{
|
{
|
||||||
nzUInt16 vertices[3];
|
nzUInt16 vertices[3];
|
||||||
nzUInt16 texCoords[3];
|
nzUInt16 texCoords[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(md2_triangle) == 2*3*sizeof(nzUInt16), "md2_triangle must be packed");
|
static_assert(sizeof(MD2_Triangle) == 2*3*sizeof(nzUInt16), "MD2_Triangle must be packed");
|
||||||
|
|
||||||
extern const nzUInt32 md2Ident;
|
extern const nzUInt32 md2Ident;
|
||||||
extern const NzVector3f md2Normals[162];
|
extern const NzVector3f md2Normals[162];
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ namespace
|
||||||
|
|
||||||
bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||||
{
|
{
|
||||||
md2_header header;
|
MD2_Header header;
|
||||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
if (stream.Read(&header, sizeof(MD2_Header)) != sizeof(MD2_Header))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to read header");
|
NazaraError("Failed to read header");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -106,10 +106,10 @@ namespace
|
||||||
indexBuffer->SetPersistent(false);
|
indexBuffer->SetPersistent(false);
|
||||||
|
|
||||||
/// Lecture des triangles
|
/// Lecture des triangles
|
||||||
std::vector<md2_triangle> triangles(header.num_tris);
|
std::vector<MD2_Triangle> triangles(header.num_tris);
|
||||||
|
|
||||||
stream.SetCursorPos(header.offset_tris);
|
stream.SetCursorPos(header.offset_tris);
|
||||||
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle));
|
||||||
|
|
||||||
NzBufferMapper<NzIndexBuffer> indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite);
|
NzBufferMapper<NzIndexBuffer> indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite);
|
||||||
nzUInt16* index = reinterpret_cast<nzUInt16*>(indexMapper.GetPointer());
|
nzUInt16* index = reinterpret_cast<nzUInt16*>(indexMapper.GetPointer());
|
||||||
|
|
@ -136,10 +136,10 @@ namespace
|
||||||
indexMapper.Unmap();
|
indexMapper.Unmap();
|
||||||
|
|
||||||
/// Lecture des coordonnées de texture
|
/// Lecture des coordonnées de texture
|
||||||
std::vector<md2_texCoord> texCoords(header.num_st);
|
std::vector<MD2_TexCoord> texCoords(header.num_st);
|
||||||
|
|
||||||
stream.SetCursorPos(header.offset_st);
|
stream.SetCursorPos(header.offset_st);
|
||||||
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
stream.Read(&texCoords[0], header.num_st*sizeof(MD2_TexCoord));
|
||||||
|
|
||||||
#ifdef NAZARA_BIG_ENDIAN
|
#ifdef NAZARA_BIG_ENDIAN
|
||||||
for (unsigned int i = 0; i < header.num_st; ++i)
|
for (unsigned int i = 0; i < header.num_st; ++i)
|
||||||
|
|
@ -166,12 +166,12 @@ namespace
|
||||||
/// Chargement des vertices
|
/// Chargement des vertices
|
||||||
stream.SetCursorPos(header.offset_frames);
|
stream.SetCursorPos(header.offset_frames);
|
||||||
|
|
||||||
std::unique_ptr<md2_vertex[]> vertices(new md2_vertex[header.num_vertices]);
|
std::unique_ptr<MD2_Vertex[]> vertices(new MD2_Vertex[header.num_vertices]);
|
||||||
NzVector3f scale, translate;
|
NzVector3f scale, translate;
|
||||||
stream.Read(scale, sizeof(NzVector3f));
|
stream.Read(scale, sizeof(NzVector3f));
|
||||||
stream.Read(translate, sizeof(NzVector3f));
|
stream.Read(translate, sizeof(NzVector3f));
|
||||||
stream.Read(nullptr, 16*sizeof(char)); // On avance en ignorant le nom de la frame (Géré par l'animation)
|
stream.Read(nullptr, 16*sizeof(char)); // Nom de la frame, inutile ici
|
||||||
stream.Read(vertices.get(), header.num_vertices*sizeof(md2_vertex));
|
stream.Read(vertices.get(), header.num_vertices*sizeof(MD2_Vertex));
|
||||||
|
|
||||||
#ifdef NAZARA_BIG_ENDIAN
|
#ifdef NAZARA_BIG_ENDIAN
|
||||||
NzByteSwap(&scale.x, sizeof(float));
|
NzByteSwap(&scale.x, sizeof(float));
|
||||||
|
|
@ -199,7 +199,7 @@ namespace
|
||||||
for (unsigned int j = 0; j < 3; ++j)
|
for (unsigned int j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
const unsigned int fixedIndex = indexFix[j];
|
const unsigned int fixedIndex = indexFix[j];
|
||||||
const md2_texCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(static_cast<float>(texC.u) / header.skinwidth, 1.f - static_cast<float>(texC.v)/header.skinheight);
|
vertex[triangles[i].vertices[fixedIndex]].uv.Set(static_cast<float>(texC.u) / header.skinwidth, 1.f - static_cast<float>(texC.v)/header.skinheight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +210,7 @@ namespace
|
||||||
|
|
||||||
for (unsigned int v = 0; v < header.num_vertices; ++v)
|
for (unsigned int v = 0; v < header.num_vertices; ++v)
|
||||||
{
|
{
|
||||||
const md2_vertex& vert = vertices[v];
|
const MD2_Vertex& vert = vertices[v];
|
||||||
NzVector3f position = rotationQuat * NzVector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z);
|
NzVector3f position = rotationQuat * NzVector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z);
|
||||||
|
|
||||||
vertex->position = position;
|
vertex->position = position;
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ bool NzMD5AnimParser::Parse(NzAnimation* animation)
|
||||||
sequenceJoint.rotation = rotationQuat * m_frames[j].joints[i].orient;
|
sequenceJoint.rotation = rotationQuat * m_frames[j].joints[i].orient;
|
||||||
}
|
}
|
||||||
|
|
||||||
sequenceJoint.scale = NzVector3f(1.f, 1.f, 1.f);
|
sequenceJoint.scale.Set(1.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
if (parent >= 0)
|
if (parent >= 0)
|
||||||
bindMatrix.MakeTransform(m_joints[i].bindPos, m_joints[i].bindOrient);
|
bindMatrix.MakeTransform(m_joints[i].bindPos, m_joints[i].bindOrient);
|
||||||
else
|
else
|
||||||
bindMatrix.MakeTransform(rotationQuat * m_joints[i].bindPos, rotationQuat * m_joints[i].bindOrient, scale);
|
bindMatrix.MakeTransform(rotationQuat * m_joints[i].bindPos, rotationQuat * m_joints[i].bindOrient);
|
||||||
|
|
||||||
joint->SetInverseBindMatrix(bindMatrix.InverseAffine());
|
joint->SetInverseBindMatrix(bindMatrix.InverseAffine());
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +250,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
vertexWeight->weights[j] = vertex.startWeight + j;
|
vertexWeight->weights[j] = vertex.startWeight + j;
|
||||||
}
|
}
|
||||||
|
|
||||||
bindPosVertex->position = scale * finalPos;
|
bindPosVertex->position = finalPos;
|
||||||
bindPosVertex->uv.Set(vertex.uv.x, 1.f-vertex.uv.y);
|
bindPosVertex->uv.Set(vertex.uv.x, 1.f-vertex.uv.y);
|
||||||
bindPosVertex++;
|
bindPosVertex++;
|
||||||
vertexWeight++;
|
vertexWeight++;
|
||||||
|
|
@ -258,6 +258,8 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
mesh->SetMaterial(i, baseDir + md5Mesh.shader);
|
||||||
|
|
||||||
|
subMesh->GenerateNormalsAndTangents();
|
||||||
subMesh->SetMaterialIndex(i);
|
subMesh->SetMaterialIndex(i);
|
||||||
|
|
||||||
mesh->AddSubMesh(subMesh.get());
|
mesh->AddSubMesh(subMesh.get());
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@
|
||||||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||||
#include <Nazara/Core/Endianness.hpp>
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/File.hpp>
|
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/MemoryStream.hpp>
|
|
||||||
#include <Nazara/Utility/Image.hpp>
|
#include <Nazara/Utility/Image.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
@ -38,7 +36,7 @@ namespace
|
||||||
nzUInt8 padding[54];
|
nzUInt8 padding[54];
|
||||||
};
|
};
|
||||||
|
|
||||||
//static_assert(sizeof(pcx_header) == 1024, "PCX header must be 1024 bytes sized");
|
static_assert(sizeof(pcx_header) == (6+48+54)*sizeof(nzUInt8) + 10*sizeof(nzUInt16), "pcx_header struct must be packed");
|
||||||
|
|
||||||
bool IsSupported(const NzString& extension)
|
bool IsSupported(const NzString& extension)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue