added SM loader and stub for converting to MESH

This commit is contained in:
gered 2010-06-23 20:37:37 -04:00
parent a45c1704f3
commit e0996a381d
4 changed files with 303 additions and 0 deletions

View file

@ -78,6 +78,7 @@
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\md2\md2.cpp" />
<ClCompile Include="src\obj\obj.cpp" />
<ClCompile Include="src\sm\sm.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\assets\material.h" />
@ -85,6 +86,7 @@
<ClInclude Include="src\geometry\vector3.h" />
<ClInclude Include="src\md2\md2.h" />
<ClInclude Include="src\obj\obj.h" />
<ClInclude Include="src\sm\sm.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -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");

213
MeshConverter/src/sm/sm.cpp Normal file
View file

@ -0,0 +1,213 @@
#include "sm.h"
#include <stdio.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, 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;
}

73
MeshConverter/src/sm/sm.h Normal file
View file

@ -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 <string>
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