removed all other model import/exporting except for md2
This commit is contained in:
parent
3b29691ce7
commit
b5b9558432
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -7,4 +7,4 @@ Debug/
|
|||
Release/
|
||||
ipch/
|
||||
*.suo
|
||||
meshconverter
|
||||
md2tomesh
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
# this Makefile is based on the ones from devkitPro
|
||||
# TODO: probably should simplify it a bunch (mainly the rules at the bottom)
|
||||
|
||||
TARGET := meshconverter
|
||||
TARGET := md2tomesh
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
#ifndef __ASSETS_COLOR_H_INCLUDED__
|
||||
#define __ASSETS_COLOR_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
#define COLOR_ALPHA_TRANSPARENT 0.0f
|
||||
#define COLOR_ALPHA_OPAQUE 1.0f
|
||||
|
||||
class Color
|
||||
{
|
||||
public:
|
||||
Color()
|
||||
{
|
||||
r = 0.0f;
|
||||
g = 0.0f;
|
||||
b = 0.0f;
|
||||
a = COLOR_ALPHA_OPAQUE;
|
||||
}
|
||||
|
||||
Color(float red, float green, float blue)
|
||||
{
|
||||
r = red;
|
||||
g = green;
|
||||
b = blue;
|
||||
a = COLOR_ALPHA_OPAQUE;
|
||||
}
|
||||
|
||||
Color(float red, float green, float blue, float alpha)
|
||||
{
|
||||
r = red;
|
||||
g = green;
|
||||
b = blue;
|
||||
a = alpha;
|
||||
}
|
||||
|
||||
uint32_t ToInt()
|
||||
{
|
||||
return ((uint32_t)(a * 255) << 24) | ((uint32_t)(r * 255) << 16) | ((uint32_t)(g * 255) << 8) | (uint32_t)(b * 255);
|
||||
}
|
||||
|
||||
static uint32_t ToInt(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
static uint32_t ToInt(float r, float g, float b, float a)
|
||||
{
|
||||
return ((int)(a * 255) << 24) | ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255);
|
||||
}
|
||||
|
||||
static void FromInt(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a)
|
||||
{
|
||||
*a = (color & 0xff000000) >> 24;
|
||||
*r = (color & 0x00ff0000) >> 16;
|
||||
*g = (color & 0x0000ff00) >> 8;
|
||||
*b = (color & 0x000000ff);
|
||||
}
|
||||
|
||||
static void FromInt(uint32_t color, float *r, float *g, float *b, float *a)
|
||||
{
|
||||
*a = ((float)((color & 0xff000000) >> 24)) / 255;
|
||||
*r = ((float)((color & 0x00ff0000) >> 16)) / 255;
|
||||
*g = ((float)((color & 0x0000ff00) >> 8)) / 255;
|
||||
*b = ((float)((color & 0x000000ff))) / 255;
|
||||
}
|
||||
|
||||
static Color FromInt(uint32_t color)
|
||||
{
|
||||
Color out;
|
||||
FromInt(color, &out.r, &out.g, &out.b, &out.a);
|
||||
return out;
|
||||
}
|
||||
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef __ASSETS_MATERIAL_H_INCLUDED__
|
||||
#define __ASSETS_MATERIAL_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
#include <string>
|
||||
#include "color.h"
|
||||
|
||||
#define RGB_32(r, g, b, a) ((b)|((g) << 8)|((r) << 16)|((a) << 24))
|
||||
#define RGB_24(r, g, b) ((b)|((g) << 8)|((r) << 16))
|
||||
#define RGB_32_f(r, g, b, a) RGB_32((int)((r) * 255), (int)((g) * 255), (int)((b) * 255), (int)((a) * 255))
|
||||
#define RGB_24_f(r, g, b) RGB_24((int)((r) * 255), (int)((g) * 255), (int)((b) * 255))
|
||||
|
||||
class Material
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::string textureFile;
|
||||
Color ambient;
|
||||
Color diffuse;
|
||||
Color specular;
|
||||
Color emissive;
|
||||
float shininess;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -7,44 +7,6 @@ void WriteFileHeader(FILE *fp)
|
|||
fwrite(&version, 1, 1, fp);
|
||||
}
|
||||
|
||||
void WriteChunk(VerticesChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
fputs("VTX", fp);
|
||||
fwrite(&size, 4, 1, fp);
|
||||
uint32_t count = chunk->GetCount();
|
||||
fwrite(&count, 4, 1, fp);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
fwrite(&chunk->vertices[i].x, sizeof(float), 1, fp);
|
||||
fwrite(&chunk->vertices[i].y, sizeof(float), 1, fp);
|
||||
fwrite(&chunk->vertices[i].z, sizeof(float), 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteChunk(NormalsChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
fputs("NRL", fp);
|
||||
fwrite(&size, 4, 1, fp);
|
||||
uint32_t count = chunk->GetCount();
|
||||
fwrite(&count, 4, 1, fp);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
fwrite(&chunk->normals[i].x, sizeof(float), 1, fp);
|
||||
fwrite(&chunk->normals[i].y, sizeof(float), 1, fp);
|
||||
fwrite(&chunk->normals[i].z, sizeof(float), 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteChunk(TexCoordsChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
|
@ -63,82 +25,6 @@ void WriteChunk(TexCoordsChunk *chunk, FILE *fp)
|
|||
}
|
||||
}
|
||||
|
||||
void WriteChunk(MaterialsChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
fputs("MTL", fp);
|
||||
fwrite(&size, 4, 1, fp);
|
||||
uint32_t count = chunk->GetCount();
|
||||
fwrite(&count, 4, 1, fp);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
Material *m = &chunk->materials[i];
|
||||
|
||||
fwrite(m->name.c_str(), m->name.length(), 1, fp);
|
||||
char ch = '\0';
|
||||
fwrite(&ch, 1, 1, fp);
|
||||
|
||||
fwrite(&m->ambient.r, sizeof(float), 1, fp);
|
||||
fwrite(&m->ambient.g, sizeof(float), 1, fp);
|
||||
fwrite(&m->ambient.b, sizeof(float), 1, fp);
|
||||
fwrite(&m->ambient.a, sizeof(float), 1, fp);
|
||||
|
||||
fwrite(&m->diffuse.r, sizeof(float), 1, fp);
|
||||
fwrite(&m->diffuse.g, sizeof(float), 1, fp);
|
||||
fwrite(&m->diffuse.b, sizeof(float), 1, fp);
|
||||
fwrite(&m->diffuse.a, sizeof(float), 1, fp);
|
||||
|
||||
fwrite(&m->specular.r, sizeof(float), 1, fp);
|
||||
fwrite(&m->specular.g, sizeof(float), 1, fp);
|
||||
fwrite(&m->specular.b, sizeof(float), 1, fp);
|
||||
fwrite(&m->specular.a, sizeof(float), 1, fp);
|
||||
|
||||
fwrite(&m->emissive.r, sizeof(float), 1, fp);
|
||||
fwrite(&m->emissive.g, sizeof(float), 1, fp);
|
||||
fwrite(&m->emissive.b, sizeof(float), 1, fp);
|
||||
fwrite(&m->emissive.a, sizeof(float), 1, fp);
|
||||
|
||||
fwrite(&m->shininess, sizeof(float), 1, fp);
|
||||
|
||||
fwrite(&m->opacity, sizeof(float), 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteChunk(TrianglesChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
fputs("TRI", fp);
|
||||
fwrite(&size, 4, 1, fp);
|
||||
uint32_t count = chunk->GetCount();
|
||||
fwrite(&count, 4, 1, fp);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
Triangle *t = &chunk->triangles[i];
|
||||
|
||||
fwrite(&t->vertices[0], 4, 1, fp);
|
||||
fwrite(&t->vertices[1], 4, 1, fp);
|
||||
fwrite(&t->vertices[2], 4, 1, fp);
|
||||
|
||||
fwrite(&t->normals[0], 4, 1, fp);
|
||||
fwrite(&t->normals[1], 4, 1, fp);
|
||||
fwrite(&t->normals[2], 4, 1, fp);
|
||||
|
||||
fwrite(&t->texCoords[0], 4, 1, fp);
|
||||
fwrite(&t->texCoords[1], 4, 1, fp);
|
||||
fwrite(&t->texCoords[2], 4, 1, fp);
|
||||
|
||||
fwrite(&t->materialIndex, 4, 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteChunk(KeyFramesChunk *chunk, FILE *fp)
|
||||
{
|
||||
uint32_t size = chunk->GetSize();
|
||||
|
@ -219,3 +105,4 @@ void WriteChunk(AnimationsChunk *chunk, FILE *fp)
|
|||
fwrite(&a->end, 4, 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,20 +8,12 @@ void WriteFileHeader(FILE *fp);
|
|||
|
||||
// to be perfectly honest, i don't care to come up with a really elegant solution for this converter tool :p
|
||||
|
||||
#include "vertices.h"
|
||||
#include "normals.h"
|
||||
#include "texcoords.h"
|
||||
#include "materials.h"
|
||||
#include "triangles.h"
|
||||
#include "keyframes.h"
|
||||
#include "keyframetriangles.h"
|
||||
#include "animations.h"
|
||||
|
||||
void WriteChunk(VerticesChunk *chunk, FILE *fp);
|
||||
void WriteChunk(NormalsChunk *chunk, FILE *fp);
|
||||
void WriteChunk(TexCoordsChunk *chunk, FILE *fp);
|
||||
void WriteChunk(MaterialsChunk *chunk, FILE *fp);
|
||||
void WriteChunk(TrianglesChunk *chunk, FILE *fp);
|
||||
void WriteChunk(KeyFramesChunk *chunk, FILE *fp);
|
||||
void WriteChunk(KeyFrameTrianglesChunk *chunk, FILE *fp);
|
||||
void WriteChunk(AnimationsChunk *chunk, FILE *fp);
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef __CHUNK_MATERIALS_H_INCLUDED__
|
||||
#define __CHUNK_MATERIALS_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
#include "../assets/material.h"
|
||||
#include <vector>
|
||||
|
||||
struct MaterialsChunk
|
||||
{
|
||||
std::vector<Material> materials;
|
||||
|
||||
uint32_t GetCount()
|
||||
{
|
||||
return materials.size();
|
||||
}
|
||||
|
||||
uint32_t GetSize()
|
||||
{
|
||||
if (materials.size() == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t size = 4; // count
|
||||
for (uint32_t i = 0; i < materials.size(); ++i)
|
||||
{
|
||||
size += materials[i].name.length() + 1; // include null terminator
|
||||
size += sizeof(float) * 4; // ambient
|
||||
size += sizeof(float) * 4; // diffuse
|
||||
size += sizeof(float) * 4; // specular
|
||||
size += sizeof(float) * 4; // emissive
|
||||
size += sizeof(float); // shininess
|
||||
size += sizeof(float); // opacity
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef __CHUNKS_NORMALS_H_INCLUDED__
|
||||
#define __CHUNKS_NORMALS_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
#include "../geometry/vector3.h"
|
||||
#include <vector>
|
||||
|
||||
struct NormalsChunk
|
||||
{
|
||||
std::vector<Vector3> normals;
|
||||
|
||||
uint32_t GetCount()
|
||||
{
|
||||
return normals.size();
|
||||
}
|
||||
|
||||
uint32_t GetSize()
|
||||
{
|
||||
if (normals.size() == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t size = 4; // count
|
||||
size +=
|
||||
(sizeof(float) * 3) // x, y, z
|
||||
* normals.size();
|
||||
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef __CHUNKS_TRIANGLES_H_INCLUDED__
|
||||
#define __CHUNKS_TRIANGLES_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
#include "../geometry/triangle.h"
|
||||
#include <vector>
|
||||
|
||||
struct TrianglesChunk
|
||||
{
|
||||
std::vector<Triangle> triangles;
|
||||
|
||||
uint32_t GetCount()
|
||||
{
|
||||
return triangles.size();
|
||||
}
|
||||
|
||||
uint32_t GetSize()
|
||||
{
|
||||
if (triangles.size() == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t size = 4; // count
|
||||
size +=
|
||||
(
|
||||
(4 * 3) // vertex indices
|
||||
+ (4 * 3) // normal indices
|
||||
+ (4 * 3) // texcoord indices
|
||||
+ 4 // material index
|
||||
) * triangles.size();
|
||||
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef __CHUNKS_VERTICES_H_INCLUDED__
|
||||
#define __CHUNKS_VERTICES_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
#include "../geometry/vector3.h"
|
||||
#include <vector>
|
||||
|
||||
struct VerticesChunk
|
||||
{
|
||||
std::vector<Vector3> vertices;
|
||||
|
||||
uint32_t GetCount()
|
||||
{
|
||||
return vertices.size();
|
||||
}
|
||||
|
||||
uint32_t GetSize()
|
||||
{
|
||||
if (vertices.size() == 0)
|
||||
return 0;
|
||||
|
||||
uint32_t size = 4; // count
|
||||
size +=
|
||||
(sizeof(float) * 3) // x, y, z
|
||||
* vertices.size();
|
||||
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,491 +0,0 @@
|
|||
#ifndef __GEOMETRY_QUATERNION_H_INCLUDED__
|
||||
#define __GEOMETRY_QUATERNION_H_INCLUDED__
|
||||
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
#include "vector3.h"
|
||||
#include "matrix4x4.h"
|
||||
|
||||
/**
|
||||
* Represents a quaternion to store an orientation or angular
|
||||
* displacement and provides methods for conversion/manipulation
|
||||
* <p>Referenced/based on code from:</p>
|
||||
* <ul>
|
||||
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
|
||||
* <li>More OpenGL Game Programming (Dave Astle, 2006)</li>
|
||||
* <li>http://www.dhpoware.com/source/mathlib.html</li>
|
||||
* </ul>
|
||||
* @author Gered
|
||||
*/
|
||||
class Quaternion
|
||||
{
|
||||
public:
|
||||
Quaternion() {}
|
||||
|
||||
Quaternion(float w, float x, float y, float z)
|
||||
{
|
||||
this->w = w;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
Quaternion(float w, const Vector3 &v)
|
||||
{
|
||||
this->w = w;
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
this->z = v.z;
|
||||
}
|
||||
|
||||
Quaternion(const float *q)
|
||||
{
|
||||
w = q[0];
|
||||
x = q[1];
|
||||
y = q[2];
|
||||
z = q[3];
|
||||
}
|
||||
|
||||
~Quaternion() {}
|
||||
|
||||
void Set(float w, float x, float y, float z);
|
||||
Matrix4x4 ToMatrix() const;
|
||||
Vector3 GetVector() const;
|
||||
|
||||
static Quaternion Cross(const Quaternion &a, const Quaternion &b);
|
||||
static float Dot(const Quaternion &a, const Quaternion &b);
|
||||
static float Length(const Quaternion &q);
|
||||
static float LengthSquared(const Quaternion &q);
|
||||
static Quaternion Normalize(const Quaternion &q);
|
||||
static Quaternion Conjugate(const Quaternion &q);
|
||||
static Quaternion Inverse(const Quaternion &q);
|
||||
static Quaternion CreateFromEulerAngles(float x, float y, float z);
|
||||
static Quaternion CreateFromAxisAngle(float angle, const Vector3 &axis);
|
||||
static Quaternion CreateFromRotationMatrix(const Matrix4x4 &matrix);
|
||||
static void ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis);
|
||||
static Quaternion Lerp(const Quaternion &a, const Quaternion &b, float interpolation);
|
||||
static Quaternion Slerp(const Quaternion &a, const Quaternion &b, float interpolation);
|
||||
|
||||
float w;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
Quaternion operator+(const Quaternion &left, const Quaternion &right);
|
||||
Quaternion &operator+=(Quaternion &left, const Quaternion &right);
|
||||
Quaternion operator-(const Quaternion &left, const Quaternion &right);
|
||||
Quaternion &operator-=(Quaternion &left, const Quaternion &right);
|
||||
Quaternion operator*(const Quaternion &left, float right);
|
||||
Quaternion &operator*=(Quaternion &left, float right);
|
||||
Quaternion operator*(const Quaternion &left, const Quaternion &right);
|
||||
Quaternion &operator*=(Quaternion &left, const Quaternion &right);
|
||||
Quaternion operator/(const Quaternion &left, float right);
|
||||
Quaternion &operator/=(Quaternion &left, float right);
|
||||
Vector3 operator*(const Vector3 &left, const Quaternion &right);
|
||||
|
||||
#define IDENTITY_QUATERNION Quaternion(1.0f, 0.0f, 0.0f, 0.0f)
|
||||
|
||||
inline void Quaternion::Set(float w, float x, float y, float z)
|
||||
{
|
||||
this->w = w;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a quaternion to a rotation matrix
|
||||
* @return Matrix4x4
|
||||
*/
|
||||
inline Matrix4x4 Quaternion::ToMatrix() const
|
||||
{
|
||||
Matrix4x4 output;
|
||||
|
||||
output.m[_11] = 1.0f - (2.0f * ((y * y) + (z * z)));
|
||||
output.m[_21] = 2.0f * ((x * y) + (z * w));
|
||||
output.m[_31] = 2.0f * ((z * x) - (y * w));
|
||||
output.m[_41] = 0.0f;
|
||||
|
||||
output.m[_12] = 2.0f * ((x * y) - (z * w));
|
||||
output.m[_22] = 1.0f - (2.0f * ((z * z) + (x * x)));
|
||||
output.m[_32] = 2.0f * ((y * z) + (x * w));
|
||||
output.m[_42] = 0.0f;
|
||||
|
||||
output.m[_13] = 2.0f * ((z * x) + (y * w));
|
||||
output.m[_23] = 2.0f * ((y * z) - (x * w));
|
||||
output.m[_33] = 1.0f - (2.0f * ((y * y) + (x * x)));
|
||||
output.m[_43] = 0.0f;
|
||||
|
||||
output.m[_14] = 0.0f;
|
||||
output.m[_24] = 0.0f;
|
||||
output.m[_34] = 0.0f;
|
||||
output.m[_44] = 1.0f;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vector3 the vector component of the quaternion.
|
||||
*/
|
||||
inline Vector3 Quaternion::GetVector() const
|
||||
{
|
||||
return Vector3(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cross product of two quaternions
|
||||
* @param a first quaternion
|
||||
* @param b second quaternion
|
||||
* @return Quaternion the cross product
|
||||
*/
|
||||
inline Quaternion Quaternion::Cross(const Quaternion &a, const Quaternion &b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the dot product of 2 quaternions.
|
||||
* @param a first quaternion
|
||||
* @param b second quaternion
|
||||
* @return float the dot product
|
||||
*/
|
||||
inline float Quaternion::Dot(const Quaternion &a, const Quaternion &b)
|
||||
{
|
||||
return (a.w * b.w) + (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the length (magnitude) of a quaternion.
|
||||
* @param q quaternion to retrieve the length of
|
||||
* @return float the length
|
||||
*/
|
||||
inline float Quaternion::Length(const Quaternion &q)
|
||||
{
|
||||
return sqrtf((q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the squared length of a quaternion (the length minus the
|
||||
* sqrt call).
|
||||
* @param q quaternion to retrieve the squared length of
|
||||
* @return float the squared length
|
||||
*/
|
||||
inline float Quaternion::LengthSquared(const Quaternion &q)
|
||||
{
|
||||
return (q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a quaternion (only if necessary)
|
||||
* @param q quaternion to be normalized
|
||||
* @return Quaternion normalized quaternion
|
||||
*/
|
||||
inline Quaternion Quaternion::Normalize(const Quaternion &q)
|
||||
{
|
||||
float inverseLength = 1.0f / Length(q);
|
||||
return Quaternion(
|
||||
q.w * inverseLength,
|
||||
q.x * inverseLength,
|
||||
q.y * inverseLength,
|
||||
q.z * inverseLength
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the conjugate of a quaternion. If the quaternion
|
||||
* is unit length, this also returns the inverse.
|
||||
* @param q quaternion to retrieve the conjugate of
|
||||
* @return Quaternion conjugate
|
||||
*/
|
||||
inline Quaternion Quaternion::Conjugate(const Quaternion &q)
|
||||
{
|
||||
return Quaternion(q.w, -q.x, -q.y, -q.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the inverse of a given quaternion
|
||||
* @param q quaternion to retrieve the inverse of
|
||||
* @return Quaternion inverse of the quaternion
|
||||
*/
|
||||
inline Quaternion Quaternion::Inverse(const Quaternion &q)
|
||||
{
|
||||
float inverseSquaredLength = 1.0f / LengthSquared(q);
|
||||
return Quaternion(
|
||||
q.w * inverseSquaredLength,
|
||||
-q.x * inverseSquaredLength,
|
||||
-q.y * inverseSquaredLength,
|
||||
-q.z * inverseSquaredLength
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts euler angles to a quaternion
|
||||
* @param x x angle of rotation (specified in radians)
|
||||
* @param y y angle of rotation (specified in radians)
|
||||
* @param z z angle of rotation (specified in radians)
|
||||
* @return Quaternion quaternion equivalent to the euler angle
|
||||
* orientation
|
||||
*/
|
||||
inline Quaternion Quaternion::CreateFromEulerAngles(float x, float y, float z)
|
||||
{
|
||||
Quaternion qx(cosf(x / 2.0f), sinf(x / 2.0f), 0.0f, 0.0f);
|
||||
Quaternion qy(cosf(y / 2.0f), 0.0f, sinf(y / 2.0f), 0.0f);
|
||||
Quaternion qz(cosf(z / 2.0f), 0.0f, 0.0f, sinf(z / 2.0f));
|
||||
|
||||
return Normalize(qz * qy * qx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an axis angle to a quaternion
|
||||
* @param angle the angle to rotate be (specified in radians)
|
||||
* @param axis the axis being rotated about
|
||||
* @return Quaternion quaternion equivalent to the axis angle
|
||||
* orientation
|
||||
*/
|
||||
inline Quaternion Quaternion::CreateFromAxisAngle(float angle, const Vector3 &axis)
|
||||
{
|
||||
Quaternion result;
|
||||
|
||||
float c = cosf(angle / 2.0f);
|
||||
float s = sinf(angle / 2.0f);
|
||||
|
||||
result.w = c;
|
||||
result.x = axis.x * s;
|
||||
result.y = axis.y * s;
|
||||
result.z = axis.z * s;
|
||||
|
||||
return Normalize(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a rotation matrix to a quaternion
|
||||
* @param matrix matrix to be converted
|
||||
* @return Quaternion quaternion equivalent of the rotation
|
||||
* matrix
|
||||
*/
|
||||
inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix4x4 &matrix)
|
||||
{
|
||||
Quaternion result;
|
||||
|
||||
float n = matrix.m[_11] + matrix.m[_22] + matrix.m[_33];
|
||||
if (n > 0.0f)
|
||||
{
|
||||
float a = sqrtf(n + 1.0f);
|
||||
result.w = a / 2.0f;
|
||||
a = 0.5f / a;
|
||||
result.x = (matrix.m[_32] - matrix.m[_23]) * a;
|
||||
result.y = (matrix.m[_13] - matrix.m[_31]) * a;
|
||||
result.z = (matrix.m[_21] - matrix.m[_12]) * a;
|
||||
}
|
||||
else if ((matrix.m[_11] >= matrix.m[_22]) && (matrix.m[_11] >= matrix.m[_33]))
|
||||
{
|
||||
float a = sqrtf(1.0f + matrix.m[_11] - matrix.m[_22] - matrix.m[_33]);
|
||||
float b = 0.5f / a;
|
||||
|
||||
result.x = 0.5f * a;
|
||||
result.y = (matrix.m[_21] + matrix.m[_12]) * b;
|
||||
result.z = (matrix.m[_31] + matrix.m[_13]) * b;
|
||||
result.w = (matrix.m[_32] - matrix.m[_23]) * b;
|
||||
}
|
||||
else if (matrix.m[_22] > matrix.m[_33])
|
||||
{
|
||||
float a = sqrtf(1.0f + matrix.m[_22] - matrix.m[_11] - matrix.m[_33]);
|
||||
float b = 0.5f / a;
|
||||
|
||||
result.x = (matrix.m[_12] + matrix.m[_21]) * b;
|
||||
result.y = 0.5f * a;
|
||||
result.z = (matrix.m[_23] + matrix.m[_32]) * b;
|
||||
result.w = (matrix.m[_13] - matrix.m[_31]) * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
float a = sqrtf(1.0f + matrix.m[_33] - matrix.m[_11] - matrix.m[_22]);
|
||||
float b = 0.5f / a;
|
||||
|
||||
result.x = (matrix.m[_13] + matrix.m[_31]) * b;
|
||||
result.y = (matrix.m[_23] + matrix.m[_32]) * b;
|
||||
result.z = 0.5f * a;
|
||||
result.w = (matrix.m[_21] - matrix.m[_12]) * b;
|
||||
}
|
||||
|
||||
return Normalize(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a quaternion to an axis-angle representation.
|
||||
* @param q the normalized quaternion to convert
|
||||
* @param angle the angle (in radians)
|
||||
* @param axis a vector that will contain the axis
|
||||
*/
|
||||
inline void Quaternion::ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis)
|
||||
{
|
||||
*angle = 2.0f * acosf(q.w);
|
||||
float n = sqrtf(1.0f - (q.w * q.w));
|
||||
if (n > 0.0001f)
|
||||
*axis = q.GetVector() / n;
|
||||
else
|
||||
*axis = X_AXIS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two quaternions.
|
||||
* @param a the first quaternion
|
||||
* @param b the second quaternion
|
||||
* @param interpolation the amount to interpolate
|
||||
* @return Quaternion the interpolated quaternion
|
||||
*/
|
||||
inline Quaternion Quaternion::Lerp(const Quaternion &a, const Quaternion &b, float interpolation)
|
||||
{
|
||||
return (a * (1.0f - interpolation)) + (b * interpolation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates between two quaternions using spherical
|
||||
* interpolation.
|
||||
* @param a the first quaternion
|
||||
* @param b the second quaternion
|
||||
* @param interpolation the amount to interpolate
|
||||
* @return Quaternion the interpolated quaternion
|
||||
*/
|
||||
inline Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b, float interpolation)
|
||||
{
|
||||
if (LengthSquared(a) == 0.0f)
|
||||
{
|
||||
if (LengthSquared(b) == 0.0f)
|
||||
return IDENTITY_QUATERNION;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
else if (LengthSquared(b) == 0.0f)
|
||||
return a;
|
||||
|
||||
Quaternion q1 = a;
|
||||
Quaternion q2 = b;
|
||||
|
||||
float cosHalfAngle = q1.w * q2.w + Vector3::Dot(q1.GetVector(), q2.GetVector());
|
||||
|
||||
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f)
|
||||
return q1;
|
||||
else if (cosHalfAngle < 0.0f)
|
||||
{
|
||||
q2.x = -q2.x;
|
||||
q2.y = -q2.y;
|
||||
q2.z = -q2.z;
|
||||
q2.w = -q2.w;
|
||||
cosHalfAngle = -cosHalfAngle;
|
||||
}
|
||||
|
||||
float blendA;
|
||||
float blendB;
|
||||
if (cosHalfAngle < 0.99f)
|
||||
{
|
||||
float halfAngle = acosf(cosHalfAngle);
|
||||
float sinHalfAngle = sinf(halfAngle);
|
||||
float oneOverSinHalfAngle = 1.0f / sinHalfAngle;
|
||||
blendA = sinf(halfAngle * (1.0f - interpolation)) * oneOverSinHalfAngle;
|
||||
blendB = sinf(halfAngle * interpolation) * oneOverSinHalfAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
blendA = 1.0f - interpolation;
|
||||
blendB = interpolation;
|
||||
}
|
||||
|
||||
Quaternion result(q1.w * blendA + q2.w * blendB, q1.GetVector() * blendA + q2.GetVector() * blendB);
|
||||
if (LengthSquared(result) > 0.0f)
|
||||
return Normalize(result);
|
||||
else
|
||||
return IDENTITY_QUATERNION;
|
||||
}
|
||||
|
||||
inline Quaternion operator+(const Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
return Quaternion(
|
||||
left.w + right.w,
|
||||
left.x + right.x,
|
||||
left.y + right.y,
|
||||
left.z + right.z
|
||||
);
|
||||
}
|
||||
|
||||
inline Quaternion &operator+=(Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
left = left + right;
|
||||
return left;
|
||||
}
|
||||
|
||||
inline Quaternion operator-(const Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
return Quaternion(
|
||||
left.w - right.w,
|
||||
left.x - right.x,
|
||||
left.y - right.y,
|
||||
left.z - right.z
|
||||
);
|
||||
}
|
||||
|
||||
inline Quaternion &operator-=(Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
left = left - right;
|
||||
return left;
|
||||
}
|
||||
|
||||
inline Quaternion operator*(const Quaternion &left, float right)
|
||||
{
|
||||
return Quaternion(
|
||||
left.w * right,
|
||||
left.x * right,
|
||||
left.y * right,
|
||||
left.z * right
|
||||
);
|
||||
}
|
||||
|
||||
inline Quaternion &operator*=(Quaternion &left, float right)
|
||||
{
|
||||
left = left * right;
|
||||
return left;
|
||||
}
|
||||
|
||||
inline Quaternion operator*(const Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
return Quaternion(
|
||||
(left.w * right.w) - (left.x * right.x) - (left.y * right.y) - (left.z * right.z),
|
||||
(left.w * right.x) + (left.x * right.w) + (left.y * right.z) - (left.z * right.y),
|
||||
(left.w * right.y) + (left.y * right.w) + (left.z * right.x) - (left.x * right.z),
|
||||
(left.w * right.z) + (left.z * right.w) + (left.x * right.y) - (left.y * right.x)
|
||||
);
|
||||
}
|
||||
|
||||
inline Quaternion &operator*=(Quaternion &left, const Quaternion &right)
|
||||
{
|
||||
left = left * right;
|
||||
return left;
|
||||
}
|
||||
|
||||
inline Quaternion operator/(const Quaternion &left, float right)
|
||||
{
|
||||
return Quaternion(
|
||||
left.w / right,
|
||||
left.x / right,
|
||||
left.y / right,
|
||||
left.z / right
|
||||
);
|
||||
}
|
||||
|
||||
inline Quaternion &operator/=(Quaternion &left, float right)
|
||||
{
|
||||
left = left / right;
|
||||
return left;
|
||||
}
|
||||
|
||||
inline Vector3 operator*(const Vector3 &left, const Quaternion &right)
|
||||
{
|
||||
return Vector3(
|
||||
((left.x * ((1.0f - (right.y * (right.y + right.y))) - (right.z * (right.z + right.z)))) + (left.y * ((right.x * (right.y + right.y)) - (right.w * (right.z + right.z))))) + (left.z * ((right.x * (right.z + right.z)) + (right.w * (right.y + right.y)))),
|
||||
((left.x * ((right.x * (right.y + right.y)) + (right.w * (right.z + right.z)))) + (left.y * ((1.0f - (right.x * (right.x + right.x))) - (right.z * (right.z + right.z))))) + (left.z * ((right.y * (right.z + right.z)) - (right.w * (right.x + right.x)))),
|
||||
((left.x * ((right.x * (right.z + right.z)) - (right.w * (right.y + right.y)))) + (left.y * ((right.y * (right.z + right.z)) + (right.w * (right.x + right.x))))) + (left.z * ((1.0f - (right.x * (right.x + right.x))) - (right.y * (right.y + right.y))))
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef __GEOMETRY_TRIANGLE_H_INCLUDED__
|
||||
#define __GEOMETRY_TRIANGLE_H_INCLUDED__
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
class Triangle
|
||||
{
|
||||
public:
|
||||
uint32_t vertices[3];
|
||||
uint32_t normals[3];
|
||||
uint32_t texCoords[3];
|
||||
uint32_t materialIndex;
|
||||
};
|
||||
|
||||
#endif
|
66
src/main.cpp
66
src/main.cpp
|
@ -3,18 +3,14 @@
|
|||
#include <exception>
|
||||
|
||||
#include "md2/md2.h"
|
||||
#include "obj/obj.h"
|
||||
#include "sm/sm.h"
|
||||
#include "ms3d/ms3d.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("MESH Converter\n");
|
||||
printf("MD2-to-MESH Converter\n");
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
printf("No input file specified.\n");
|
||||
printf("Usage: meshconverter.exe [inputfile]\n\n");
|
||||
printf("Usage: md2tomesh.exe [inputfile]\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -40,26 +36,6 @@ int main(int argc, char **argv)
|
|||
meshFile.append(".mesh");
|
||||
}
|
||||
|
||||
if (extension == ".obj")
|
||||
{
|
||||
printf("Using OBJ converter.\n");
|
||||
|
||||
Obj *obj = new Obj();
|
||||
if (!obj->Load(file, "./"))
|
||||
{
|
||||
printf("Error loading OBJ file.\n\n");
|
||||
return 1;
|
||||
}
|
||||
if (!obj->ConvertToMesh(meshFile))
|
||||
{
|
||||
printf("Error converting OBJ to MESH.\n\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (extension == ".md2")
|
||||
{
|
||||
printf("Using MD2 converter.\n");
|
||||
|
||||
Md2 *md2 = new Md2();
|
||||
if (!md2->Load(file))
|
||||
{
|
||||
|
@ -71,44 +47,6 @@ int main(int argc, char **argv)
|
|||
printf("Error converting MD2 to MESH.\n\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (extension == ".sm")
|
||||
{
|
||||
printf("Using SM converter.\n");
|
||||
|
||||
StaticModel *sm = new StaticModel();
|
||||
if (!sm->Load(file))
|
||||
{
|
||||
printf("Error loading SM file.\n\n");
|
||||
return 1;
|
||||
}
|
||||
if (!sm->ConvertToMesh(meshFile))
|
||||
{
|
||||
printf("Error converting SM to MESH.\n\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (extension == ".ms3d")
|
||||
{
|
||||
printf("Using MS3D converter.\n");
|
||||
|
||||
Ms3d *ms3d = new Ms3d();
|
||||
if (!ms3d->Load(file))
|
||||
{
|
||||
printf("Error loading MS3D file.\n\n");
|
||||
return 1;
|
||||
}
|
||||
if (!ms3d->ConvertToMesh(meshFile))
|
||||
{
|
||||
printf("Error converting MS3D to MESH.\n\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unrecognized file type.\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Finished converting to %s\n", meshFile.c_str());
|
||||
|
||||
|
|
|
@ -1,437 +0,0 @@
|
|||
#include "ms3d.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.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)
|
||||
{
|
||||
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];
|
||||
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];
|
||||
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];
|
||||
|
||||
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 (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
146
src/ms3d/ms3d.h
|
@ -1,146 +0,0 @@
|
|||
#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);
|
||||
|
||||
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
|
496
src/obj/obj.cpp
496
src/obj/obj.cpp
|
@ -1,496 +0,0 @@
|
|||
#include "obj.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
Obj::Obj()
|
||||
{
|
||||
m_vertices = NULL;
|
||||
m_normals = NULL;
|
||||
m_texCoords = NULL;
|
||||
m_materials = NULL;
|
||||
m_numVertices = 0;
|
||||
m_numNormals = 0;
|
||||
m_numTexCoords = 0;
|
||||
m_numMaterials = 0;
|
||||
}
|
||||
|
||||
void Obj::Release()
|
||||
{
|
||||
delete[] m_vertices;
|
||||
delete[] m_normals;
|
||||
delete[] m_texCoords;
|
||||
delete[] m_materials;
|
||||
m_vertices = NULL;
|
||||
m_normals = NULL;
|
||||
m_texCoords = NULL;
|
||||
m_materials = NULL;
|
||||
m_numVertices = 0;
|
||||
m_numNormals = 0;
|
||||
m_numTexCoords = 0;
|
||||
m_numMaterials = 0;
|
||||
}
|
||||
|
||||
bool Obj::Load(const std::string &file, const std::string &texturePath)
|
||||
{
|
||||
std::ifstream input;
|
||||
std::string line;
|
||||
std::string op;
|
||||
std::string path;
|
||||
std::string tempName;
|
||||
Vector3 vertex;
|
||||
Vector3 normal;
|
||||
ObjMaterial *currentMaterial = NULL;
|
||||
int currentVertex = 0;
|
||||
int currentNormal = 0;
|
||||
int currentTexCoord = 0;
|
||||
int numGroups = 0;
|
||||
|
||||
// Get pathname from filename given (if present)
|
||||
// Need this as we assume any .mtl files specified are in the same path as this .obj file
|
||||
if (file.find_last_of('/') != std::string::npos)
|
||||
path = file.substr(0, file.find_last_of('/') + 1);
|
||||
|
||||
if (!FindAndLoadMaterials(path, texturePath, file))
|
||||
return false;
|
||||
if (!GetDataSizes(file))
|
||||
return false;
|
||||
|
||||
input.open(file.c_str());
|
||||
if (input.fail())
|
||||
return false;
|
||||
|
||||
// Extract name of model from the filename given (basically, chop off the extension and path)
|
||||
//if (file.find_last_of('.') != std::string::npos)
|
||||
// model->name = file.substr(path.length(), file.find_last_of('.') - path.length());
|
||||
|
||||
// Begin reading in model data
|
||||
while (!input.eof())
|
||||
{
|
||||
if (numGroups > 1)
|
||||
break;
|
||||
|
||||
std::getline(input, line, '\n');
|
||||
|
||||
op = line.substr(0, line.find(' '));
|
||||
|
||||
// Comments
|
||||
if (op == "#")
|
||||
{
|
||||
}
|
||||
|
||||
// Vertex
|
||||
else if (op == "v")
|
||||
{
|
||||
sscanf(line.c_str(), "v %f %f %f", &m_vertices[currentVertex].x, &m_vertices[currentVertex].y, &m_vertices[currentVertex].z);
|
||||
++currentVertex;
|
||||
}
|
||||
|
||||
// Texture coordinate
|
||||
else if (op == "vt")
|
||||
{
|
||||
sscanf(line.c_str(), "vt %f %f", &m_texCoords[currentTexCoord].x, &m_texCoords[currentTexCoord].y);
|
||||
m_texCoords[currentTexCoord].x = -m_texCoords[currentTexCoord].y;
|
||||
++currentTexCoord;
|
||||
}
|
||||
|
||||
// Vertex normal
|
||||
else if (op == "vn")
|
||||
{
|
||||
sscanf(line.c_str(), "vn %f %f %f", &m_normals[currentNormal].x, &m_normals[currentNormal].y, &m_normals[currentNormal].z);
|
||||
++currentNormal;
|
||||
}
|
||||
|
||||
// Face definition
|
||||
else if (op == "f")
|
||||
{
|
||||
ParseFaceDefinition(line, currentMaterial);
|
||||
}
|
||||
|
||||
// Group name
|
||||
else if (op == "g")
|
||||
{
|
||||
++numGroups;
|
||||
}
|
||||
|
||||
// Object name
|
||||
else if (op == "o")
|
||||
{
|
||||
}
|
||||
|
||||
// Material
|
||||
else if (op == "usemtl")
|
||||
{
|
||||
tempName = line.substr(line.find(' ') + 1);
|
||||
|
||||
currentMaterial = NULL;
|
||||
|
||||
// Find the named material and set it as current
|
||||
for (unsigned int i = 0; i < m_numMaterials; ++i)
|
||||
{
|
||||
if (m_materials[i].name == tempName)
|
||||
{
|
||||
currentMaterial = &m_materials[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//ASSERT(currentMaterial != NULL);
|
||||
}
|
||||
|
||||
// Material file
|
||||
else if (op == "mtllib")
|
||||
{
|
||||
// Already would have been loaded
|
||||
}
|
||||
}
|
||||
|
||||
input.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Obj::ParseFaceDefinition(const std::string &faceDefinition, ObjMaterial *currentMaterial)
|
||||
{
|
||||
static int numFaceVertices = 0;
|
||||
static OBJ_FACE_VERTEX_TYPE vertexType;
|
||||
std::string def;
|
||||
int pos;
|
||||
int n = 0;
|
||||
|
||||
// Just get the vertex index part of the line (can be variable length, and we dont want the newline at the end)
|
||||
pos = faceDefinition.find(' ') + 1;
|
||||
def = faceDefinition.substr(pos);
|
||||
|
||||
// Few different face formats, and variable amount of vertices per face possible
|
||||
|
||||
// How many vertices are there in this face definition? (only calc this once)
|
||||
// Also calc the vertex format
|
||||
if (!numFaceVertices)
|
||||
{
|
||||
pos = 0;
|
||||
while (def.length() > 0 && def[def.length() - 1] == ' ')
|
||||
def = def.substr(0, def.length() - 1);
|
||||
//ASSERT(def.length() > 0);
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
++pos;
|
||||
++numFaceVertices;
|
||||
pos = def.find(' ', pos);
|
||||
}
|
||||
|
||||
std::string tempVertex = def.substr(0, def.find(' '));
|
||||
if (tempVertex.find("//") != std::string::npos)
|
||||
vertexType = OBJ_VERTEX_NORMAL;
|
||||
else
|
||||
{
|
||||
pos = 0;
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
++pos;
|
||||
++n;
|
||||
pos = tempVertex.find('/', pos);
|
||||
}
|
||||
|
||||
if (n == 1)
|
||||
vertexType = OBJ_VERTEX_TEXCOORD;
|
||||
else
|
||||
vertexType = OBJ_VERTEX_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse out vertices in this face
|
||||
// We also store only triangles. Since OBJ file face definitions can have any number
|
||||
// of vertices per face, we need to split it up into triangles here for easy rendering
|
||||
// This is done as follows:
|
||||
// - first 3 vertices = first triangle for face
|
||||
// - for each additional 1 vertex, take the first vertex read for this face + the previously
|
||||
// read vertex for this face and combine to make a new triangle
|
||||
std::istringstream parser;
|
||||
std::string currentVertex;
|
||||
int thisVertex[3];
|
||||
int firstVertex[3];
|
||||
int lastReadVertex[3];
|
||||
int thisTriangle[3][3];
|
||||
ObjFace face;
|
||||
|
||||
memset(&firstVertex, 0, sizeof(int) * 3);
|
||||
memset(&lastReadVertex, 0, sizeof(int) * 3);
|
||||
memset(&thisTriangle, 0, sizeof(int) * (3 * 3));
|
||||
parser.clear();
|
||||
parser.str(def);
|
||||
|
||||
for (int i = 0; i < numFaceVertices; ++i)
|
||||
{
|
||||
// Get current vertex for this face
|
||||
parser >> currentVertex;
|
||||
|
||||
// Add vertex/texcoord/normal indexes to the data arrays
|
||||
// (OBJ file indexes are NOT zero based. We fix that here)
|
||||
memset(&thisVertex, 0, sizeof(int) * 3);
|
||||
switch (vertexType)
|
||||
{
|
||||
case OBJ_VERTEX_FULL: // v/vt/vn
|
||||
sscanf(currentVertex.c_str(), "%d/%d/%d", &thisVertex[0], &thisVertex[1], &thisVertex[2]);
|
||||
break;
|
||||
case OBJ_VERTEX_NORMAL: // v//vn
|
||||
sscanf(currentVertex.c_str(), "%d//%d", &thisVertex[0], &thisVertex[2]);
|
||||
break;
|
||||
case OBJ_VERTEX_TEXCOORD: // v/vt
|
||||
sscanf(currentVertex.c_str(), "%d/%d", &thisVertex[0], &thisVertex[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
// Save the first vertex read for a face
|
||||
if (i == 0)
|
||||
memcpy(&firstVertex, &thisVertex, sizeof(int) * 3);
|
||||
|
||||
// First 3 vertices simply form a triangle
|
||||
if (i <= 2)
|
||||
{
|
||||
face.vertices[i] = thisVertex[0] - 1;
|
||||
face.texcoords[i] = thisVertex[1] - 1;
|
||||
face.normals[i] = thisVertex[2] - 1;
|
||||
}
|
||||
|
||||
// Store the first triangle
|
||||
if (i == 2)
|
||||
{
|
||||
//ASSERT(currentMaterial != NULL);
|
||||
currentMaterial->faces[currentMaterial->lastFaceIndex] = face;
|
||||
++currentMaterial->lastFaceIndex;
|
||||
}
|
||||
|
||||
// Combine vertices to form additional triangles
|
||||
if (i > 2)
|
||||
{
|
||||
//ASSERT(currentMaterial != NULL);
|
||||
face.vertices[0] = firstVertex[0] - 1; face.texcoords[0] = firstVertex[1] - 1; face.normals[0] = firstVertex[2] - 1;
|
||||
face.vertices[1] = lastReadVertex[0] - 1; face.texcoords[1] = lastReadVertex[1] - 1; face.normals[1] = lastReadVertex[2] - 1;
|
||||
face.vertices[2] = thisVertex[0] - 1; face.texcoords[2] = thisVertex[1] - 1; face.normals[2] = thisVertex[2] - 1;
|
||||
currentMaterial->faces[currentMaterial->lastFaceIndex] = face;
|
||||
++currentMaterial->lastFaceIndex;
|
||||
}
|
||||
|
||||
// Save as "previously read vertex"
|
||||
memcpy(&lastReadVertex, &thisVertex, sizeof(int) * 3);
|
||||
}
|
||||
}
|
||||
|
||||
bool Obj::GetDataSizes(const std::string &file)
|
||||
{
|
||||
std::ifstream input;
|
||||
std::string line;
|
||||
std::string op;
|
||||
int countVertices = 0;
|
||||
int countNormals = 0;
|
||||
int countTexCoords = 0;
|
||||
int numGroups = 0;
|
||||
std::string useMtlName;
|
||||
ObjMaterial *currentMaterial;
|
||||
|
||||
input.open(file.c_str());
|
||||
if (input.fail())
|
||||
return false;
|
||||
|
||||
while (!input.eof())
|
||||
{
|
||||
if (numGroups > 1)
|
||||
break;
|
||||
|
||||
std::getline(input, line, '\n');
|
||||
|
||||
op = line.substr(0, line.find(' '));
|
||||
|
||||
if (op == "g")
|
||||
++numGroups;
|
||||
else if (op == "v")
|
||||
++countVertices;
|
||||
else if (op == "vt")
|
||||
++countTexCoords;
|
||||
else if (op == "vn")
|
||||
++countNormals;
|
||||
else if (op == "f")
|
||||
// TODO: count number of vertices per face definition, and adjust the ++ operation accordingly (i.e. for 4 vertices per face, needs to be "+= 2")
|
||||
++currentMaterial->numFaces;
|
||||
|
||||
else if (op == "usemtl")
|
||||
{
|
||||
std::string useMtlName = line.substr(line.find(' ') + 1);
|
||||
|
||||
currentMaterial = NULL;
|
||||
|
||||
// Find the named material and set it as current
|
||||
for (unsigned int i = 0; i < m_numMaterials; ++i)
|
||||
{
|
||||
if (m_materials[i].name == useMtlName)
|
||||
{
|
||||
currentMaterial = &m_materials[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//ASSERT(currentMaterial != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
input.close();
|
||||
|
||||
m_numVertices = countVertices;
|
||||
m_numTexCoords = countTexCoords;
|
||||
m_numNormals = countNormals;
|
||||
m_vertices = new Vector3[m_numVertices];
|
||||
m_texCoords = new Vector2[m_numTexCoords];
|
||||
m_normals = new Vector3[m_numNormals];
|
||||
for (unsigned int i = 0; i < m_numMaterials; ++i)
|
||||
{
|
||||
m_materials[i].faces = new ObjFace[m_materials[i].numFaces];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Obj::LoadMaterialLibrary(const std::string &file, const std::string &texturePath)
|
||||
{
|
||||
std::ifstream input;
|
||||
std::string line;
|
||||
std::string op;
|
||||
int currentMaterial = -1;
|
||||
float r, g, b;
|
||||
|
||||
if (!CountDefinedMaterials(file))
|
||||
return false;
|
||||
m_materials = new ObjMaterial[m_numMaterials];
|
||||
|
||||
input.open(file.c_str());
|
||||
if (input.fail())
|
||||
return false;
|
||||
|
||||
while (!input.eof())
|
||||
{
|
||||
std::getline(input, line, '\n');
|
||||
|
||||
op = line.substr(0, line.find(' '));
|
||||
|
||||
// New material definition (possibility of multiple per .mtl file)
|
||||
if (op == "newmtl")
|
||||
{
|
||||
++currentMaterial;
|
||||
m_materials[currentMaterial].name = line.substr(op.length() + 1);
|
||||
}
|
||||
|
||||
// Ambient color
|
||||
else if (op == "Ka")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
sscanf(line.c_str(), "Ka %f %f %f", &r, &g, &b);
|
||||
m_materials[currentMaterial].material->ambient = Color::FromInt(RGB_24_f(r, g, b));
|
||||
}
|
||||
|
||||
// Diffuse color
|
||||
else if (op == "Kd")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
sscanf(line.c_str(), "Kd %f %f %f", &r, &g, &b);
|
||||
m_materials[currentMaterial].material->diffuse = Color::FromInt(RGB_24_f(r, g, b));
|
||||
}
|
||||
|
||||
// Specular color
|
||||
else if (op == "Ks")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
sscanf(line.c_str(), "Ks %f %f %f", &r, &g, &b);
|
||||
m_materials[currentMaterial].material->specular = Color::FromInt(RGB_24_f(r, g, b));
|
||||
}
|
||||
|
||||
// Alpha value
|
||||
else if (op == "d" || op == "Tr")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
}
|
||||
|
||||
// Shininess
|
||||
else if (op == "Ns")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
}
|
||||
|
||||
// Illumination model
|
||||
else if (op == "illum")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
}
|
||||
|
||||
// Texture
|
||||
else if (op == "map_Ka" || op == "map_Kd")
|
||||
{
|
||||
//ASSERT(currentMaterial >= 0);
|
||||
m_materials[currentMaterial].material->textureFile = texturePath + line.substr(op.length() + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
input.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Obj::CountDefinedMaterials(const std::string &file)
|
||||
{
|
||||
std::ifstream input;
|
||||
std::string line;
|
||||
std::string op;
|
||||
|
||||
input.open(file.c_str());
|
||||
if (input.fail())
|
||||
return false;
|
||||
|
||||
while (!input.eof())
|
||||
{
|
||||
std::getline(input, line, '\n');
|
||||
|
||||
op = line.substr(0, line.find(' '));
|
||||
if (op == "newmtl")
|
||||
++m_numMaterials;
|
||||
}
|
||||
|
||||
input.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Obj::FindAndLoadMaterials(const std::string &materialPath, const std::string &texturePath, const std::string &file)
|
||||
{
|
||||
std::ifstream input;
|
||||
std::string line;
|
||||
std::string op;
|
||||
|
||||
input.open(file.c_str());
|
||||
if (input.fail())
|
||||
return false;
|
||||
|
||||
while (!input.eof())
|
||||
{
|
||||
std::getline(input, line, '\n');
|
||||
|
||||
op = line.substr(0, line.find(' '));
|
||||
|
||||
if (op == "mtllib")
|
||||
{
|
||||
LoadMaterialLibrary(materialPath + line.substr(line.find(' ') + 1), texturePath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
input.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Obj::ConvertToMesh(const std::string &file)
|
||||
{
|
||||
return false;
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
#ifndef __OBJ_H_INCLUDED__
|
||||
#define __OBJ_H_INCLUDED__
|
||||
|
||||
#include "../geometry/vector3.h"
|
||||
#include "../geometry/vector2.h"
|
||||
#include "../assets/material.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
enum OBJ_FACE_VERTEX_TYPE
|
||||
{
|
||||
OBJ_VERTEX_TEXCOORD,
|
||||
OBJ_VERTEX_NORMAL,
|
||||
OBJ_VERTEX_FULL
|
||||
};
|
||||
|
||||
struct ObjFace
|
||||
{
|
||||
unsigned int vertices[3];
|
||||
unsigned int texcoords[3];
|
||||
unsigned int normals[3];
|
||||
};
|
||||
|
||||
struct ObjMaterial
|
||||
{
|
||||
std::string name;
|
||||
Material *material;
|
||||
ObjFace *faces;
|
||||
unsigned int numFaces;
|
||||
unsigned int lastFaceIndex;
|
||||
|
||||
ObjMaterial()
|
||||
{
|
||||
material = new Material();
|
||||
faces = NULL;
|
||||
numFaces = 0;
|
||||
lastFaceIndex = 0;
|
||||
}
|
||||
|
||||
~ObjMaterial()
|
||||
{
|
||||
delete material;
|
||||
delete[] faces;
|
||||
}
|
||||
};
|
||||
|
||||
class Obj
|
||||
{
|
||||
public:
|
||||
Obj();
|
||||
virtual ~Obj() { Release(); }
|
||||
|
||||
void Release();
|
||||
bool Load(const std::string &file, const std::string &texturePath);
|
||||
bool ConvertToMesh(const std::string &file);
|
||||
|
||||
int GetNumVertices() { return m_numVertices; }
|
||||
int GetNumNormals() { return m_numNormals; }
|
||||
int GetNumTexCoords() { return m_numTexCoords; }
|
||||
int GetNumMaterials() { return m_numMaterials; }
|
||||
Vector3* GetVertices() { return m_vertices; }
|
||||
Vector3* GetNormals() { return m_normals; }
|
||||
Vector2* GetTexCoords() { return m_texCoords; }
|
||||
ObjMaterial* GetMaterials() { return m_materials; }
|
||||
|
||||
private:
|
||||
bool GetDataSizes(const std::string &file);
|
||||
bool LoadMaterialLibrary(const std::string &file, const std::string &texturePath);
|
||||
bool CountDefinedMaterials(const std::string &file);
|
||||
bool FindAndLoadMaterials(const std::string &materialPath, const std::string &texturePath, const std::string &file);
|
||||
void ParseFaceDefinition(const std::string &faceDefinition, ObjMaterial *currentMaterial);
|
||||
|
||||
Vector3 *m_vertices;
|
||||
Vector3 *m_normals;
|
||||
Vector2 *m_texCoords;
|
||||
ObjMaterial *m_materials;
|
||||
unsigned int m_numVertices;
|
||||
unsigned int m_numNormals;
|
||||
unsigned int m_numTexCoords;
|
||||
unsigned int m_numMaterials;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
259
src/sm/sm.cpp
259
src/sm/sm.cpp
|
@ -1,259 +0,0 @@
|
|||
#include "sm.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../util/files.h"
|
||||
#include "../chunks/chunks.h"
|
||||
|
||||
StaticModel::StaticModel()
|
||||
{
|
||||
m_numMaterials = 0;
|
||||
m_numPolygons = 0;
|
||||
m_numVertices = 0;
|
||||
m_numNormals = 0;
|
||||
m_numTexCoords = 0;
|
||||
m_hasNormals = false;
|
||||
m_hasTexCoords = false;
|
||||
m_hasColors = false;
|
||||
m_materials = NULL;
|
||||
m_polygons = NULL;
|
||||
m_texCoords = NULL;
|
||||
m_vertices = NULL;
|
||||
m_normals = NULL;
|
||||
}
|
||||
|
||||
void StaticModel::Release()
|
||||
{
|
||||
delete[] m_materials;
|
||||
delete[] m_polygons;
|
||||
delete[] m_texCoords;
|
||||
delete[] m_vertices;
|
||||
delete[] m_normals;
|
||||
}
|
||||
|
||||
bool StaticModel::Load(const std::string &file)
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned short numMaterials;
|
||||
unsigned int numPolys, numVertices, numNormals, numTexCoords;
|
||||
unsigned int ambient, diffuse, specular, emission;
|
||||
unsigned int n;
|
||||
int currentMaterial;
|
||||
float x, y, z;
|
||||
unsigned char header[2];
|
||||
std::string texture;
|
||||
|
||||
fp = fopen(file.c_str(), "rb");
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
// Simple file type validation
|
||||
fread(&header[0], 2, 1, fp);
|
||||
if (header[0] != 'S' || header[1] != 'M')
|
||||
return false;
|
||||
|
||||
fread(&numMaterials, 2, 1, fp);
|
||||
fread(&numPolys, 4, 1, fp);
|
||||
fread(&numVertices, 4, 1, fp);
|
||||
fread(&numNormals, 4, 1, fp);
|
||||
fread(&numTexCoords, 4, 1, fp);
|
||||
|
||||
m_materials = new SmMaterial[numMaterials];
|
||||
m_polygons = new SmPolygon[numPolys];
|
||||
m_texCoords = new Vector2[numTexCoords];
|
||||
m_vertices = new Vector3[numVertices];
|
||||
m_normals = new Vector3[numNormals];
|
||||
|
||||
//ASSERT(m_materials != NULL);
|
||||
//ASSERT(m_polygons != NULL);
|
||||
//ASSERT(m_texCoords != NULL);
|
||||
//ASSERT(m_vertices != NULL);
|
||||
//ASSERT(m_normals != NULL);
|
||||
|
||||
m_numMaterials = numMaterials;
|
||||
m_numPolygons = numPolys;
|
||||
m_numVertices = numVertices;
|
||||
m_numNormals = numNormals;
|
||||
m_numTexCoords = numTexCoords;
|
||||
|
||||
// Read in material definitions
|
||||
for (int i = 0; i < m_numMaterials; ++i)
|
||||
{
|
||||
fread(&ambient, 4, 1, fp);
|
||||
fread(&diffuse, 4, 1, fp);
|
||||
fread(&specular, 4, 1, fp);
|
||||
fread(&emission, 4, 1, fp);
|
||||
|
||||
m_materials[i].material->ambient = Color::FromInt(ambient);
|
||||
m_materials[i].material->diffuse = Color::FromInt(diffuse);
|
||||
m_materials[i].material->specular = Color::FromInt(specular);
|
||||
m_materials[i].material->emissive = Color::FromInt(emission);
|
||||
m_materials[i].material->shininess = 0.0f;
|
||||
m_materials[i].material->opacity = COLOR_ALPHA_OPAQUE;
|
||||
ReadString(fp, m_materials[i].material->name);
|
||||
}
|
||||
|
||||
// Read in triangle definitions (all are indexes into raw data following)
|
||||
currentMaterial = NO_MATERIAL;
|
||||
for (unsigned int i = 0; i < m_numPolygons; ++i)
|
||||
{
|
||||
// Vertices
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
fread(&n, 4, 1, fp);
|
||||
m_polygons[i].vertices[j] = n;
|
||||
}
|
||||
|
||||
// Normals
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
fread(&n, 4, 1, fp);
|
||||
m_polygons[i].normals[j] = n;
|
||||
}
|
||||
|
||||
// TexCoords
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
fread(&n, 4, 1, fp);
|
||||
m_polygons[i].texcoords[j] = n;
|
||||
}
|
||||
|
||||
// Vertex colors
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
fread(&n, 2, 1, fp);
|
||||
m_polygons[i].colors[j] = n;
|
||||
}
|
||||
|
||||
// Material index
|
||||
fread(&m_polygons[i].material, 2, 1, fp);
|
||||
|
||||
// Record start/end indices for the different materials
|
||||
// This way rendering can be done per material while still only looping
|
||||
// over all of this model's polygons once per frame
|
||||
if (m_polygons[i].material != currentMaterial)
|
||||
{
|
||||
if (currentMaterial > NO_MATERIAL)
|
||||
m_materials[currentMaterial].polyEnd = i;
|
||||
|
||||
currentMaterial = m_polygons[i].material;
|
||||
m_materials[currentMaterial].polyStart = i;
|
||||
}
|
||||
|
||||
// If any of the normals, texcoords, or colors are non-zero, we need to flag that such
|
||||
// information exists in this model
|
||||
if (m_polygons[i].colors[0] != 0 || m_polygons[i].colors[1] != 0 || m_polygons[i].colors[2] != 0)
|
||||
m_hasColors = true;
|
||||
}
|
||||
|
||||
// Will always include the last polygon due to the way the .SM exporter sorts
|
||||
m_materials[currentMaterial].polyEnd = numPolys;
|
||||
|
||||
// Vertices
|
||||
for (unsigned int i = 0; i < m_numVertices; ++i)
|
||||
{
|
||||
fread(&x, 4, 1, fp);
|
||||
fread(&y, 4, 1, fp);
|
||||
fread(&z, 4, 1, fp);
|
||||
|
||||
m_vertices[i].x = x / 2;
|
||||
m_vertices[i].y = y / 2;
|
||||
m_vertices[i].z = z / 2;
|
||||
}
|
||||
|
||||
// Normals
|
||||
for (unsigned int i = 0; i < m_numNormals; ++i)
|
||||
{
|
||||
fread(&x, 4, 1, fp);
|
||||
fread(&y, 4, 1, fp);
|
||||
fread(&z, 4, 1, fp);
|
||||
//ASSERT(!((x >= 1.0f || x <= -1.0f) ||
|
||||
// (y >= 1.0f || y <= -1.0f) ||
|
||||
// (z >= 1.0f || z <= -1.0f)));
|
||||
m_normals[i].x = x;
|
||||
m_normals[i].y = y;
|
||||
m_normals[i].z = z;
|
||||
|
||||
if (m_normals[i].x != 0 || m_normals[i].y != 0 || m_normals[i].z != 0)
|
||||
m_hasNormals = true;
|
||||
}
|
||||
|
||||
// Texture coordinates
|
||||
for (unsigned int i = 0; i < m_numTexCoords; ++i)
|
||||
{
|
||||
fread(&x, 4, 1, fp);
|
||||
fread(&y, 4, 1, fp);
|
||||
//ASSERT(!((x >= 2048.0f || x <= -2048.0f) ||
|
||||
// (y >= 2048.0f || y <= -2048.0f)));
|
||||
|
||||
// TODO: revisit this, seems a bit hack-ish and probably only correct
|
||||
// for the shitty models I made
|
||||
m_texCoords[i].x = x;
|
||||
m_texCoords[i].y = -y;
|
||||
|
||||
if (m_texCoords[i].x != 0 || m_texCoords[i].y != 0)
|
||||
m_hasTexCoords = true;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticModel::ConvertToMesh(const std::string &file)
|
||||
{
|
||||
FILE *fp = fopen(file.c_str(), "wb");
|
||||
if (fp == NULL)
|
||||
return false;
|
||||
|
||||
WriteFileHeader(fp);
|
||||
|
||||
VerticesChunk *verticesChunk = new VerticesChunk();
|
||||
for (long i = 0; i < m_numVertices; ++i)
|
||||
verticesChunk->vertices.push_back(m_vertices[i]);
|
||||
WriteChunk(verticesChunk, fp);
|
||||
SAFE_DELETE(verticesChunk);
|
||||
|
||||
NormalsChunk *normalsChunk = new NormalsChunk();
|
||||
for (long i = 0; i < m_numNormals; ++i)
|
||||
normalsChunk->normals.push_back(m_normals[i]);
|
||||
WriteChunk(normalsChunk, fp);
|
||||
SAFE_DELETE(normalsChunk);
|
||||
|
||||
TexCoordsChunk *texCoordsChunk = new TexCoordsChunk();
|
||||
for (long i = 0; i < m_numTexCoords; ++i)
|
||||
texCoordsChunk->texCoords.push_back(m_texCoords[i]);
|
||||
WriteChunk(texCoordsChunk, fp);
|
||||
SAFE_DELETE(texCoordsChunk);
|
||||
|
||||
MaterialsChunk *materialsChunk = new MaterialsChunk();
|
||||
for (long i = 0; i < m_numMaterials; ++i)
|
||||
materialsChunk->materials.push_back(*m_materials[i].material);
|
||||
WriteChunk(materialsChunk, fp);
|
||||
SAFE_DELETE(materialsChunk);
|
||||
|
||||
TrianglesChunk *trianglesChunk = new TrianglesChunk();
|
||||
for (long i = 0; i < m_numPolygons; ++i)
|
||||
{
|
||||
Triangle t;
|
||||
|
||||
t.vertices[0] = m_polygons[i].vertices[0];
|
||||
t.vertices[1] = m_polygons[i].vertices[1];
|
||||
t.vertices[2] = m_polygons[i].vertices[2];
|
||||
|
||||
t.normals[0] = m_polygons[i].normals[0];
|
||||
t.normals[1] = m_polygons[i].normals[1];
|
||||
t.normals[2] = m_polygons[i].normals[2];
|
||||
|
||||
t.texCoords[0] = m_polygons[i].texcoords[0];
|
||||
t.texCoords[1] = m_polygons[i].texcoords[1];
|
||||
t.texCoords[2] = m_polygons[i].texcoords[2];
|
||||
|
||||
t.materialIndex = m_polygons[i].material;
|
||||
|
||||
trianglesChunk->triangles.push_back(t);
|
||||
}
|
||||
WriteChunk(trianglesChunk, fp);
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
73
src/sm/sm.h
73
src/sm/sm.h
|
@ -1,73 +0,0 @@
|
|||
#ifndef __SM_H_INCLUDED__
|
||||
#define __SM_H_INCLUDED__
|
||||
|
||||
#include "../assets/material.h"
|
||||
#include "../geometry/vector3.h"
|
||||
#include "../geometry/vector2.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
struct SmPolygon
|
||||
{
|
||||
unsigned int vertices[3];
|
||||
unsigned int normals[3];
|
||||
unsigned int texcoords[3];
|
||||
unsigned short colors[3];
|
||||
short material;
|
||||
};
|
||||
|
||||
struct SmMaterial
|
||||
{
|
||||
Material *material;
|
||||
unsigned int polyStart;
|
||||
unsigned int polyEnd;
|
||||
|
||||
SmMaterial()
|
||||
{
|
||||
material = new Material();
|
||||
polyStart = 0;
|
||||
polyEnd = 0;
|
||||
};
|
||||
|
||||
~SmMaterial()
|
||||
{
|
||||
delete material;
|
||||
}
|
||||
};
|
||||
|
||||
#define NO_MATERIAL -1
|
||||
|
||||
class StaticModel
|
||||
{
|
||||
public:
|
||||
StaticModel();
|
||||
virtual ~StaticModel() { Release(); }
|
||||
|
||||
void Release();
|
||||
bool Load(const std::string &file);
|
||||
bool ConvertToMesh(const std::string &file);
|
||||
|
||||
SmMaterial* GetMaterial(unsigned short index) { return &m_materials[index]; }
|
||||
SmPolygon* GetPolygon(unsigned int index) { return &m_polygons[index]; }
|
||||
Vector3* GetVertex(unsigned int index) { return &m_vertices[index]; }
|
||||
unsigned int GetNumMaterials() { return (unsigned int)m_numMaterials; }
|
||||
unsigned int GetNumPolygons() { return m_numPolygons; }
|
||||
unsigned int GetNumVertices() { return m_numVertices; }
|
||||
|
||||
private:
|
||||
SmMaterial *m_materials;
|
||||
SmPolygon *m_polygons;
|
||||
Vector3 *m_vertices;
|
||||
Vector3 *m_normals;
|
||||
Vector2 *m_texCoords;
|
||||
int m_numMaterials;
|
||||
unsigned int m_numPolygons;
|
||||
unsigned int m_numVertices;
|
||||
unsigned int m_numNormals;
|
||||
unsigned int m_numTexCoords;
|
||||
bool m_hasNormals;
|
||||
bool m_hasTexCoords;
|
||||
bool m_hasColors;
|
||||
};
|
||||
|
||||
#endif
|
Reference in a new issue