From e0996a381de294b569f997c7b591a62ed118d605 Mon Sep 17 00:00:00 2001 From: gered Date: Wed, 23 Jun 2010 20:37:37 -0400 Subject: [PATCH] added SM loader and stub for converting to MESH --- MeshConverter/MeshConverter.vcxproj | 2 + MeshConverter/src/main.cpp | 15 ++ MeshConverter/src/sm/sm.cpp | 213 ++++++++++++++++++++++++++++ MeshConverter/src/sm/sm.h | 73 ++++++++++ 4 files changed, 303 insertions(+) create mode 100644 MeshConverter/src/sm/sm.cpp create mode 100644 MeshConverter/src/sm/sm.h diff --git a/MeshConverter/MeshConverter.vcxproj b/MeshConverter/MeshConverter.vcxproj index ef10192..3f4239d 100644 --- a/MeshConverter/MeshConverter.vcxproj +++ b/MeshConverter/MeshConverter.vcxproj @@ -78,6 +78,7 @@ + @@ -85,6 +86,7 @@ + diff --git a/MeshConverter/src/main.cpp b/MeshConverter/src/main.cpp index b843c71..f1b9152 100644 --- a/MeshConverter/src/main.cpp +++ b/MeshConverter/src/main.cpp @@ -4,6 +4,7 @@ #include "md2/md2.h" #include "obj/obj.h" +#include "sm/sm.h" int main(int argc, char **argv) { @@ -66,6 +67,20 @@ int main(int argc, char **argv) return 1; } } + else if (extension == ".sm") + { + 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 { printf("Unrecognized file type.\n\n"); diff --git a/MeshConverter/src/sm/sm.cpp b/MeshConverter/src/sm/sm.cpp new file mode 100644 index 0000000..4716ba9 --- /dev/null +++ b/MeshConverter/src/sm/sm.cpp @@ -0,0 +1,213 @@ +#include "sm.h" + +#include + +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, const std::string &texturePath) +{ + FILE *fp; + unsigned short numMaterials; + unsigned int numPolys, numVertices, numNormals, numTexCoords; + unsigned int ambient, diffuse, specular, emission; + unsigned int n; + int currentMaterial; + int count; + float x, y, z; + unsigned char header[2]; + unsigned char c; + 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->SetAmbient(ambient); + m_materials[i].material->SetDiffuse(diffuse); + m_materials[i].material->SetSpecular(specular); + m_materials[i].material->SetEmission(emission); + + // Read up to the null terminator on the texture filename (could be any length) + count = 0; + texture = ""; + do + { + fread(&c, 1, 1, fp); + if (c) + texture += c; + } while (c != '\0'); + m_materials[i].material->SetTexture(texturePath + texture); + } + + // 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) +{ + return true; +} diff --git a/MeshConverter/src/sm/sm.h b/MeshConverter/src/sm/sm.h new file mode 100644 index 0000000..39311bd --- /dev/null +++ b/MeshConverter/src/sm/sm.h @@ -0,0 +1,73 @@ +#ifndef __SM_H_INCLUDED__ +#define __SM_H_INCLUDED__ + +#include "../assets/material.h" +#include "../geometry/vector3.h" +#include "../geometry/vector2.h" +#include + + +typedef struct +{ + unsigned int vertices[3]; + unsigned int normals[3]; + unsigned int texcoords[3]; + unsigned short colors[3]; + short material; +} SmPolygon; + +typedef struct SmMaterial +{ + Material *material; + unsigned int polyStart; + unsigned int polyEnd; + + SmMaterial() + { + material = new Material(); + polyStart = 0; + polyEnd = 0; + }; + + ~SmMaterial() + { + delete material; + } +} SmMaterial; + +#define NO_MATERIAL -1 + +class StaticModel +{ +public: + StaticModel(); + virtual ~StaticModel() { Release(); } + + void Release(); + bool Load(const std::string &file, const std::string &texturePath); + 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 \ No newline at end of file