initial commit (based on MeshConverter source)
This commit is contained in:
commit
3e28e22b6e
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal 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
3
generate_makefile.sh
Normal 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
8
generate_vs2010.bat
Normal 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
63
premake.lua
Normal 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
11
src/geometry/vector2.h
Normal 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
319
src/geometry/vector3.h
Normal 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
85
src/main.cpp
Normal 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
443
src/ms3d/ms3d.cpp
Normal 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
146
src/ms3d/ms3d.h
Normal 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
25
src/util/files.cpp
Normal 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
9
src/util/files.h
Normal 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
|
Reference in a new issue