From b5b95584326dd91bb61212df35dfd4e0b5db1d07 Mon Sep 17 00:00:00 2001 From: gered Date: Tue, 7 Jun 2011 12:09:19 -0400 Subject: [PATCH] removed all other model import/exporting except for md2 --- .gitignore | 2 +- Makefile | 2 +- src/assets/color.h | 80 --- src/assets/material.h | 26 - src/chunks/chunks.cpp | 115 +---- src/chunks/chunks.h | 8 - src/chunks/materials.h | 38 -- src/chunks/normals.h | 31 -- src/chunks/triangles.h | 35 -- src/chunks/vertices.h | 31 -- src/geometry/matrix4x4.h | 1030 ------------------------------------- src/geometry/quaternion.h | 491 ------------------ src/geometry/triangle.h | 15 - src/main.cpp | 80 +-- src/ms3d/ms3d.cpp | 437 ---------------- src/ms3d/ms3d.h | 146 ------ src/obj/obj.cpp | 496 ------------------ src/obj/obj.h | 84 --- src/sm/sm.cpp | 259 ---------- src/sm/sm.h | 73 --- 20 files changed, 12 insertions(+), 3467 deletions(-) delete mode 100644 src/assets/color.h delete mode 100644 src/assets/material.h delete mode 100644 src/chunks/materials.h delete mode 100644 src/chunks/normals.h delete mode 100644 src/chunks/triangles.h delete mode 100644 src/chunks/vertices.h delete mode 100644 src/geometry/matrix4x4.h delete mode 100644 src/geometry/quaternion.h delete mode 100644 src/geometry/triangle.h delete mode 100644 src/ms3d/ms3d.cpp delete mode 100644 src/ms3d/ms3d.h delete mode 100644 src/obj/obj.cpp delete mode 100644 src/obj/obj.h delete mode 100644 src/sm/sm.cpp delete mode 100644 src/sm/sm.h diff --git a/.gitignore b/.gitignore index 67d4158..0334f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ Debug/ Release/ ipch/ *.suo -meshconverter +md2tomesh diff --git a/Makefile b/Makefile index 50988f8..9ddab30 100644 --- a/Makefile +++ b/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 diff --git a/src/assets/color.h b/src/assets/color.h deleted file mode 100644 index 56c51dd..0000000 --- a/src/assets/color.h +++ /dev/null @@ -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 diff --git a/src/assets/material.h b/src/assets/material.h deleted file mode 100644 index ba63028..0000000 --- a/src/assets/material.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ASSETS_MATERIAL_H_INCLUDED__ -#define __ASSETS_MATERIAL_H_INCLUDED__ - -#include "../common.h" -#include -#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 diff --git a/src/chunks/chunks.cpp b/src/chunks/chunks.cpp index ee4b38f..309e1bf 100644 --- a/src/chunks/chunks.cpp +++ b/src/chunks/chunks.cpp @@ -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); } } + diff --git a/src/chunks/chunks.h b/src/chunks/chunks.h index 8cb4fb4..6143f84 100644 --- a/src/chunks/chunks.h +++ b/src/chunks/chunks.h @@ -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); diff --git a/src/chunks/materials.h b/src/chunks/materials.h deleted file mode 100644 index cfb10c2..0000000 --- a/src/chunks/materials.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __CHUNK_MATERIALS_H_INCLUDED__ -#define __CHUNK_MATERIALS_H_INCLUDED__ - -#include "../common.h" -#include "../assets/material.h" -#include - -struct MaterialsChunk -{ - std::vector 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 diff --git a/src/chunks/normals.h b/src/chunks/normals.h deleted file mode 100644 index a32fd67..0000000 --- a/src/chunks/normals.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __CHUNKS_NORMALS_H_INCLUDED__ -#define __CHUNKS_NORMALS_H_INCLUDED__ - -#include "../common.h" -#include "../geometry/vector3.h" -#include - -struct NormalsChunk -{ - std::vector 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 diff --git a/src/chunks/triangles.h b/src/chunks/triangles.h deleted file mode 100644 index 066af71..0000000 --- a/src/chunks/triangles.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __CHUNKS_TRIANGLES_H_INCLUDED__ -#define __CHUNKS_TRIANGLES_H_INCLUDED__ - -#include "../common.h" -#include "../geometry/triangle.h" -#include - -struct TrianglesChunk -{ - std::vector 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 diff --git a/src/chunks/vertices.h b/src/chunks/vertices.h deleted file mode 100644 index 9f5860a..0000000 --- a/src/chunks/vertices.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __CHUNKS_VERTICES_H_INCLUDED__ -#define __CHUNKS_VERTICES_H_INCLUDED__ - -#include "../common.h" -#include "../geometry/vector3.h" -#include - -struct VerticesChunk -{ - std::vector 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 diff --git a/src/geometry/matrix4x4.h b/src/geometry/matrix4x4.h deleted file mode 100644 index f17d954..0000000 --- a/src/geometry/matrix4x4.h +++ /dev/null @@ -1,1030 +0,0 @@ -#ifndef __GEOMETRY_MATRIX4X4_H_INCLUDED__ -#define __GEOMETRY_MATRIX4X4_H_INCLUDED__ - -#include -#include "common.h" -#include "vector3.h" - -enum MATRIX_ELEMENTS -{ - _11 = 0, - _12 = 4, - _13 = 8, - _14 = 12, - _21 = 1, - _22 = 5, - _23 = 9, - _24 = 13, - _31 = 2, - _32 = 6, - _33 = 10, - _34 = 14, - _41 = 3, - _42 = 7, - _43 = 11, - _44 = 15 -}; - -/** - * Represents a 4x4 column-major Matrix and provides common methods for - * matrix math. - *

Referenced/based on code from:

- *
    - *
  • 3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)
  • - *
  • http://www.dhpoware.com/source/mathlib.html
  • - *
  • http://www.songho.ca/opengl/gl_transform.html
  • - *
  • http://www.opengl.org/sdk/docs/man/
  • - *
