initial commit (based on MeshConverter source)

This commit is contained in:
gered 2012-12-10 15:28:23 -05:00
commit 3e28e22b6e
11 changed files with 1126 additions and 0 deletions

14
.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
.DS_Store
*.sdf
*.opensdf
*.user
*.suo
/*.exe
/*.idb
/*.ilk
/*.pdb
*.vpwhistu
*.vtg
/*.dll
/ms3dtomesh
/build

3
generate_makefile.sh Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
type premake4 >/dev/null 2>&1 || { echo >&2 "'premake4' not found in your path."; exit 1; }
premake4 --file=premake.lua gmake

8
generate_vs2010.bat Normal file
View file

@ -0,0 +1,8 @@
@echo off
for %%X in (premake4.exe) do (set FOUND=%%~$PATH:X)
if not defined FOUND (
echo 'premake4' not found in your path.
exit /b
)
premake4 --file=premake.lua vs2010

63
premake.lua Normal file
View file

@ -0,0 +1,63 @@
BUILD_DIR = "build"
if _ACTION == "clean" then
os.rmdir(BUILD_DIR)
end
solution "Ms3dToMesh"
configurations { "Debug", "Release" }
location (BUILD_DIR .. "/" .. _ACTION)
project "Ms3dToMesh"
kind "ConsoleApp"
language "C++"
location (BUILD_DIR .. "/" .. _ACTION)
files {
"./src/**.c*",
"./src/**.h",
}
debugdir "."
---- PLATFORM SPECIFICS ----------------------------------------------------
configuration "vs*"
flags {
"NoPCH",
"NoMinimalRebuild"
}
buildoptions { "/MP" }
defines {
"_CRT_SECURE_NO_WARNINGS",
"_CRT_NONSTDC_NO_WARNINGS"
}
configuration "gmake"
kind "ConsoleApp"
buildoptions { "-Wall" }
configuration { "windows", "gmake" }
kind "ConsoleApp"
defines {
"_GNU_SOURCE=1",
}
links {
"mingw32",
}
linkoptions {
"-static-libgcc",
"-static-libstdc++",
}
----------------------------------------------------------------------------
configuration "Debug"
defines {
"DEBUG",
"DEBUG_ASSERT_BREAK",
}
flags { "Symbols" }
configuration "Release"
defines {
"NDEBUG",
}
flags { "Optimize" }

11
src/geometry/vector2.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef __VECTOR2_H_INCLUDED__
#define __VECTOR2_H_INCLUDED__
class Vector2
{
public:
float x;
float y;
};
#endif

319
src/geometry/vector3.h Normal file
View file

@ -0,0 +1,319 @@
#ifndef __VECTOR3_H_INCLUDED__
#define __VECTOR3_H_INCLUDED__
#include <math.h>
/**
* Represents a 3D vector and provides common methods/operators
* for vector math
*/
class Vector3
{
public:
Vector3() {}
Vector3(float vx, float vy, float vz) { x = vx; y = vy; z = vz; }
Vector3(const float *v) { x = v[0]; y = v[1]; z = v[2]; }
~Vector3() {}
static Vector3 Cross(const Vector3 &a, const Vector3 &b);
static float Dot(const Vector3 &a, const Vector3 &b);
static Vector3 Normalize(const Vector3 &a);
static Vector3 SurfaceNormal(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3);
static float Magnitude(const Vector3 &a);
static float SquaredLength(const Vector3 &a);
static Vector3 SetLength(const Vector3 &v, float length);
static float Distance(const Vector3 &a, const Vector3 &b);
static bool IsPointInTriangle(const Vector3 &point, const Vector3 &pa, const Vector3 &pb, const Vector3 &pc);
float x;
float y;
float z;
};
bool operator==(const Vector3 &left, const Vector3 &right);
Vector3 operator-(const Vector3 &left);
Vector3 operator+(const Vector3 &left, const Vector3 &right);
Vector3 &operator+=(Vector3 &left, const Vector3 &right);
Vector3 operator-(const Vector3 &left, const Vector3 &right);
Vector3 &operator-=(Vector3 &left, const Vector3 &right);
Vector3 operator*(const Vector3 &left, float right);
Vector3 &operator*=(Vector3 &left, float right);
Vector3 operator/(const Vector3 &left, float right);
Vector3 &operator/=(Vector3 &left, float right);
Vector3 operator*(const Vector3 &left, const Vector3 &right);
Vector3 &operator*=(Vector3 &left, const Vector3 &right);
Vector3 operator/(const Vector3 &left, const Vector3 &right);
Vector3 &operator/=(Vector3 &left, const Vector3 &right);
#define ZERO_VECTOR Vector3(0.0f, 0.0f, 0.0f)
#define X_AXIS Vector3(1.0f, 0.0f, 0.0f)
#define Y_AXIS Vector3(0.0f, 1.0f, 0.0f)
#define Z_AXIS Vector3(0.0f, 0.0f, 1.0f)
#define UP_VECTOR Vector3(0.0f, 1.0f, 0.0f)
/**
* Computes the cross product of 2 vectors.
* x = a.y * b.z - b.y * a.z
* y = a.z * b.x - b.z * a.x
* z = a.x * b.y - b.x * a.y
* @param a first vector
* @param b second vector
*
* @return Vector3 the cross product
*/
inline Vector3 Vector3::Cross(const Vector3 &a, const Vector3 &b)
{
return Vector3(
(a.y * b.z) - (b.y * a.z),
(a.z * b.x) - (b.z * a.x),
(a.x * b.y) - (b.x * a.y)
);
}
/**
* Computes the dot product of 2 vectors.
* dot = (a.x * b.x) + (a.y * b.y) + (a.z * b.z)
* @param a first vector
* @param b second vector
*
* @return float the dot product
*/
inline float Vector3::Dot(const Vector3 &a, const Vector3 &b)
{
return (a.x * b.x) +
(a.y * b.y) +
(a.z * b.z);
}
/**
* Normalizes a vector
* x = a.x / ||a||
* y = a.y / ||a||
* z = a.z / ||a||
* @param a vector to normalize
*
* @return Vector3 the normalized vector
*/
inline Vector3 Vector3::Normalize(const Vector3 &a)
{
float magnitudeSquared = (a.x * a.x) + (a.y * a.y) + (a.z * a.z);
if (magnitudeSquared > 0.0f)
{
float inverseMagnitude = 1.0f / sqrtf(magnitudeSquared);
return Vector3(
a.x * inverseMagnitude,
a.y * inverseMagnitude,
a.z * inverseMagnitude
);
}
else
return a;
}
/**
* Calculates a normal vector for the given 3 vectors making up
* a triangle (counter-clockwise order)
* @param v1 first vertex
* @param v2 second vertex
* @param v3 third vertex
*
* @return Vector3 normal vector for the triangle
*/
inline Vector3 Vector3::SurfaceNormal(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3)
{
return Vector3::Normalize(Vector3::Cross(v2 - v1, v3 - v1));
}
/**
* Returns magnitude of a vector.
* ||a|| = sqrt((a.x * a.x) + (a.y * a.y) + (a.z * a.z))
* @param a vector to calculate the magnitude of
*
* @return float vector magnitude
*/
inline float Vector3::Magnitude(const Vector3 &a)
{
return sqrtf(
(a.x * a.x) +
(a.y * a.y) +
(a.z * a.z)
);
}
/**
* Returns the squared length of a vector (the magnitude minus
* the sqrt call)
* @param a vector to calculate the squared length of
*
* @return float squared length of the vector
*/
inline float Vector3::SquaredLength(const Vector3 &a)
{
return
(a.x * a.x) +
(a.y * a.y) +
(a.z * a.z);
}
/**
* Adjusts a vector so that it's magnitude is equal to the given
* length
* @param v the original vector to be adjusted
* @param length desired vector magnitude
*
* @return Vector3 the resulting vector after it's length has
* been converted to the desired amount
*/
inline Vector3 Vector3::SetLength(const Vector3 &v, float length)
{
float magnitude = Vector3::Magnitude(v);
return v * (length / magnitude);
}
/**
* Calculates the distance between two points
* @param a the first point
* @param b the second point
*
* @return float the distance between both points
*/
inline float Vector3::Distance(const Vector3 &a, const Vector3 &b)
{
return sqrtf(
((b.x - a.x) * (b.x - a.x)) +
((b.y - a.y) * (b.y - a.y)) +
((b.z - a.z) * (b.z - a.z))
);
}
/**
* Checks if a given point lies inside a triangle or not
* @param point point to test
* @param a first vector of the triangle
* @param b second vector of the triangle
* @param c third vector of the triangle
*
* @return BOOL TRUE if the point lies inside the triangle,
* FALSE if it doesn't
*/
inline bool Vector3::IsPointInTriangle(const Vector3 &point, const Vector3 &pa, const Vector3 &pb, const Vector3 &pc)
{
Vector3 edge1 = pb - pa;
Vector3 edge2 = pc - pa;
float a = Vector3::Dot(edge1, edge1);
float b = Vector3::Dot(edge1, edge2);
float c = Vector3::Dot(edge2, edge2);
float ac_bb = (a * c) - (b * b);
Vector3 vp(point.x - pa.x, point.y - pa.y, point.z - pa.z);
float d = Vector3::Dot(vp, edge1);
float e = Vector3::Dot(vp, edge2);
float x = (d * c) - (e * b);
float y = (e * a) - (d * b);
float z = x + y - ac_bb;
int result = (( ((unsigned int&) z)& ~(((unsigned int&) x)|((unsigned int&) y)) ) & 0x80000000);
if (result == 0)
return false;
else
return true;
}
inline bool operator==(const Vector3 &left, const Vector3 &right)
{
return (left.x == right.x && left.y == right.y && left.z == right.z);
}
inline Vector3 operator-(const Vector3 &left)
{
return Vector3(-left.x, -left.y, -left.z);
}
inline Vector3 operator+(const Vector3 &left, const Vector3 &right)
{
return Vector3(left.x + right.x, left.y + right.y, left.z + right.z);
}
inline Vector3 &operator+=(Vector3 &left, const Vector3 &right)
{
left.x += right.x;
left.y += right.y;
left.z += right.z;
return left;
}
inline Vector3 operator-(const Vector3 &left, const Vector3 &right)
{
return Vector3(left.x - right.x, left.y - right.y, left.z - right.z);
}
inline Vector3 &operator-=(Vector3 &left, const Vector3 &right)
{
left.x -= right.x;
left.y -= right.y;
left.z -= right.z;
return left;
}
inline Vector3 operator*(const Vector3 &left, float right)
{
return Vector3(left.x * right, left.y * right, left.z * right);
}
inline Vector3 &operator*=(Vector3 &left, float right)
{
left.x *= right;
left.y *= right;
left.z *= right;
return left;
}
inline Vector3 operator/(const Vector3 &left, float right)
{
return Vector3(left.x / right, left.y / right, left.z / right);
}
inline Vector3 &operator/=(Vector3 &left, float right)
{
left.x /= right;
left.y /= right;
left.z /= right;
return left;
}
inline Vector3 operator*(const Vector3 &left, const Vector3 &right)
{
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
}
inline Vector3 &operator*=(Vector3 &left, const Vector3 &right)
{
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
return left;
}
inline Vector3 operator/(const Vector3 &left, const Vector3 &right)
{
return Vector3(left.x / right.x, left.y / right.y, left.z / right.z);
}
inline Vector3 &operator/=(Vector3 &left, const Vector3 &right)
{
left.x /= right.x;
left.y /= right.y;
left.z /= right.z;
return left;
}
#endif

