Skip to content

Commit

Permalink
alignment and big-endian fixes for ms3d loader
Browse files Browse the repository at this point in the history
  • Loading branch information
a1200 committed Nov 22, 2019
1 parent 11938c2 commit 2b132c1
Showing 1 changed file with 73 additions and 22 deletions.
95 changes: 73 additions & 22 deletions source/Irrlicht/CMS3DMeshFileLoader.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// 2019 additional alignment and big_endian fixes by Corto and Salas00
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

Expand Down Expand Up @@ -34,12 +35,16 @@ struct MS3DHeader
// Vertex information
struct MS3DVertex
{
u8 pad1[3];
u8 Flags;
float Vertex[3];
char BoneID;
u8 RefCount;
u8 pad2[2];
} PACK_STRUCT;

#define MS3DVERTEX_NUM_PAD_BYTES 5

// Triangle information
struct MS3DTriangle
{
Expand All @@ -49,8 +54,11 @@ struct MS3DTriangle
float S[3], T[3];
u8 SmoothingGroup;
u8 GroupIndex;
u8 pad1[2];
} PACK_STRUCT;

#define MS3DTRIANGLE_NUM_PAD_BYTES 2

// Material information
struct MS3DMaterial
{
Expand All @@ -64,11 +72,15 @@ struct MS3DMaterial
u8 Mode; // 0, 1, 2 is unused now
char Texture[128];
char Alphamap[128];
u8 pad1[3];
} PACK_STRUCT;

#define MS3DMATERIAL_NUM_PAD_BYTES 3

// Joint information
struct MS3DJoint
{
u8 pad[3];
u8 Flags;
char Name[32];
char ParentName[32];
Expand All @@ -78,6 +90,8 @@ struct MS3DJoint
u16 NumTranslationKeyframes;
} PACK_STRUCT;

#define MS3DJOINT_NUM_PAD_BYTES 3