- * @author Gered - */ -class Matrix4x4 -{ -public: - Matrix4x4() {} - - Matrix4x4( - float m11, float m12, float m13, float m14, - float m21, float m22, float m23, float m24, - float m31, float m32, float m33, float m34, - float m41, float m42, float m43, float m44 - ); - - Matrix4x4(const float *mv); - - ~Matrix4x4() {} - - void Set( - float m11, float m12, float m13, float m14, - float m21, float m22, float m23, float m24, - float m31, float m32, float m33, float m34, - float m41, float m42, float m43, float m44 - ); - float GetDeterminant() const; - Vector3 GetForward() const; - Vector3 GetBackward() const; - Vector3 GetLeft() const; - Vector3 GetRight() const; - Vector3 GetUp() const; - Vector3 GetDown() const; - Vector3 GetTranslation() const; - - static Matrix4x4 Identity(); - static Matrix4x4 CreateBillboard(const Vector3 &objectPosition, const Vector3 &cameraPosition, const Vector3 &cameraUp, const Vector3 &cameraForward); - static Matrix4x4 CreateCylindricalBillboard(const Vector3 &objectPosition, const Vector3 &cameraPosition, const Vector3 &cameraForward, const Vector3 &axis); - static Matrix4x4 CreateFromEulerAngles(float x, float y, float z); - static Matrix4x4 CreateLookAt(const Vector3 &cameraPosition, const Vector3 &cameraTarget, const Vector3 &cameraUp); - static Matrix4x4 CreateOrthographic(float left, float right, float bottom, float top, float near_, float far_); - static Matrix4x4 CreatePerspective(float left, float right, float bottom, float top, float near_, float far_); - static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float near_, float far_); - static Matrix4x4 CreateRotation(float angle, const Vector3 &axis); - static Matrix4x4 CreateRotationX(float angle); - static Matrix4x4 CreateRotationY(float angle); - static Matrix4x4 CreateRotationZ(float angle); - static Matrix4x4 CreateScale(float x, float y, float z); - static Matrix4x4 CreateTranslation(float x, float y, float z); - static Matrix4x4 CreateWorld(const Vector3 &position, const Vector3 &forward, const Vector3 &up); - static Matrix4x4 Inverse(const Matrix4x4 &m); - static Matrix4x4 Transpose(const Matrix4x4 &m); - - float m[16]; -}; - -Matrix4x4 operator+(const Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 &operator+=(Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 operator-(const Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 &operator-=(Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 operator*(const Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 &operator*=(Matrix4x4 &left, const Matrix4x4 &right); -Matrix4x4 operator*(const Matrix4x4 &left, float right); -Matrix4x4 &operator*=(Matrix4x4 &left, float right); -Vector3 operator*(const Vector3 &left, const Matrix4x4 &right); - -#define IDENTITY_MATRIX Matrix4x4::Identity() - -inline Matrix4x4::Matrix4x4( - float m11, float m12, float m13, float m14, - float m21, float m22, float m23, float m24, - float m31, float m32, float m33, float m34, - float m41, float m42, float m43, float m44 - ) -{ - m[_11] = m11; - m[_12] = m12; - m[_13] = m13; - m[_14] = m14; - m[_21] = m21; - m[_22] = m22; - m[_23] = m23; - m[_24] = m24; - m[_31] = m31; - m[_32] = m32; - m[_33] = m33; - m[_34] = m34; - m[_41] = m41; - m[_42] = m42; - m[_43] = m43; - m[_44] = m44; -} - -inline Matrix4x4::Matrix4x4(const float *mv) -{ - m[_11] = mv[_11]; - m[_12] = mv[_12]; - m[_13] = mv[_13]; - m[_14] = mv[_14]; - m[_21] = mv[_21]; - m[_22] = mv[_22]; - m[_23] = mv[_23]; - m[_24] = mv[_24]; - m[_31] = mv[_31]; - m[_32] = mv[_32]; - m[_33] = mv[_33]; - m[_34] = mv[_34]; - m[_41] = mv[_41]; - m[_42] = mv[_42]; - m[_43] = mv[_43]; - m[_44] = mv[_44]; -} - -inline void Matrix4x4::Set( - float m11, float m12, float m13, float m14, - float m21, float m22, float m23, float m24, - float m31, float m32, float m33, float m34, - float m41, float m42, float m43, float m44 - ) -{ - m[_11] = m11; - m[_12] = m12; - m[_13] = m13; - m[_14] = m14; - m[_21] = m21; - m[_22] = m22; - m[_23] = m23; - m[_24] = m24; - m[_31] = m31; - m[_32] = m32; - m[_33] = m33; - m[_34] = m34; - m[_41] = m41; - m[_42] = m42; - m[_43] = m43; - m[_44] = m44; -} - -/** - * Gets the determinant of the matrix. - * @return the determinant - */ -inline float Matrix4x4::GetDeterminant() const -{ - return - (m[_11] * m[_22] - m[_21] * m[_12]) * - (m[_33] * m[_44] - m[_43] * m[_34]) - - (m[_11] * m[_32] - m[_31] * m[_12]) * - (m[_23] * m[_44] - m[_43] * m[_24]) + - (m[_11] * m[_42] - m[_41] * m[_12]) * - (m[_23] * m[_34] - m[_33] * m[_24]) + - (m[_21] * m[_32] - m[_31] * m[_22]) * - (m[_13] * m[_44] - m[_43] * m[_14]) - - (m[_21] * m[_42] - m[_41] * m[_22]) * - (m[_13] * m[_34] - m[_33] * m[_14]) + - (m[_31] * m[_42] - m[_41] * m[_32]) * - (m[_13] * m[_24] - m[_23] * m[_14]); -} - -/** - * @return Vector3 the forward vector (z-axis) - */ -inline Vector3 Matrix4x4::GetForward() const -{ - return Vector3(m[_13], m[_23], m[_33]); -} - -/** - * @return Vector3 the backward vector (inverse z-axis) - */ -inline Vector3 Matrix4x4::GetBackward() const -{ - return Vector3(-m[_13], -m[_23], -m[_33]); -} - -/** - * @return Vector3 the left vector (x-axis) - */ -inline Vector3 Matrix4x4::GetLeft() const -{ - return Vector3(m[_11], m[_21], m[_31]); -} - -/** - * @return Vector3 the right vector (inverse x-axis) - */ -inline Vector3 Matrix4x4::GetRight() const -{ - return Vector3(-m[_11], -m[_21], -m[_31]); -} - -/** - * @return Vector3 the up vector (y-axis) - */ -inline Vector3 Matrix4x4::GetUp() const -{ - return Vector3(m[_12], m[_22], m[_32]); -} - -/** - * @return Vector3 the down vector (inverse y-axis) - */ -inline Vector3 Matrix4x4::GetDown() const -{ - return Vector3(-m[_12], -m[_22], -m[_32]); -} - -/** - * @return Vector3 the translation vector - */ -inline Vector3 Matrix4x4::GetTranslation() const -{ - return Vector3(m[_14], m[_24], m[_34]); -} - -/** - * @return Matrix4x4 identity matrix - */ -inline Matrix4x4 Matrix4x4::Identity() -{ - Matrix4x4 identity; - - identity.m[_11] = 1.0f; - identity.m[_12] = 0.0f; - identity.m[_13] = 0.0f; - identity.m[_14] = 0.0f; - identity.m[_21] = 0.0f; - identity.m[_22] = 1.0f; - identity.m[_23] = 0.0f; - identity.m[_24] = 0.0f; - identity.m[_31] = 0.0f; - identity.m[_32] = 0.0f; - identity.m[_33] = 1.0f; - identity.m[_34] = 0.0f; - identity.m[_41] = 0.0f; - identity.m[_42] = 0.0f; - identity.m[_43] = 0.0f; - identity.m[_44] = 1.0f; - - return identity; -} - -/** - * Constructs a point billboard (spherical billboard) transformation matrix. - * @param objectPosition the position of the billboard object - * @param cameraPosition the position of the camera viewing the billboard - * @param cameraUp the up vector of the camera - * @param cameraForward the forward vector of the camera - * @return a billboard transformation matrix - */ -inline Matrix4x4 Matrix4x4::CreateBillboard(const Vector3 &objectPosition, const Vector3 &cameraPosition, const Vector3 &cameraUp, const Vector3 &cameraForward) -{ - Vector3 forward = objectPosition - cameraPosition; - float forwardLengthSquared = Vector3::LengthSquared(forward); - if (forwardLengthSquared < 0.0001f) - forward = -cameraForward; - else - forward = forward * (1.0f / (sqrtf(forwardLengthSquared))); - - Vector3 left = Vector3::Normalize(Vector3::Cross(cameraUp, forward)); - Vector3 up = Vector3::Cross(forward, left); - - Matrix4x4 out; - - out.m[_11] = left.x; - out.m[_21] = left.y; - out.m[_31] = left.z; - out.m[_41] = 0.0f; - - out.m[_12] = up.x; - out.m[_22] = up.y; - out.m[_32] = up.z; - out.m[_42] = 0.0f; - - out.m[_13] = forward.x; - out.m[_23] = forward.y; - out.m[_33] = forward.z; - out.m[_43] = 0.0f; - - out.m[_14] = objectPosition.x; - out.m[_24] = objectPosition.y; - out.m[_34] = objectPosition.z; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Creates a transformation matrix for a billboard that is constrained to - * rotate about an arbitrary axis. - * @param objectPosition the position of the billboard object - * @param cameraPosition the position of the camera viewing the billboard - * @param cameraForward the forward vector of the camera - * @param axis the axis that the billboard is to rotate about - * @return a billboard transformation matrix - */ -inline Matrix4x4 Matrix4x4::CreateCylindricalBillboard(const Vector3 &objectPosition, const Vector3 &cameraPosition, const Vector3 &cameraForward, const Vector3 &axis) -{ - Vector3 temp = objectPosition - cameraPosition; - float lengthSquared = Vector3::LengthSquared(temp); - if (lengthSquared < 0.0001f) - temp = -cameraForward; - else - temp = temp * (1.0f / (sqrtf(lengthSquared))); - - Vector3 up = axis; - Vector3 forward; - Vector3 left; - - float dot = Vector3::Dot(axis, temp); - if (fabs(dot) > 0.9982547f) - { - dot = Vector3::Dot(axis, FORWARD); - if (fabs(dot) > 0.9982547f) - forward = RIGHT; - else - forward = FORWARD; - - left = Vector3::Normalize(Vector3::Cross(axis, forward)); - forward = Vector3::Normalize(Vector3::Cross(left, axis)); - } - else - { - left = Vector3::Normalize(Vector3::Cross(axis, temp)); - forward = Vector3::Normalize(Vector3::Cross(left, up)); - } - - Matrix4x4 out; - - out.m[_11] = left.x; - out.m[_21] = left.y; - out.m[_31] = left.z; - out.m[_41] = 0.0f; - - out.m[_12] = up.x; - out.m[_22] = up.y; - out.m[_32] = up.z; - out.m[_42] = 0.0f; - - out.m[_13] = forward.x; - out.m[_23] = forward.y; - out.m[_33] = forward.z; - out.m[_43] = 0.0f; - - out.m[_14] = objectPosition.x; - out.m[_24] = objectPosition.y; - out.m[_34] = objectPosition.z; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a rotation matrix from euler angles (specified in radians). - * @param x the x angle - * @param y the y angle - * @param z the z angle - * @return a rotation matrix representing the provided angles - */ -inline Matrix4x4 Matrix4x4::CreateFromEulerAngles(float x, float y, float z) -{ - Matrix4x4 rotateZ = CreateRotationZ(z); - Matrix4x4 rotateY = CreateRotationY(y); - Matrix4x4 rotateX = CreateRotationX(x); - - // "right-to-left" column-major matrix concatenation - return rotateZ * rotateY * rotateX; -} - -/** - * Constructs a modelview matrix. This constructs the same matrix as a call - * to gluLookAt. - * @param cameraPosition position of the camera (eye) - * @param cameraTarget the direction the camera is pointing (center) - * @param cameraUp the up direction relative to the camera - * @return a modelview matrix - */ -inline Matrix4x4 Matrix4x4::CreateLookAt(const Vector3 &cameraPosition, const Vector3 &cameraTarget, const Vector3 &cameraUp) -{ - Matrix4x4 out; - - // build basic lookat matrix without translation component included - Vector3 forward = Vector3::Normalize(cameraTarget - cameraPosition); - Vector3 left = Vector3::Normalize(Vector3::Cross(forward, cameraUp)); - Vector3 up = Vector3::Cross(left, forward); - - out.m[_11] = left.x; - out.m[_21] = up.x; - out.m[_31] = -forward.x; - out.m[_41] = 0.0f; - - out.m[_12] = left.y; - out.m[_22] = up.y; - out.m[_32] = -forward.y; - out.m[_42] = 0.0f; - - out.m[_13] = left.z; - out.m[_23] = up.z; - out.m[_33] = -forward.z; - out.m[_43] = 0.0f; - - out.m[_14] = 0.0f; - out.m[_24] = 0.0f; - out.m[_34] = 0.0f; - out.m[_44] = 1.0f; - - // multiply the translation into the lookat matrix - // this matrix multiplication is simplified so that we're only multiplying components that can actually affect the result - // out = Matrix4x4::CreateTranslation(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z) * out; - out.m[_14] = out.m[_11] * -cameraPosition.x + out.m[_12] * -cameraPosition.y + out.m[_13] * -cameraPosition.z + out.m[_14]; - out.m[_24] = out.m[_21] * -cameraPosition.x + out.m[_22] * -cameraPosition.y + out.m[_23] * -cameraPosition.z + out.m[_24]; - out.m[_34] = out.m[_31] * -cameraPosition.x + out.m[_32] * -cameraPosition.y + out.m[_33] * -cameraPosition.z + out.m[_34]; - out.m[_44] = out.m[_41] * -cameraPosition.x + out.m[_42] * -cameraPosition.y + out.m[_43] * -cameraPosition.z + out.m[_44]; - - return out; -} - -/** - * Creates an orthogonal projection matrix. This is equivalent to a matrix - * created by using OpenGL's glOrtho() function. - * @param left coordinate of the left vertical clipping plane - * @param right coordinate of the right vertical clipping plane - * @param bottom coordinate of the bottom horizontal clipping plane - * @param top coordinate of the top horizontal clipping plane - * @param near near clipping plane distance (negative value is behind the viewer) - * @param far far clipping plane distance (negative value is behind the viewer) - * @return an orthogonal projection matrix - */ -inline Matrix4x4 Matrix4x4::CreateOrthographic(float left, float right, float bottom, float top, float near_, float far_) -{ - Matrix4x4 out; - - out.m[_11] = 2.0f / (right - left); - out.m[_12] = 0.0f; - out.m[_13] = 0.0f; - out.m[_14] = -((right + left) / (right - left)); - - out.m[_21] = 0.0f; - out.m[_22] = 2.0f / (top - bottom); - out.m[_23] = 0.0f; - out.m[_24] = -((top + bottom) / (top - bottom)); - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = -2.0f / (far_ - near_); - out.m[_34] = -((far_ + near_) / (far_ - near_)); - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a perspective projection matrix. This is equivalent to a - * matrix created by using OpenGL's glFrustum() function. - * @param left coordinate of the left vertical clipping plane - * @param right coordinate of the right vertical clipping plane - * @param bottom coordinate of the bottom horizontal clipping plane - * @param top coordinate of the top horizontal clipping plane - * @param near near clipping plane distance - * @param far far clipping plane distance - * @return a perspective projection matrix - */ -inline Matrix4x4 Matrix4x4::CreatePerspective(float left, float right, float bottom, float top, float near_, float far_) -{ - Matrix4x4 out; - - out.m[_11] = (2.0f * near_) / (right - left); - out.m[_12] = 0.0f; - out.m[_13] = (right + left) / (right - left); - out.m[_14] = 0.0f; - - out.m[_21] = 0.0f; - out.m[_22] = (2.0f * near_) / (top - bottom); - out.m[_23] = (top + bottom) / (top - bottom); - out.m[_24] = 0.0f; - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = -((far_ + near_)) / (far_ - near_); - out.m[_34] = -((2.0f * far_ * near_)) / (far_ - near_); - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = -1.0f; - out.m[_44] = 0.0f; - - return out; -} - -/** - * Constructs a perspective projection matrix. This is equivalent to a - * matrix created by using OpenGL's gluPerspective() function. - * @param fieldOfView the field of view in the y direction (specified in radians) - * @param aspectRatio the aspect ratio of the viewport - * @param near near clipping plane distance - * @param far far clipping plane distance - * @return a perspective projection matrix - */ -inline Matrix4x4 Matrix4x4::CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float near_, float far_) -{ - Matrix4x4 out; - - float f = 1.0f / tanf(fieldOfView / 2.0f); - - out.m[_11] = f / aspectRatio; - out.m[_12] = 0.0f; - out.m[_13] = 0.0f; - out.m[_14] = 0.0f; - - out.m[_21] = 0.0f; - out.m[_22] = f; - out.m[_23] = 0.0f; - out.m[_24] = 0.0f; - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = (far_ + near_) / (near_ - far_); - out.m[_34] = (2.0f * far_ * near_) / (near_ - far_); - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = -1.0f; - out.m[_44] = 0.0f; - - return out; -} - -/** - * Sets up a rotation matrix about the specified axis. This returns a matrix - * equivalent to the matrix that OpenGL multiples into the modelview matrix - * whenever glRotate(angle, axis.x, axis.y, axis.z) is called. - * @param angle angle in radians to rotate - * @param axis unit vector denoting the axis for the rotation - * @return a rotation matrix representing the specific axis rotation - */ -inline Matrix4x4 Matrix4x4::CreateRotation(float angle, const Vector3 &axis) -{ - Matrix4x4 out; - - float s = sinf(angle); - float c = cosf(angle); - - out.m[_11] = (axis.x * axis.x) * (1.0f - c) + c; - out.m[_12] = (axis.x * axis.y) * (1.0f - c) - (axis.z * s); - out.m[_13] = (axis.x * axis.z) * (1.0f - c) + (axis.y * s); - out.m[_14] = 0.0f; - - out.m[_21] = (axis.y * axis.x) * (1.0f - c) + (axis.z * s); - out.m[_22] = (axis.y * axis.y) * (1.0f - c) + c; - out.m[_23] = (axis.y * axis.z) * (1.0f - c) - (axis.x * s); - out.m[_24] = 0.0f; - - out.m[_31] = (axis.z * axis.x) * (1.0f - c) - (axis.y * s); - out.m[_32] = (axis.z * axis.y) * (1.0f - c) + (axis.x * s); - out.m[_33] = (axis.z * axis.z) * (1.0f - c) + c; - out.m[_34] = 0.0f; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a rotation matrix for a rotation around the x axis. This returns - * a matrix equivalent to the matrix that OpenGL multiples into the modelview - * matrix whenever glRotate(angle, 1.0f, 0.0f, 0.0f) is called. - * @param angle angle to rotate the x axis around (in radians) - * @return the rotation matrix - */ -inline Matrix4x4 Matrix4x4::CreateRotationX(float angle) -{ - Matrix4x4 out; - - float s = sinf(angle); - float c = cosf(angle); - - out.m[_11] = 1.0f; - out.m[_12] = 0.0f; - out.m[_13] = 0.0f; - out.m[_14] = 0.0f; - - out.m[_21] = 0.0f; - out.m[_22] = c; - out.m[_23] = -s; - out.m[_24] = 0.0f; - - out.m[_31] = 0.0f; - out.m[_32] = s; - out.m[_33] = c; - out.m[_34] = 0.0f; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a rotation matrix for a rotation around the y axis. This returns - * a matrix equivalent to the matrix that OpenGL multiples into the modelview - * matrix whenever glRotate(angle, 0.0f, 1.0f, 0.0f) is called. - * @param angle angle to rotate the y axis around (in radians) - * @return the rotation matrix - */ -inline Matrix4x4 Matrix4x4::CreateRotationY(float angle) -{ - Matrix4x4 out; - - float s = sinf(angle); - float c = cosf(angle); - - out.m[_11] = c; - out.m[_12] = 0.0f; - out.m[_13] = s; - out.m[_14] = 0.0f; - - out.m[_21] = 0.0f; - out.m[_22] = 1.0f; - out.m[_23] = 0.0f; - out.m[_24] = 0.0f; - - out.m[_31] = -s; - out.m[_32] = 0.0f; - out.m[_33] = c; - out.m[_34] = 0.0f; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a rotation matrix for a rotation around the z axis. This returns - * a matrix equivalent to the matrix that OpenGL multiples into the modelview - * matrix whenever glRotate(angle, 0.0f, 0.0f, 1.0f) is called. - * @param angle angle to rotate the z axis around (in radians) - * @return the rotation matrix - */ -inline Matrix4x4 Matrix4x4::CreateRotationZ(float angle) -{ - Matrix4x4 out; - - float s = sinf(angle); - float c = cosf(angle); - - out.m[_11] = c; - out.m[_12] = -s; - out.m[_13] = 0.0f; - out.m[_14] = 0.0f; - - out.m[_21] = s; - out.m[_22] = c; - out.m[_23] = 0.0f; - out.m[_24] = 0.0f; - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = 1.0f; - out.m[_34] = 0.0f; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a scaling matrix from scaling factors for each axis. This returns - * a matrix equivalent to the matrix that OpenGL multiples into the modelview - * matrix whenever glScale(x, y, z) is called. - * @param x the scale factor for the x axis - * @param y the scale factor for the y axis - * @param z the scale factor for the z axis - * @return a scaling matrix - */ -inline Matrix4x4 Matrix4x4::CreateScale(float x, float y, float z) -{ - Matrix4x4 out; - - out.m[_11] = x; - out.m[_12] = 0.0f; - out.m[_13] = 0.0f; - out.m[_14] = 0.0f; - - out.m[_21] = 0.0f; - out.m[_22] = y; - out.m[_23] = 0.0f; - out.m[_24] = 0.0f; - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = z; - out.m[_34] = 0.0f; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a translation matrix. This returns a matrix equivalent to the - * matrix that OpenGL multiples into the modelview matrix whenever - * glTranslate(x, y, z) is called. - * @param x the amount to translate on the x axis - * @param y the amount to translate on the y axis - * @param z the amount to translate on the z axis - * @return a translation matrix - */ -inline Matrix4x4 Matrix4x4::CreateTranslation(float x, float y, float z) -{ - Matrix4x4 out; - - out.m[_11] = 1.0f; - out.m[_12] = 0.0f; - out.m[_13] = 0.0f; - out.m[_14] = x; - - out.m[_21] = 0.0f; - out.m[_22] = 1.0f; - out.m[_23] = 0.0f; - out.m[_24] = y; - - out.m[_31] = 0.0f; - out.m[_32] = 0.0f; - out.m[_33] = 1.0f; - out.m[_34] = z; - - out.m[_41] = 0.0f; - out.m[_42] = 0.0f; - out.m[_43] = 0.0f; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Constructs a world matrix. - * @param position the position of the object (translation) - * @param forward the forward facing direction of the object - * @param up the up direction of the object - * @return a world matrix - */ -inline Matrix4x4 Matrix4x4::CreateWorld(const Vector3 &position, const Vector3 &forward, const Vector3 &up) -{ - Matrix4x4 out; - - Vector3 f = Vector3::Normalize(-forward); - Vector3 l = Vector3::Normalize(Vector3::Cross(up, f)); - Vector3 u = Vector3::Cross(f, l); - - out.m[_11] = l.x; - out.m[_21] = l.y; - out.m[_31] = l.z; - out.m[_41] = 0.0f; - - out.m[_12] = u.x; - out.m[_22] = u.y; - out.m[_32] = u.z; - out.m[_42] = 0.0f; - - out.m[_13] = f.x; - out.m[_23] = f.y; - out.m[_33] = f.z; - out.m[_43] = 0.0f; - - out.m[_14] = position.x; - out.m[_24] = position.y; - out.m[_34] = position.z; - out.m[_44] = 1.0f; - - return out; -} - -/** - * Calculates the inverse of the specified matrix. - * @param m the matrix to calculate the inverse of - * @return the inverse of the specified matrix - */ -inline Matrix4x4 Matrix4x4::Inverse(const Matrix4x4 &m) -{ - float d = m.GetDeterminant(); - if (IS_CLOSE_ENOUGH(d, 0.0f)) - return IDENTITY_MATRIX; - else - { - Matrix4x4 out; - - d = 1.0f / d; - - out.m[_11] = d * (m.m[_22] * (m.m[_33] * m.m[_44] - m.m[_43] * m.m[_34]) + m.m[_32] * (m.m[_43] * m.m[_24] - m.m[_23] * m.m[_44]) + m.m[_42] * (m.m[_23] * m.m[_34] - m.m[_33] * m.m[_24])); - out.m[_21] = d * (m.m[_23] * (m.m[_31] * m.m[_44] - m.m[_41] * m.m[_34]) + m.m[_33] * (m.m[_41] * m.m[_24] - m.m[_21] * m.m[_44]) + m.m[_43] * (m.m[_21] * m.m[_34] - m.m[_31] * m.m[_24])); - out.m[_31] = d * (m.m[_24] * (m.m[_31] * m.m[_42] - m.m[_41] * m.m[_32]) + m.m[_34] * (m.m[_41] * m.m[_22] - m.m[_21] * m.m[_42]) + m.m[_44] * (m.m[_21] * m.m[_32] - m.m[_31] * m.m[_22])); - out.m[_41] = d * (m.m[_21] * (m.m[_42] * m.m[_33] - m.m[_32] * m.m[_43]) + m.m[_31] * (m.m[_22] * m.m[_43] - m.m[_42] * m.m[_23]) + m.m[_41] * (m.m[_32] * m.m[_23] - m.m[_22] * m.m[_33])); - - out.m[_12] = d * (m.m[_32] * (m.m[_13] * m.m[_44] - m.m[_43] * m.m[_14]) + m.m[_42] * (m.m[_33] * m.m[_14] - m.m[_13] * m.m[_34]) + m.m[_12] * (m.m[_43] * m.m[_34] - m.m[_33] * m.m[_44])); - out.m[_22] = d * (m.m[_33] * (m.m[_11] * m.m[_44] - m.m[_41] * m.m[_14]) + m.m[_43] * (m.m[_31] * m.m[_14] - m.m[_11] * m.m[_34]) + m.m[_13] * (m.m[_41] * m.m[_34] - m.m[_31] * m.m[_44])); - out.m[_32] = d * (m.m[_34] * (m.m[_11] * m.m[_42] - m.m[_41] * m.m[_12]) + m.m[_44] * (m.m[_31] * m.m[_12] - m.m[_11] * m.m[_32]) + m.m[_14] * (m.m[_41] * m.m[_32] - m.m[_31] * m.m[_42])); - out.m[_42] = d * (m.m[_31] * (m.m[_42] * m.m[_13] - m.m[_12] * m.m[_43]) + m.m[_41] * (m.m[_12] * m.m[_33] - m.m[_32] * m.m[_13]) + m.m[_11] * (m.m[_32] * m.m[_43] - m.m[_42] * m.m[_33])); - - out.m[_13] = d * (m.m[_42] * (m.m[_13] * m.m[_24] - m.m[_23] * m.m[_14]) + m.m[_12] * (m.m[_23] * m.m[_44] - m.m[_43] * m.m[_24]) + m.m[_22] * (m.m[_43] * m.m[_14] - m.m[_13] * m.m[_44])); - out.m[_23] = d * (m.m[_43] * (m.m[_11] * m.m[_24] - m.m[_21] * m.m[_14]) + m.m[_13] * (m.m[_21] * m.m[_44] - m.m[_41] * m.m[_24]) + m.m[_23] * (m.m[_41] * m.m[_14] - m.m[_11] * m.m[_44])); - out.m[_33] = d * (m.m[_44] * (m.m[_11] * m.m[_22] - m.m[_21] * m.m[_12]) + m.m[_14] * (m.m[_21] * m.m[_42] - m.m[_41] * m.m[_22]) + m.m[_24] * (m.m[_41] * m.m[_12] - m.m[_11] * m.m[_42])); - out.m[_43] = d * (m.m[_41] * (m.m[_22] * m.m[_13] - m.m[_12] * m.m[_23]) + m.m[_11] * (m.m[_42] * m.m[_23] - m.m[_22] * m.m[_43]) + m.m[_21] * (m.m[_12] * m.m[_43] - m.m[_42] * m.m[_13])); - - out.m[_14] = d * (m.m[_12] * (m.m[_33] * m.m[_24] - m.m[_23] * m.m[_34]) + m.m[_22] * (m.m[_13] * m.m[_34] - m.m[_33] * m.m[_14]) + m.m[_32] * (m.m[_23] * m.m[_14] - m.m[_13] * m.m[_24])); - out.m[_24] = d * (m.m[_13] * (m.m[_31] * m.m[_24] - m.m[_21] * m.m[_34]) + m.m[_23] * (m.m[_11] * m.m[_34] - m.m[_31] * m.m[_14]) + m.m[_33] * (m.m[_21] * m.m[_14] - m.m[_11] * m.m[_24])); - out.m[_34] = d * (m.m[_14] * (m.m[_31] * m.m[_22] - m.m[_21] * m.m[_32]) + m.m[_24] * (m.m[_11] * m.m[_32] - m.m[_31] * m.m[_12]) + m.m[_34] * (m.m[_21] * m.m[_12] - m.m[_11] * m.m[_22])); - out.m[_44] = d * (m.m[_11] * (m.m[_22] * m.m[_33] - m.m[_32] * m.m[_23]) + m.m[_21] * (m.m[_32] * m.m[_13] - m.m[_12] * m.m[_33]) + m.m[_31] * (m.m[_12] * m.m[_23] - m.m[_22] * m.m[_13])); - - return out; - } -} - -/** - * Calculates the transpose of a given matrix. - * @param m the matrix to get the transpose of - * @return the transpose matrix - */ -inline Matrix4x4 Matrix4x4::Transpose(const Matrix4x4 &m) -{ - Matrix4x4 out; - - out.m[_11] = m.m[_11]; - out.m[_12] = m.m[_21]; - out.m[_13] = m.m[_31]; - out.m[_14] = m.m[_41]; - - out.m[_21] = m.m[_12]; - out.m[_22] = m.m[_22]; - out.m[_23] = m.m[_32]; - out.m[_24] = m.m[_42]; - - out.m[_31] = m.m[_13]; - out.m[_32] = m.m[_23]; - out.m[_33] = m.m[_33]; - out.m[_34] = m.m[_43]; - - out.m[_41] = m.m[_14]; - out.m[_42] = m.m[_24]; - out.m[_43] = m.m[_34]; - out.m[_44] = m.m[_44]; - - return out; -} - -inline Matrix4x4 operator+(const Matrix4x4 &left, const Matrix4x4 &right) -{ - Matrix4x4 result; - - result.m[_11] = left.m[_11] + right.m[_11]; - result.m[_12] = left.m[_12] + right.m[_12]; - result.m[_13] = left.m[_13] + right.m[_13]; - result.m[_14] = left.m[_14] + right.m[_14]; - result.m[_21] = left.m[_21] + right.m[_21]; - result.m[_22] = left.m[_22] + right.m[_22]; - result.m[_23] = left.m[_23] + right.m[_23]; - result.m[_24] = left.m[_24] + right.m[_24]; - result.m[_31] = left.m[_31] + right.m[_31]; - result.m[_32] = left.m[_32] + right.m[_32]; - result.m[_33] = left.m[_33] + right.m[_33]; - result.m[_34] = left.m[_34] + right.m[_34]; - result.m[_41] = left.m[_41] + right.m[_41]; - result.m[_42] = left.m[_42] + right.m[_42]; - result.m[_43] = left.m[_43] + right.m[_43]; - result.m[_44] = left.m[_44] + right.m[_44]; - - return result; -} - -inline Matrix4x4 &operator+=(Matrix4x4 &left, const Matrix4x4 &right) -{ - left = left + right; - return left; -} - -inline Matrix4x4 operator-(const Matrix4x4 &left, const Matrix4x4 &right) -{ - Matrix4x4 result; - - result.m[_11] = left.m[_11] - right.m[_11]; - result.m[_12] = left.m[_12] - right.m[_12]; - result.m[_13] = left.m[_13] - right.m[_13]; - result.m[_14] = left.m[_14] - right.m[_14]; - result.m[_21] = left.m[_21] - right.m[_21]; - result.m[_22] = left.m[_22] - right.m[_22]; - result.m[_23] = left.m[_23] - right.m[_23]; - result.m[_24] = left.m[_24] - right.m[_24]; - result.m[_31] = left.m[_31] - right.m[_31]; - result.m[_32] = left.m[_32] - right.m[_32]; - result.m[_33] = left.m[_33] - right.m[_33]; - result.m[_34] = left.m[_34] - right.m[_34]; - result.m[_41] = left.m[_41] - right.m[_41]; - result.m[_42] = left.m[_42] - right.m[_42]; - result.m[_43] = left.m[_43] - right.m[_43]; - result.m[_44] = left.m[_44] - right.m[_44]; - - return result; -} - -inline Matrix4x4 &operator-=(Matrix4x4 &left, const Matrix4x4 &right) -{ - left = left - right; - return left; -} - -inline Matrix4x4 operator*(const Matrix4x4 &left, const Matrix4x4 &right) -{ - Matrix4x4 result; - - result.m[_11] = left.m[_11] * right.m[_11] + left.m[_12] * right.m[_21] + left.m[_13] * right.m[_31] + left.m[_14] * right.m[_41]; - result.m[_12] = left.m[_11] * right.m[_12] + left.m[_12] * right.m[_22] + left.m[_13] * right.m[_32] + left.m[_14] * right.m[_42]; - result.m[_13] = left.m[_11] * right.m[_13] + left.m[_12] * right.m[_23] + left.m[_13] * right.m[_33] + left.m[_14] * right.m[_43]; - result.m[_14] = left.m[_11] * right.m[_14] + left.m[_12] * right.m[_24] + left.m[_13] * right.m[_34] + left.m[_14] * right.m[_44]; - - result.m[_21] = left.m[_21] * right.m[_11] + left.m[_22] * right.m[_21] + left.m[_23] * right.m[_31] + left.m[_24] * right.m[_41]; - result.m[_22] = left.m[_21] * right.m[_12] + left.m[_22] * right.m[_22] + left.m[_23] * right.m[_32] + left.m[_24] * right.m[_42]; - result.m[_23] = left.m[_21] * right.m[_13] + left.m[_22] * right.m[_23] + left.m[_23] * right.m[_33] + left.m[_24] * right.m[_43]; - result.m[_24] = left.m[_21] * right.m[_14] + left.m[_22] * right.m[_24] + left.m[_23] * right.m[_34] + left.m[_24] * right.m[_44]; - - result.m[_31] = left.m[_31] * right.m[_11] + left.m[_32] * right.m[_21] + left.m[_33] * right.m[_31] + left.m[_34] * right.m[_41]; - result.m[_32] = left.m[_31] * right.m[_12] + left.m[_32] * right.m[_22] + left.m[_33] * right.m[_32] + left.m[_34] * right.m[_42]; - result.m[_33] = left.m[_31] * right.m[_13] + left.m[_32] * right.m[_23] + left.m[_33] * right.m[_33] + left.m[_34] * right.m[_43]; - result.m[_34] = left.m[_31] * right.m[_14] + left.m[_32] * right.m[_24] + left.m[_33] * right.m[_34] + left.m[_34] * right.m[_44]; - - result.m[_41] = left.m[_41] * right.m[_11] + left.m[_42] * right.m[_21] + left.m[_43] * right.m[_31] + left.m[_44] * right.m[_41]; - result.m[_42] = left.m[_41] * right.m[_12] + left.m[_42] * right.m[_22] + left.m[_43] * right.m[_32] + left.m[_44] * right.m[_42]; - result.m[_43] = left.m[_41] * right.m[_13] + left.m[_42] * right.m[_23] + left.m[_43] * right.m[_33] + left.m[_44] * right.m[_43]; - result.m[_44] = left.m[_41] * right.m[_14] + left.m[_42] * right.m[_24] + left.m[_43] * right.m[_34] + left.m[_44] * right.m[_44]; - - return result; -} - -inline Matrix4x4 &operator*=(Matrix4x4 &left, const Matrix4x4 &right) -{ - left = left * right; - return left; -} - -inline Matrix4x4 operator*(const Matrix4x4 &left, float right) -{ - Matrix4x4 result; - - result.m[_11] = left.m[_11] * right; - result.m[_12] = left.m[_12] * right; - result.m[_13] = left.m[_13] * right; - result.m[_14] = left.m[_14] * right; - result.m[_21] = left.m[_21] * right; - result.m[_22] = left.m[_22] * right; - result.m[_23] = left.m[_23] * right; - result.m[_24] = left.m[_24] * right; - result.m[_31] = left.m[_31] * right; - result.m[_32] = left.m[_32] * right; - result.m[_33] = left.m[_33] * right; - result.m[_34] = left.m[_34] * right; - result.m[_41] = left.m[_41] * right; - result.m[_42] = left.m[_42] * right; - result.m[_43] = left.m[_43] * right; - result.m[_44] = left.m[_44] * right; - - return result; -} - -inline Matrix4x4 &operator*=(Matrix4x4 &left, float right) -{ - left = left * right; - return left; -} - -inline Vector3 operator*(const Vector3 &left, const Matrix4x4 &right) -{ - return Vector3( - left.x * right.m[_11] + left.y * right.m[_12] + left.z * right.m[_13] + right.m[_14], - left.x * right.m[_21] + left.y * right.m[_22] + left.z * right.m[_23] + right.m[_24], - left.x * right.m[_31] + left.y * right.m[_32] + left.z * right.m[_33] + right.m[_34] - ); -} - -#endif diff --git a/src/geometry/quaternion.h b/src/geometry/quaternion.h deleted file mode 100644 index d21ed2d..0000000 --- a/src/geometry/quaternion.h +++ /dev/null @@ -1,491 +0,0 @@ -#ifndef __GEOMETRY_QUATERNION_H_INCLUDED__ -#define __GEOMETRY_QUATERNION_H_INCLUDED__ - -#include -#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 - *

Referenced/based on code from:

- *
    - *
  • 3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)
  • - *
  • More OpenGL Game Programming (Dave Astle, 2006)
  • - *
  • http://www.dhpoware.com/source/mathlib.html
  • - *
- * @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 diff --git a/src/geometry/triangle.h b/src/geometry/triangle.h deleted file mode 100644 index d0f6909..0000000 --- a/src/geometry/triangle.h +++ /dev/null @@ -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 diff --git a/src/main.cpp b/src/main.cpp index 8b34121..4b5dce0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,18 +3,14 @@ #include #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,73 +36,15 @@ int main(int argc, char **argv) meshFile.append(".mesh"); } - if (extension == ".obj") + Md2 *md2 = new Md2(); + if (!md2->Load(file)) { - 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; - } + printf("Error loading MD2 file.\n\n"); + return 1; } - else if (extension == ".md2") + if (!md2->ConvertToMesh(meshFile)) { - printf("Using MD2 converter.\n"); - - Md2 *md2 = new Md2(); - if (!md2->Load(file)) - { - printf("Error loading MD2 file.\n\n"); - return 1; - } - if (!md2->ConvertToMesh(meshFile)) - { - 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"); + printf("Error converting MD2 to MESH.\n\n"); return 1; } @@ -114,4 +52,4 @@ int main(int argc, char **argv) return 0; -} \ No newline at end of file +} diff --git a/src/ms3d/ms3d.cpp b/src/ms3d/ms3d.cpp deleted file mode 100644 index 8134788..0000000 --- a/src/ms3d/ms3d.cpp +++ /dev/null @@ -1,437 +0,0 @@ -#include "ms3d.h" - -#include -#include -#include - -#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; -} diff --git a/src/ms3d/ms3d.h b/src/ms3d/ms3d.h deleted file mode 100644 index d6c85b0..0000000 --- a/src/ms3d/ms3d.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef __MS3D_H_INCLUDED__ -#define __MS3D_H_INCLUDED__ - -#include -#include "../geometry/vector3.h" -#include "../geometry/vector2.h" -#include - -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 m_animations; -}; - -#endif diff --git a/src/obj/obj.cpp b/src/obj/obj.cpp deleted file mode 100644 index 3d738f6..0000000 --- a/src/obj/obj.cpp +++ /dev/null @@ -1,496 +0,0 @@ -#include "obj.h" - -#include -#include -#include -#include - -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; -} diff --git a/src/obj/obj.h b/src/obj/obj.h deleted file mode 100644 index 9ebea87..0000000 --- a/src/obj/obj.h +++ /dev/null @@ -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 - -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 diff --git a/src/sm/sm.cpp b/src/sm/sm.cpp deleted file mode 100644 index 13d2419..0000000 --- a/src/sm/sm.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "sm.h" - -#include -#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; -} diff --git a/src/sm/sm.h b/src/sm/sm.h deleted file mode 100644 index 95147d0..0000000 --- a/src/sm/sm.h +++ /dev/null @@ -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 - - -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