85
src/main.cpp Normal file
View file

@ -0,0 +1,85 @@
#include <stdio.h>
#include <string>
#include <exception>
#include "ms3d/ms3d.h"
int main(int argc, char **argv)
{
printf("MS3D-to-MESH Converter\n");
if (argc == 1)
{
printf("No input file specified.\n");
printf("Usage: ms3dtomesh.exe [--scale=<scale factor>] [inputfile]\n\n");
return 1;
}
// input file is always the last argument
std::string file = argv[argc - 1];
// default option values
float scaleFactor = 1.0f;
// find any options and update their values
for (int i = 1; i < argc - 1; ++i)
{
std::string arg = argv[i];
if (arg.substr(0, 8) == "--scale=")
{
// scale factor
if (arg.length() == 8)
{
printf("Missing scale factor.\n");
return 1;
}
scaleFactor = (float)atof(arg.substr(8).c_str());
if (scaleFactor == 0.0f)
{
printf("Invalid or 0.0 scale factor.\n");
return 1;
}
}
}
std::string extension;
try
{
extension = file.substr(file.find_last_of('.'), std::string::npos);
for (unsigned int i = 0; i < extension.size(); ++i)
extension[i] = tolower(extension[i]);
}
catch (std::exception &e)
{
extension = "";
}
std::string meshFile = "";
if (extension.length() > 0)
{
meshFile = file;
meshFile.erase(meshFile.find_last_of('.'), std::string::npos);
meshFile.append(".mesh");
}
Ms3d *ms3d = new Ms3d();
if (!ms3d->Load(file))
{
printf("Error loading MS3D file.\n\n");
return 1;
}
if (!ms3d->ConvertToMesh(meshFile, scaleFactor))
{
printf("Error converting MS3D to MESH.\n\n");
return 1;
}
printf("Finished converting to %s\n", meshFile.c_str());
return 0;
}