// Keyframe data
struct MS3DKeyframe
{
Expand All @@ -97,6 +111,25 @@ struct MS3DVertexWeights
// Default alignment
#include "irrunpack.h"


static inline float get_unaligned_le_float(const u8 *ptr)
{
union {
u8 u[4];
float f;
} tmp;
#ifdef __BIG_ENDIAN__
tmp.u[0] = ptr[3];
tmp.u[1] = ptr[2];
tmp.u[2] = ptr[1];
tmp.u[3] = ptr[0];
#else
tmp.u = *(float*)ptr;
#endif
return tmp.f;
}


struct SGroup
{
core::stringc Name;
Expand Down Expand Up @@ -202,25 +235,30 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
#endif
#ifdef _IRR_DEBUG_MS3D_LOADER_
os::Printer::log("Load vertices", core::stringc(numVertices).c_str());
os::Printer::log("sizeof(MS3DVertex) = ", core::stringc(sizeof(MS3DVertex)).c_str());
os::Printer::log("sizeof(struct MS3DVertex) = ", core::stringc(sizeof(struct MS3DVertex)).c_str());
#endif

pPtr += sizeof(u16);
MS3DVertex *vertices = (MS3DVertex*)pPtr;
pPtr += sizeof(MS3DVertex) * numVertices;
if (pPtr > buffer+fileSize)
MS3DVertex *vertices = new MS3DVertex[numVertices];
if (pPtr + ((sizeof(struct MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES) * numVertices) > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
for (u16 tmp=0; tmp<numVertices; ++tmp)
{
memcpy(&vertices[tmp].Flags, pPtr, sizeof(struct MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES);
#ifdef __BIG_ENDIAN__
vertices[tmp].Vertex[0] = os::Byteswap::byteswap(vertices[tmp].Vertex[0]);
vertices[tmp].Vertex[1] = os::Byteswap::byteswap(vertices[tmp].Vertex[1]);
vertices[tmp].Vertex[2] = -os::Byteswap::byteswap(vertices[tmp].Vertex[2]);
#else
vertices[tmp].Vertex[2] = -vertices[tmp].Vertex[2];
#endif
// Go to the next vertex structure
pPtr += sizeof(struct MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES;
}

// triangles
Expand All @@ -232,16 +270,18 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
os::Printer::log("Load Triangles", core::stringc(numTriangles).c_str());
#endif
pPtr += sizeof(u16);
MS3DTriangle *triangles = (MS3DTriangle*)pPtr;
pPtr += sizeof(MS3DTriangle) * numTriangles;
if (pPtr > buffer+fileSize)

MS3DTriangle *triangles = new MS3DTriangle[numTriangles];

if (pPtr + ((sizeof(struct MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES) * numTriangles) > buffer+fileSize)
{
delete [] buffer;
os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR);
return false;
}
for (u16 tmp=0; tmp<numTriangles; ++tmp)
{
memcpy(&triangles[tmp].Flags, pPtr, sizeof(struct MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES);
#ifdef __BIG_ENDIAN__
triangles[tmp].Flags = os::Byteswap::byteswap(triangles[tmp].Flags);
for (u16 j=0; j<3; ++j)
Expand All @@ -258,6 +298,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
triangles[tmp].VertexNormals[1][2] = -triangles[tmp].VertexNormals[1][2];
triangles[tmp].VertexNormals[2][2] = -triangles[tmp].VertexNormals[2][2];
#endif
// Go to the next triangle structure
pPtr += sizeof(struct MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES;
}

// groups
Expand Down Expand Up @@ -291,7 +333,6 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
pPtr += sizeof(u16);
grp.VertexIds.reallocate(triangleCount);

//pPtr += sizeof(u16) * triangleCount; // triangle indices
for (u16 j=0; j<triangleCount; ++j)
{
#ifdef __BIG_ENDIAN__
Expand Down Expand Up @@ -331,9 +372,11 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
AnimatedMesh->addMeshBuffer();
}

MS3DMaterial *material = new MS3DMaterial;

for (i=0; i<numMaterials; ++i)
{
MS3DMaterial *material = (MS3DMaterial*)pPtr;
memcpy(material, pPtr, sizeof(struct MS3DMaterial) - MS3DMATERIAL_NUM_PAD_BYTES);
#ifdef __BIG_ENDIAN__
for (u16 j=0; j<4; ++j)
material->Ambient[j] = os::Byteswap::byteswap(material->Ambient[j]);
Expand All @@ -346,7 +389,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
material->Shininess = os::Byteswap::byteswap(material->Shininess);
material->Transparency = os::Byteswap::byteswap(material->Transparency);
#endif
pPtr += sizeof(MS3DMaterial);
pPtr += (sizeof(MS3DMaterial) - MS3DMATERIAL_NUM_PAD_BYTES);
if (pPtr > buffer+fileSize)
{
delete [] buffer;
Expand Down Expand Up @@ -378,12 +421,11 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath));
}
}
delete material;

// animation time
f32 framesPerSecond = get_unaligned_le_float(pPtr);

// animation time
f32 framesPerSecond = *(float*)pPtr;
#ifdef __BIG_ENDIAN__
framesPerSecond = os::Byteswap::byteswap(framesPerSecond);
#endif
#ifdef _IRR_DEBUG_MS3D_LOADER_
os::Printer::log("FPS", core::stringc(framesPerSecond).c_str());
#endif
Expand All @@ -394,10 +436,6 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
AnimatedMesh->setAnimationSpeed(framesPerSecond);

// ignore, calculated inside SkinnedMesh
// s32 frameCount = *(int*)pPtr;
#ifdef __BIG_ENDIAN__
// frameCount = os::Byteswap::byteswap(frameCount);
#endif
pPtr += sizeof(int);

u16 jointCount = *(u16*)pPtr;
Expand All @@ -422,7 +460,11 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
for (i=0; i<jointCount; ++i)
{
u32 j;
MS3DJoint *pJoint = (MS3DJoint*)pPtr;

MS3DJoint *pJoint = new MS3DJoint;

memcpy(&pJoint->Flags, pPtr, sizeof(MS3DJoint) - MS3DJOINT_NUM_PAD_BYTES);

#ifdef __BIG_ENDIAN__
for (j=0; j<3; ++j)
pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]);
Expand All @@ -431,7 +473,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes);
pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes);
#endif
pPtr += sizeof(MS3DJoint);
pPtr = pPtr + sizeof(MS3DJoint) - 3;
if (pPtr > buffer+fileSize)
{
delete [] buffer;
Expand Down Expand Up @@ -468,11 +510,14 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
HasAnimation = true;
*/

MS3DKeyframe* kf = new MS3DKeyframe;

// get rotation keyframes
const u16 numRotationKeyframes = pJoint->NumRotationKeyframes;
for (j=0; j < numRotationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
memcpy(kf, pPtr, sizeof(MS3DKeyframe));

#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
Expand Down Expand Up @@ -510,7 +555,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
const u16 numTranslationKeyframes = pJoint->NumTranslationKeyframes;
for (j=0; j<numTranslationKeyframes; ++j)
{
MS3DKeyframe* kf = (MS3DKeyframe*)pPtr;
memcpy(kf, pPtr, sizeof(MS3DKeyframe));

#ifdef __BIG_ENDIAN__
kf->Time = os::Byteswap::byteswap(kf->Time);
for (u32 l=0; l<3; ++l)
Expand All @@ -532,6 +578,9 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
kf->Parameter[1]+pJoint->Translation[1],
-kf->Parameter[2]-pJoint->Translation[2]);
}

delete kf;
delete pJoint;
}

core::array<MS3DVertexWeights> vertexWeights;
Expand Down Expand Up @@ -785,6 +834,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file)
}

delete [] buffer;
delete [] triangles;
delete [] vertices;

return true;
}
Expand Down

0 comments on commit 2b132c1

Please sign in to comment.