443
src/ms3d/ms3d.cpp Normal file
View file

@ -0,0 +1,443 @@
#include "ms3d.h"
#include <stdio.h>
#include "../util/files.h"
Ms3d::Ms3d()
{
m_numVertices = 0;
m_numTriangles = 0;
m_numMeshes = 0;
m_numMaterials = 0;
m_numJoints = 0;
m_vertices = NULL;
m_triangles = NULL;
m_meshes = NULL;
m_materials = NULL;
m_joints = NULL;
}
void Ms3d::Release()
{
delete[] m_vertices;
delete[] m_triangles;
delete[] m_meshes;
delete[] m_materials;
delete[] m_joints;
m_numVertices = 0;
m_numTriangles = 0;
m_numMeshes = 0;
m_numMaterials = 0;
m_numJoints = 0;
}
bool Ms3d::Load(const std::string &file)
{
FILE *fp;
Ms3dHeader header;
fp = fopen(file.c_str(), "rb");
if (!fp)
return false;
// filetype verification
fread(&header.id, 10, 1, fp);
if (strncmp(header.id, "MS3D000000", 10) != 0)
{
fclose(fp);
return false;
}
fread(&header.version, 4, 1, fp);
if (header.version != 4)
{
fclose(fp);
return false;
}
// read vertices
fread(&m_numVertices, 2, 1, fp);
m_vertices = new Ms3dVertex[m_numVertices];
for (int i = 0; i < m_numVertices; ++i)
{
Ms3dVertex *vertex = &m_vertices[i];
fread(&vertex->editorFlags, 1, 1, fp);
fread(&vertex->vertex.x, 4, 1, fp);
fread(&vertex->vertex.y, 4, 1, fp);
fread(&vertex->vertex.z, 4, 1, fp);
fread(&vertex->jointIndex, 1, 1, fp);
fread(&vertex->unused, 1, 1, fp);
}
// read triangle definitions
fread(&m_numTriangles, 2, 1, fp);
m_triangles = new Ms3dTriangle[m_numTriangles];
for (int i = 0; i < m_numTriangles; ++i)
{
Ms3dTriangle *triangle = &m_triangles[i];
fread(&triangle->editorFlags, 2, 1, fp);
for (int j = 0; j < 3; ++j)
fread(&triangle->vertices[j], 2, 1, fp);
for (int j = 0; j < 3; ++j)
{
fread(&triangle->normals[j].x, 4, 1, fp);
fread(&triangle->normals[j].y, 4, 1, fp);
fread(&triangle->normals[j].z, 4, 1, fp);
}
for (int j = 0; j < 3; ++j)
fread(&triangle->texCoords[j].x, 4, 1, fp);
for (int j = 0; j < 3; ++j)
fread(&triangle->texCoords[j].y, 4, 1, fp);
fread(&triangle->smoothingGroup, 1, 1, fp);
fread(&triangle->meshIndex, 1, 1, fp);
}
// read mesh information
fread(&m_numMeshes, 2, 1, fp);
m_meshes = new Ms3dMesh[m_numMeshes];
for (int i = 0; i < m_numMeshes; ++i)
{
Ms3dMesh *mesh = &m_meshes[i];
fread(&mesh->editorFlags, 1, 1, fp);
ReadString(fp, mesh->name, 32);
fread(&mesh->numTriangles, 2, 1, fp);
mesh->triangles = new unsigned short[mesh->numTriangles];
for (int j = 0; j < mesh->numTriangles; ++j)
fread(&mesh->triangles[j], 2, 1, fp);
fread(&mesh->materialIndex, 1, 1, fp);
}
// read material information
fread(&m_numMaterials, 2, 1, fp);
if (m_numMaterials > 0)
{
m_materials = new Ms3dMaterial[m_numMaterials];
for (int i = 0; i < m_numMaterials; ++i)
{
Ms3dMaterial *material = &m_materials[i];
ReadString(fp, material->name, 32);
for (int j = 0; j < 4; ++j)
fread(&material->ambient[j], 4, 1, fp);
for (int j = 0; j < 4; ++j)
fread(&material->diffuse[j], 4, 1, fp);
for (int j = 0; j < 4; ++j)
fread(&material->specular[j], 4, 1, fp);
for (int j = 0; j < 4; ++j)
fread(&material->emissive[j], 4, 1, fp);
fread(&material->shininess, 4, 1, fp);
fread(&material->transparency, 4, 1, fp);
fread(&material->mode, 1, 1, fp);
ReadString(fp, material->texture, 128);
ReadString(fp, material->alpha, 128);
}
}
// read joints
fread(&m_animationFps, 4, 1, fp);
fread(&m_editorAnimationTime, 4, 1, fp);
fread(&m_numFrames, 4, 1, fp);
fread(&m_numJoints, 2, 1, fp);
if (m_numJoints > 0)
{
m_joints = new Ms3dJoint[m_numJoints];
for (int i = 0; i < m_numJoints; ++i)
{
Ms3dJoint *joint = &m_joints[i];
fread(&joint->editorFlags, 1, 1, fp);
ReadString(fp, joint->name, 32);
ReadString(fp, joint->parentName, 32);
fread(&joint->rotation.x, 4, 1, fp);
fread(&joint->rotation.y, 4, 1, fp);
fread(&joint->rotation.z, 4, 1, fp);
fread(&joint->position.x, 4, 1, fp);
fread(&joint->position.y, 4, 1, fp);
fread(&joint->position.z, 4, 1, fp);
fread(&joint->numRotationFrames, 2, 1, fp);
fread(&joint->numTranslationFrames, 2, 1, fp);
joint->rotationFrames = new Ms3dKeyFrame[joint->numRotationFrames];
for (int j = 0; j < joint->numRotationFrames; ++j)
{
Ms3dKeyFrame *frame = &joint->rotationFrames[j];
fread(&frame->time, 4, 1, fp);
fread(&frame->param.x, 4, 1, fp);
fread(&frame->param.y, 4, 1, fp);
fread(&frame->param.z, 4, 1, fp);
}
joint->translationFrames = new Ms3dKeyFrame[joint->numTranslationFrames];
for (int j = 0; j < joint->numTranslationFrames; ++j)
{
Ms3dKeyFrame *frame = &joint->translationFrames[j];
fread(&frame->time, 4, 1, fp);
fread(&frame->param.x, 4, 1, fp);
fread(&frame->param.y, 4, 1, fp);
fread(&frame->param.z, 4, 1, fp);
}
}
}
fclose(fp);
// check for an animation definition file
std::string animationFile = file;
animationFile.erase(animationFile.find_last_of('.', std::string::npos));
animationFile.append(".animations");
fp = fopen(animationFile.c_str(), "r");
if (fp != NULL)
{
char *buffer = new char[80];
std::string line;
std::string name;
std::string temp;
int start;
int end;
while (!feof(fp))
{
fgets(buffer, 80, fp);
line = buffer;
if (strlen(buffer) > 5) // minimum length for a viable frame definition
{
// get animation name
int nameEnd = line.find_first_of(',');
if (nameEnd == std::string::npos)
continue;
name = line.substr(0, nameEnd);
// get start frame index
int startEnd = line.find_first_of(',', nameEnd + 1);
if (startEnd == std::string::npos)
continue;
temp = line.substr(nameEnd + 1, startEnd);
start = atoi(temp.c_str());
// get end frame index
temp = line.substr(startEnd + 1, std::string::npos);
end = atoi(temp.c_str());
Ms3dAnimation *animation = new Ms3dAnimation();
animation->name = name;
animation->startFrame = start;
animation->endFrame = end;
m_animations.push_back(*animation);
}
}
delete[] buffer;
fclose(fp);
}
return true;
}
bool Ms3d::ConvertToMesh(const std::string &file, float scaleFactor)
{
FILE *fp = fopen(file.c_str(), "wb");
if (fp == NULL)
return false;
fputs("MESH", fp);
unsigned char version = 1;
fwrite(&version, 1, 1, fp);
// vertices chunk
fputs("VTX", fp);
long numVertices = m_numVertices;
long sizeOfVertices = ((sizeof(float) * 3)) * numVertices + sizeof(long);
fwrite(&sizeOfVertices, sizeof(long), 1, fp);
fwrite(&numVertices, sizeof(long), 1, fp);
for (long i = 0; i < numVertices; ++i)
{
Ms3dVertex *vertex = &m_vertices[i];
vertex->vertex *= scaleFactor;
fwrite(&vertex->vertex.x, sizeof(float), 1, fp);
fwrite(&vertex->vertex.y, sizeof(float), 1, fp);
fwrite(&vertex->vertex.z, sizeof(float), 1, fp);
}
// triangles chunk
fputs("TRI", fp);
long numTriangles = m_numTriangles;
long sizeOfTriangles = (sizeof(int) * 4 + (sizeof(float) * 3) * 3 + (sizeof(float) * 2) * 3) * numTriangles + sizeof(long);
fwrite(&sizeOfTriangles, sizeof(long), 1, fp);
fwrite(&numTriangles, sizeof(long), 1, fp);
for (long i = 0; i < numTriangles; ++i)
{
Ms3dTriangle *triangle = &m_triangles[i];
int index = triangle->vertices[0];
fwrite(&index, sizeof(int), 1, fp);
index = triangle->vertices[1];
fwrite(&index, sizeof(int), 1, fp);
index = triangle->vertices[2];
fwrite(&index, sizeof(int), 1, fp);
index = triangle->meshIndex;
fwrite(&index, sizeof(int), 1, fp);
for (int j = 0; j < 3; ++j)
{
fwrite(&triangle->normals[j].x, sizeof(float), 1, fp);
fwrite(&triangle->normals[j].y, sizeof(float), 1, fp);
fwrite(&triangle->normals[j].z, sizeof(float), 1, fp);
}
for (int j = 0; j < 3; ++j)
{
fwrite(&triangle->texCoords[j].x, sizeof(float), 1, fp);
fwrite(&triangle->texCoords[j].y, sizeof(float), 1, fp);
}
}
// sub-meshes / groups chunk
fputs("GRP", fp);
long numGroups = m_numMeshes;
long sizeOfGroupNames = 0;
for (long i = 0; i < numGroups; ++i)
sizeOfGroupNames += (m_meshes[i].name.length() + 1);
long sizeOfGroups = sizeOfGroupNames + (sizeof(int)) * numGroups + sizeof(long);
fwrite(&sizeOfGroups, sizeof(long), 1, fp);
fwrite(&numGroups, sizeof(long), 1, fp);
for (long i = 0; i < numGroups; ++i)
{
Ms3dMesh *mesh = &m_meshes[i];
fwrite(mesh->name.c_str(), mesh->name.length(), 1, fp);
char c = '\0';
fwrite(&c, 1, 1, fp);
int numTriangles = mesh->numTriangles;
fwrite(&numTriangles, sizeof(int), 1, fp);
}
// joints chunk
fputs("JNT", fp);
long numJoints = m_numJoints;
long sizeOfJointNames = 0;
for (long i = 0; i < numJoints; ++i)
sizeOfJointNames += (m_joints[i].name.length() + 1);
long sizeOfJoints = sizeOfJointNames + (sizeof(int) + sizeof(float) * 3 + sizeof(float) * 3) * numJoints + sizeof(long);
fwrite(&sizeOfJoints, sizeof(long), 1, fp);
fwrite(&numJoints, sizeof(long), 1, fp);
for (long i = 0; i < numJoints; ++i)
{
Ms3dJoint *joint = &m_joints[i];
joint->position *= scaleFactor;
fwrite(joint->name.c_str(), joint->name.length(), 1, fp);
char c = '\0';
fwrite(&c, 1, 1, fp);
int parentIndex = FindIndexOfJoint(joint->parentName);
fwrite(&parentIndex, sizeof(int), 1, fp);
fwrite(&joint->position.x, sizeof(float), 1, fp);
fwrite(&joint->position.y, sizeof(float), 1, fp);
fwrite(&joint->position.z, sizeof(float), 1, fp);
fwrite(&joint->rotation.x, sizeof(float), 1, fp);
fwrite(&joint->rotation.y, sizeof(float), 1, fp);
fwrite(&joint->rotation.z, sizeof(float), 1, fp);
}
// joints to vertices mapping chunk
fputs("JTV", fp);
long numMappings = numVertices;
long sizeOfJointMappings = (sizeof(int) + sizeof(float)) * numMappings + sizeof(long);
fwrite(&sizeOfJointMappings, sizeof(long), 1, fp);
fwrite(&numMappings, sizeof(long), 1, fp);
for (long i = 0; i < numMappings; ++i)
{
Ms3dVertex *vertex = &m_vertices[i];
int jointIndex = vertex->jointIndex;
fwrite(&jointIndex, sizeof(int), 1, fp);
float weight = 1.0f;
fwrite(&weight, sizeof(float), 1, fp);
}
// joint animation keyframes
fputs("JKF", fp);
long numFrames = m_numFrames;
long sizeOfJointFrames = ((6 * sizeof(float)) * m_numJoints) * numFrames + sizeof(long);
fwrite(&sizeOfJointFrames, sizeof(long), 1, fp);
fwrite(&numFrames, sizeof(long), 1, fp);
for (long i = 0; i < numFrames; ++i)
{
for (int j = 0; j < m_numJoints; ++j)
{
Ms3dJoint *joint = &m_joints[j];
Ms3dKeyFrame *position;
Ms3dKeyFrame *rotation;
if (i >= joint->numTranslationFrames)
position = &joint->translationFrames[0];
else
position = &joint->translationFrames[i];
if (i >= joint->numRotationFrames)
rotation = &joint->rotationFrames[0];
else
rotation = &joint->rotationFrames[i];
position->param *= scaleFactor;
fwrite(&position->param.x, sizeof(float), 1, fp);
fwrite(&position->param.y, sizeof(float), 1, fp);
fwrite(&position->param.z, sizeof(float), 1, fp);
fwrite(&rotation->param.x, sizeof(float), 1, fp);
fwrite(&rotation->param.y, sizeof(float), 1, fp);
fwrite(&rotation->param.z, sizeof(float), 1, fp);
}
}
if (m_animations.size() > 0)
{
// figure out the size of all the animation name strings
long sizeofNames = 0;
for (unsigned int i = 0; i < m_animations.size(); ++i)
sizeofNames += m_animations[i].name.length() + 1;
// animations chunk
fputs("ANI", fp);
long numAnimations = m_animations.size();
long sizeofAnimations = (sizeof(long) * 2) * numAnimations + sizeofNames + sizeof(long);
fwrite(&sizeofAnimations, sizeof(long), 1, fp);
fwrite(&numAnimations, sizeof(long), 1, fp);
for (long i = 0; i < numAnimations; ++i)
{
long data;
const Ms3dAnimation *animation = &m_animations[i];
//fputs(animation->name.c_str(), fp);
fputs(animation->name.c_str(), fp);
fwrite("\0", 1, 1, fp);
data = animation->startFrame;
fwrite(&data, sizeof(long), 1, fp);
data = animation->endFrame;
fwrite(&data, sizeof(long), 1, fp);
}
}
fclose(fp);
return true;
}
int Ms3d::FindIndexOfJoint(const std::string &jointName)
{
if (jointName.length() == 0)
return -1;
for (int i = 0; i < m_numJoints; ++i)
{
Ms3dJoint *joint = &m_joints[i];
if (joint->name == jointName)
return i;
}
return -1;
}

146
src/ms3d/ms3d.h Normal file
View file

@ -0,0 +1,146 @@
#ifndef __MS3D_H_INCLUDED__
#define __MS3D_H_INCLUDED__
#include <string>
#include "../geometry/vector3.h"
#include "../geometry/vector2.h"
#include <vector>
struct Ms3dHeader
{
char id[10];
long version;
};
struct Ms3dVertex
{
unsigned char editorFlags;
Vector3 vertex;
char jointIndex;
unsigned char unused;
};
struct Ms3dTriangle
{
unsigned short editorFlags;
unsigned short vertices[3];
Vector3 normals[3];
Vector2 texCoords[3];
unsigned char smoothingGroup;
unsigned char meshIndex;
};
struct Ms3dMesh
{
unsigned char editorFlags;
std::string name;
unsigned short numTriangles;
unsigned short *triangles;
char materialIndex;
Ms3dMesh()
{
triangles = NULL;
}
~Ms3dMesh()
{
delete[] triangles;
}
};
struct Ms3dMaterial
{
std::string name;
float ambient[4];
float diffuse[4];
float specular[4];
float emissive[4];
float shininess;
float transparency;
char mode;
std::string texture;
std::string alpha;
};
struct Ms3dKeyFrame
{
float time;
Vector3 param;
};
struct Ms3dJoint
{
unsigned char editorFlags;
std::string name;
std::string parentName;
Vector3 rotation;
Vector3 position;
unsigned short numRotationFrames;
unsigned short numTranslationFrames;
Ms3dKeyFrame *rotationFrames;
Ms3dKeyFrame *translationFrames;
Ms3dJoint()
{
rotationFrames = NULL;
translationFrames = NULL;
}
~Ms3dJoint()
{
delete[] rotationFrames;
delete[] translationFrames;
}
};
struct Ms3dAnimation
{
std::string name;
unsigned int startFrame;
unsigned int endFrame;
};
class Ms3d
{
public:
Ms3d();
virtual ~Ms3d() { Release(); }
void Release();
bool Load(const std::string &file);
bool ConvertToMesh(const std::string &file, float scaleFactor);
unsigned short GetNumVertices() { return m_numVertices; }
unsigned short GetNumTriangles() { return m_numTriangles; }
unsigned short GetNumMeshes() { return m_numMeshes; }
unsigned short GetNumMaterials() { return m_numMaterials; }
unsigned short GetNumJoints() { return m_numJoints; }
float GetAnimationFps() { return m_animationFps; }
int GetNumFrames() { return m_numFrames; }
Ms3dVertex* GetVertices() { return m_vertices; }
Ms3dTriangle* GetTriangles() { return m_triangles; }
Ms3dMesh* GetMeshes() { return m_meshes; }
Ms3dMaterial* GetMaterials() { return m_materials; }
Ms3dJoint* GetJoints() { return m_joints; }
private:
int FindIndexOfJoint(const std::string &jointName);
unsigned short m_numVertices;
unsigned short m_numTriangles;
unsigned short m_numMeshes;
unsigned short m_numMaterials;
unsigned short m_numJoints;
float m_animationFps;
float m_editorAnimationTime;
int m_numFrames;
Ms3dVertex *m_vertices;
Ms3dTriangle *m_triangles;
Ms3dMesh *m_meshes;
Ms3dMaterial *m_materials;
Ms3dJoint *m_joints;
std::vector<Ms3dAnimation> m_animations;
};
#endif

25
src/util/files.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "files.h"
void ReadString(FILE *fp, std::string &buffer, int fixedLength)
{
char c;
if (fixedLength > 0)
{
for (int i = 0; i < fixedLength; ++i)
{
fread(&c, 1, 1, fp);
if (c != '\0')
buffer += c;
}
}
else
{
do
{
fread(&c, 1, 1, fp);
if (c != '\0')
buffer += c;
} while (c != '\0');
}
}

9
src/util/files.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __UTIL_FILES_H_INCLUDED__
#define __UTIL_FILES_H_INCLUDED__
#include <stdio.h>
#include <string>
void ReadString(FILE *fp, std::string &buffer, int fixedLength = 0);
#endif