This commit is contained in:
gered 2011-06-07 11:30:05 -04:00
parent 978f2aa08e
commit 87a60137f1
36 changed files with 5105 additions and 5105 deletions

18
.gitignore vendored
View file

@ -1,10 +1,10 @@
*.sdf *.sdf
*.opensdf *.opensdf
*.user *.user
*.vcxproj.filters *.vcxproj.filters
Debug/ Debug/
Release/ Release/
ipch/ ipch/
*.suo *.suo

View file

@ -1,20 +1,20 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshConverter", "MeshConverter\MeshConverter.vcxproj", "{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshConverter", "MeshConverter\MeshConverter.vcxproj", "{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Debug|Win32.ActiveCfg = Debug|Win32 {AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Debug|Win32.ActiveCfg = Debug|Win32
{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Debug|Win32.Build.0 = Debug|Win32 {AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Debug|Win32.Build.0 = Debug|Win32
{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Release|Win32.ActiveCfg = Release|Win32 {AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Release|Win32.ActiveCfg = Release|Win32
{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Release|Win32.Build.0 = Release|Win32 {AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View file

@ -1,122 +1,122 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}</ProjectGuid> <ProjectGuid>{AADE0387-ED8A-46E2-B2DA-FC521DF7CB9C}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>MeshConverter</RootNamespace> <RootNamespace>MeshConverter</RootNamespace>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>E:\assimp--2.0.863-sdk\include;$(IncludePath)</IncludePath> <IncludePath>E:\assimp--2.0.863-sdk\include;$(IncludePath)</IncludePath>
<LibraryPath>E:\assimp--2.0.863-sdk\lib\assimp_debug-dll_win32;$(LibraryPath)</LibraryPath> <LibraryPath>E:\assimp--2.0.863-sdk\lib\assimp_debug-dll_win32;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>E:\assimp--2.0.863-sdk\include;$(IncludePath)</IncludePath> <IncludePath>E:\assimp--2.0.863-sdk\include;$(IncludePath)</IncludePath>
<LibraryPath>E:\assimp--2.0.863-sdk\lib\assimp_release-dll_win32;$(LibraryPath)</LibraryPath> <LibraryPath>E:\assimp--2.0.863-sdk\lib\assimp_release-dll_win32;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PrecompiledHeader> <PrecompiledHeader>
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>assimp.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<PrecompiledHeader> <PrecompiledHeader>
</PrecompiledHeader> </PrecompiledHeader>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>assimp.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\chunks\chunks.cpp" /> <ClCompile Include="src\chunks\chunks.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
<ClCompile Include="src\md2\md2.cpp" /> <ClCompile Include="src\md2\md2.cpp" />
<ClCompile Include="src\ms3d\ms3d.cpp" /> <ClCompile Include="src\ms3d\ms3d.cpp" />
<ClCompile Include="src\obj\obj.cpp" /> <ClCompile Include="src\obj\obj.cpp" />
<ClCompile Include="src\sm\sm.cpp" /> <ClCompile Include="src\sm\sm.cpp" />
<ClCompile Include="src\util\files.cpp" /> <ClCompile Include="src\util\files.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\assets\animationsequence.h" /> <ClInclude Include="src\assets\animationsequence.h" />
<ClInclude Include="src\assets\color.h" /> <ClInclude Include="src\assets\color.h" />
<ClInclude Include="src\assets\material.h" /> <ClInclude Include="src\assets\material.h" />
<ClInclude Include="src\chunks\animations.h" /> <ClInclude Include="src\chunks\animations.h" />
<ClInclude Include="src\chunks\chunks.h" /> <ClInclude Include="src\chunks\chunks.h" />
<ClInclude Include="src\chunks\keyframes.h" /> <ClInclude Include="src\chunks\keyframes.h" />
<ClInclude Include="src\chunks\keyframetriangles.h" /> <ClInclude Include="src\chunks\keyframetriangles.h" />
<ClInclude Include="src\chunks\materials.h" /> <ClInclude Include="src\chunks\materials.h" />
<ClInclude Include="src\chunks\normals.h" /> <ClInclude Include="src\chunks\normals.h" />
<ClInclude Include="src\chunks\texcoords.h" /> <ClInclude Include="src\chunks\texcoords.h" />
<ClInclude Include="src\chunks\triangles.h" /> <ClInclude Include="src\chunks\triangles.h" />
<ClInclude Include="src\chunks\vertices.h" /> <ClInclude Include="src\chunks\vertices.h" />
<ClInclude Include="src\common.h" /> <ClInclude Include="src\common.h" />
<ClInclude Include="src\geometry\common.h" /> <ClInclude Include="src\geometry\common.h" />
<ClInclude Include="src\geometry\keyframe.h" /> <ClInclude Include="src\geometry\keyframe.h" />
<ClInclude Include="src\geometry\keyframetriangle.h" /> <ClInclude Include="src\geometry\keyframetriangle.h" />
<ClInclude Include="src\geometry\matrix4x4.h" /> <ClInclude Include="src\geometry\matrix4x4.h" />
<ClInclude Include="src\geometry\quaternion.h" /> <ClInclude Include="src\geometry\quaternion.h" />
<ClInclude Include="src\geometry\triangle.h" /> <ClInclude Include="src\geometry\triangle.h" />
<ClInclude Include="src\geometry\vector2.h" /> <ClInclude Include="src\geometry\vector2.h" />
<ClInclude Include="src\geometry\vector3.h" /> <ClInclude Include="src\geometry\vector3.h" />
<ClInclude Include="src\md2\md2.h" /> <ClInclude Include="src\md2\md2.h" />
<ClInclude Include="src\ms3d\ms3d.h" /> <ClInclude Include="src\ms3d\ms3d.h" />
<ClInclude Include="src\obj\obj.h" /> <ClInclude Include="src\obj\obj.h" />
<ClInclude Include="src\sm\sm.h" /> <ClInclude Include="src\sm\sm.h" />
<ClInclude Include="src\util\files.h" /> <ClInclude Include="src\util\files.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View file

@ -1,15 +1,15 @@
#ifndef __ASSETS_ANIMATIONSEQUENCE_H_INCLUDED__ #ifndef __ASSETS_ANIMATIONSEQUENCE_H_INCLUDED__
#define __ASSETS_ANIMATIONSEQUENCE_H_INCLUDED__ #define __ASSETS_ANIMATIONSEQUENCE_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include <string> #include <string>
class AnimationSequence class AnimationSequence
{ {
public: public:
std::string name; std::string name;
uint32_t start; uint32_t start;
uint32_t end; uint32_t end;
}; };
#endif #endif

View file

@ -1,80 +1,80 @@
#ifndef __ASSETS_COLOR_H_INCLUDED__ #ifndef __ASSETS_COLOR_H_INCLUDED__
#define __ASSETS_COLOR_H_INCLUDED__ #define __ASSETS_COLOR_H_INCLUDED__
#include "../common.h" #include "../common.h"
#define COLOR_ALPHA_TRANSPARENT 0.0f #define COLOR_ALPHA_TRANSPARENT 0.0f
#define COLOR_ALPHA_OPAQUE 1.0f #define COLOR_ALPHA_OPAQUE 1.0f
class Color class Color
{ {
public: public:
Color() Color()
{ {
r = 0.0f; r = 0.0f;
g = 0.0f; g = 0.0f;
b = 0.0f; b = 0.0f;
a = COLOR_ALPHA_OPAQUE; a = COLOR_ALPHA_OPAQUE;
} }
Color(float red, float green, float blue) Color(float red, float green, float blue)
{ {
r = red; r = red;
g = green; g = green;
b = blue; b = blue;
a = COLOR_ALPHA_OPAQUE; a = COLOR_ALPHA_OPAQUE;
} }
Color(float red, float green, float blue, float alpha) Color(float red, float green, float blue, float alpha)
{ {
r = red; r = red;
g = green; g = green;
b = blue; b = blue;
a = alpha; a = alpha;
} }
uint32_t ToInt() uint32_t ToInt()
{ {
return ((uint32_t)(a * 255) << 24) | ((uint32_t)(r * 255) << 16) | ((uint32_t)(g * 255) << 8) | (uint32_t)(b * 255); 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) static uint32_t ToInt(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{ {
return (a << 24) | (r << 16) | (g << 8) | b; return (a << 24) | (r << 16) | (g << 8) | b;
} }
static uint32_t ToInt(float r, float g, float b, float a) 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); 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) static void FromInt(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a)
{ {
*a = (color & 0xff000000) >> 24; *a = (color & 0xff000000) >> 24;
*r = (color & 0x00ff0000) >> 16; *r = (color & 0x00ff0000) >> 16;
*g = (color & 0x0000ff00) >> 8; *g = (color & 0x0000ff00) >> 8;
*b = (color & 0x000000ff); *b = (color & 0x000000ff);
} }
static void FromInt(uint32_t color, float *r, float *g, float *b, float *a) static void FromInt(uint32_t color, float *r, float *g, float *b, float *a)
{ {
*a = ((float)((color & 0xff000000) >> 24)) / 255; *a = ((float)((color & 0xff000000) >> 24)) / 255;
*r = ((float)((color & 0x00ff0000) >> 16)) / 255; *r = ((float)((color & 0x00ff0000) >> 16)) / 255;
*g = ((float)((color & 0x0000ff00) >> 8)) / 255; *g = ((float)((color & 0x0000ff00) >> 8)) / 255;
*b = ((float)((color & 0x000000ff))) / 255; *b = ((float)((color & 0x000000ff))) / 255;
} }
static Color FromInt(uint32_t color) static Color FromInt(uint32_t color)
{ {
Color out; Color out;
FromInt(color, &out.r, &out.g, &out.b, &out.a); FromInt(color, &out.r, &out.g, &out.b, &out.a);
return out; return out;
} }
float r; float r;
float g; float g;
float b; float b;
float a; float a;
}; };
#endif #endif

View file

@ -1,25 +1,25 @@
#ifndef __ASSETS_MATERIAL_H_INCLUDED__ #ifndef __ASSETS_MATERIAL_H_INCLUDED__
#define __ASSETS_MATERIAL_H_INCLUDED__ #define __ASSETS_MATERIAL_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include <string> #include <string>
#include "color.h" #include "color.h"
#define RGB_32(r, g, b, a) ((b)|((g) << 8)|((r) << 16)|((a) << 24)) #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_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_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)) #define RGB_24_f(r, g, b) RGB_24((int)((r) * 255), (int)((g) * 255), (int)((b) * 255))
class Material class Material
{ {
public: public:
std::string name; std::string name;
Color ambient; Color ambient;
Color diffuse; Color diffuse;
Color specular; Color specular;
Color emissive; Color emissive;
float shininess; float shininess;
float opacity; float opacity;
}; };
#endif #endif

View file

@ -1,33 +1,33 @@
#ifndef __CHUNKS_ANIMATIONS_H_INCLUDED__ #ifndef __CHUNKS_ANIMATIONS_H_INCLUDED__
#define __CHUNKS_ANIMATIONS_H_INCLUDED__ #define __CHUNKS_ANIMATIONS_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../assets/animationsequence.h" #include "../assets/animationsequence.h"
#include <vector> #include <vector>
struct AnimationsChunk struct AnimationsChunk
{ {
std::vector<AnimationSequence> animations; std::vector<AnimationSequence> animations;
uint32_t GetCount() uint32_t GetCount()
{ {
return animations.size(); return animations.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (animations.size() == 0) if (animations.size() == 0)
return 0; return 0;
uint32_t size = sizeof(uint32_t); uint32_t size = sizeof(uint32_t);
for (uint32_t i = 0; i < animations.size(); ++i) for (uint32_t i = 0; i < animations.size(); ++i)
{ {
size += animations[i].name.length() + 1; // include null terminator size += animations[i].name.length() + 1; // include null terminator
size += sizeof(uint32_t) * 2; // start + end size += sizeof(uint32_t) * 2; // start + end
} }
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,221 +1,221 @@
#include "chunks.h" #include "chunks.h"
void WriteFileHeader(FILE *fp) void WriteFileHeader(FILE *fp)
{ {
fputs("MESH", fp); fputs("MESH", fp);
uint8_t version = 1; uint8_t version = 1;
fwrite(&version, 1, 1, fp); fwrite(&version, 1, 1, fp);
} }
void WriteChunk(VerticesChunk *chunk, FILE *fp) void WriteChunk(VerticesChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("VTX", fp); fputs("VTX", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
fwrite(&chunk->vertices[i].x, sizeof(float), 1, fp); fwrite(&chunk->vertices[i].x, sizeof(float), 1, fp);
fwrite(&chunk->vertices[i].y, sizeof(float), 1, fp); fwrite(&chunk->vertices[i].y, sizeof(float), 1, fp);
fwrite(&chunk->vertices[i].z, sizeof(float), 1, fp); fwrite(&chunk->vertices[i].z, sizeof(float), 1, fp);
} }
} }
void WriteChunk(NormalsChunk *chunk, FILE *fp) void WriteChunk(NormalsChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("NRL", fp); fputs("NRL", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
fwrite(&chunk->normals[i].x, sizeof(float), 1, fp); fwrite(&chunk->normals[i].x, sizeof(float), 1, fp);
fwrite(&chunk->normals[i].y, sizeof(float), 1, fp); fwrite(&chunk->normals[i].y, sizeof(float), 1, fp);
fwrite(&chunk->normals[i].z, sizeof(float), 1, fp); fwrite(&chunk->normals[i].z, sizeof(float), 1, fp);
} }
} }
void WriteChunk(TexCoordsChunk *chunk, FILE *fp) void WriteChunk(TexCoordsChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("TXT", fp); fputs("TXT", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
fwrite(&chunk->texCoords[i].x, sizeof(float), 1, fp); fwrite(&chunk->texCoords[i].x, sizeof(float), 1, fp);
fwrite(&chunk->texCoords[i].y, sizeof(float), 1, fp); fwrite(&chunk->texCoords[i].y, sizeof(float), 1, fp);
} }
} }
void WriteChunk(MaterialsChunk *chunk, FILE *fp) void WriteChunk(MaterialsChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("MTL", fp); fputs("MTL", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
Material *m = &chunk->materials[i]; Material *m = &chunk->materials[i];
fwrite(m->name.c_str(), m->name.length(), 1, fp); fwrite(m->name.c_str(), m->name.length(), 1, fp);
char ch = '\0'; char ch = '\0';
fwrite(&ch, 1, 1, fp); fwrite(&ch, 1, 1, fp);
fwrite(&m->ambient.r, sizeof(float), 1, fp); fwrite(&m->ambient.r, sizeof(float), 1, fp);
fwrite(&m->ambient.g, sizeof(float), 1, fp); fwrite(&m->ambient.g, sizeof(float), 1, fp);
fwrite(&m->ambient.b, sizeof(float), 1, fp); fwrite(&m->ambient.b, sizeof(float), 1, fp);
fwrite(&m->ambient.a, sizeof(float), 1, fp); fwrite(&m->ambient.a, sizeof(float), 1, fp);
fwrite(&m->diffuse.r, sizeof(float), 1, fp); fwrite(&m->diffuse.r, sizeof(float), 1, fp);
fwrite(&m->diffuse.g, sizeof(float), 1, fp); fwrite(&m->diffuse.g, sizeof(float), 1, fp);
fwrite(&m->diffuse.b, sizeof(float), 1, fp); fwrite(&m->diffuse.b, sizeof(float), 1, fp);
fwrite(&m->diffuse.a, sizeof(float), 1, fp); fwrite(&m->diffuse.a, sizeof(float), 1, fp);
fwrite(&m->specular.r, sizeof(float), 1, fp); fwrite(&m->specular.r, sizeof(float), 1, fp);
fwrite(&m->specular.g, sizeof(float), 1, fp); fwrite(&m->specular.g, sizeof(float), 1, fp);
fwrite(&m->specular.b, sizeof(float), 1, fp); fwrite(&m->specular.b, sizeof(float), 1, fp);
fwrite(&m->specular.a, sizeof(float), 1, fp); fwrite(&m->specular.a, sizeof(float), 1, fp);
fwrite(&m->emissive.r, sizeof(float), 1, fp); fwrite(&m->emissive.r, sizeof(float), 1, fp);
fwrite(&m->emissive.g, sizeof(float), 1, fp); fwrite(&m->emissive.g, sizeof(float), 1, fp);
fwrite(&m->emissive.b, sizeof(float), 1, fp); fwrite(&m->emissive.b, sizeof(float), 1, fp);
fwrite(&m->emissive.a, sizeof(float), 1, fp); fwrite(&m->emissive.a, sizeof(float), 1, fp);
fwrite(&m->shininess, sizeof(float), 1, fp); fwrite(&m->shininess, sizeof(float), 1, fp);
fwrite(&m->opacity, sizeof(float), 1, fp); fwrite(&m->opacity, sizeof(float), 1, fp);
} }
} }
void WriteChunk(TrianglesChunk *chunk, FILE *fp) void WriteChunk(TrianglesChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("TRI", fp); fputs("TRI", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
Triangle *t = &chunk->triangles[i]; Triangle *t = &chunk->triangles[i];
fwrite(&t->vertices[0], 4, 1, fp); fwrite(&t->vertices[0], 4, 1, fp);
fwrite(&t->vertices[1], 4, 1, fp); fwrite(&t->vertices[1], 4, 1, fp);
fwrite(&t->vertices[2], 4, 1, fp); fwrite(&t->vertices[2], 4, 1, fp);
fwrite(&t->normals[0], 4, 1, fp); fwrite(&t->normals[0], 4, 1, fp);
fwrite(&t->normals[1], 4, 1, fp); fwrite(&t->normals[1], 4, 1, fp);
fwrite(&t->normals[2], 4, 1, fp); fwrite(&t->normals[2], 4, 1, fp);
fwrite(&t->texCoords[0], 4, 1, fp); fwrite(&t->texCoords[0], 4, 1, fp);
fwrite(&t->texCoords[1], 4, 1, fp); fwrite(&t->texCoords[1], 4, 1, fp);
fwrite(&t->texCoords[2], 4, 1, fp); fwrite(&t->texCoords[2], 4, 1, fp);
fwrite(&t->materialIndex, 4, 1, fp); fwrite(&t->materialIndex, 4, 1, fp);
} }
} }
void WriteChunk(KeyFramesChunk *chunk, FILE *fp) void WriteChunk(KeyFramesChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("KFR", fp); fputs("KFR", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t numFrames = chunk->GetNumFrames(); uint32_t numFrames = chunk->GetNumFrames();
fwrite(&numFrames, 4, 1, fp); fwrite(&numFrames, 4, 1, fp);
fwrite(&chunk->numVertices, 4, 1, fp); fwrite(&chunk->numVertices, 4, 1, fp);
for (uint32_t i = 0; i < numFrames; ++i) for (uint32_t i = 0; i < numFrames; ++i)
{ {
KeyFrame *f = chunk->frames[i]; KeyFrame *f = chunk->frames[i];
for (uint32_t j = 0; j < chunk->numVertices; ++j) for (uint32_t j = 0; j < chunk->numVertices; ++j)
{ {
fwrite(&f->vertices->x, sizeof(float), 1, fp); fwrite(&f->vertices->x, sizeof(float), 1, fp);
fwrite(&f->vertices->y, sizeof(float), 1, fp); fwrite(&f->vertices->y, sizeof(float), 1, fp);
fwrite(&f->vertices->z, sizeof(float), 1, fp); fwrite(&f->vertices->z, sizeof(float), 1, fp);
} }
for (uint32_t j = 0; j < chunk->numVertices; ++j) for (uint32_t j = 0; j < chunk->numVertices; ++j)
{ {
fwrite(&f->normals->x, sizeof(float), 1, fp); fwrite(&f->normals->x, sizeof(float), 1, fp);
fwrite(&f->normals->y, sizeof(float), 1, fp); fwrite(&f->normals->y, sizeof(float), 1, fp);
fwrite(&f->normals->z, sizeof(float), 1, fp); fwrite(&f->normals->z, sizeof(float), 1, fp);
} }
} }
} }
void WriteChunk(KeyFrameTrianglesChunk *chunk, FILE *fp) void WriteChunk(KeyFrameTrianglesChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("KTR", fp); fputs("KTR", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
KeyFrameTriangle *t = &chunk->triangles[i]; KeyFrameTriangle *t = &chunk->triangles[i];
fwrite(&t->vertices[0], 4, 1, fp); fwrite(&t->vertices[0], 4, 1, fp);
fwrite(&t->vertices[1], 4, 1, fp); fwrite(&t->vertices[1], 4, 1, fp);
fwrite(&t->vertices[2], 4, 1, fp); fwrite(&t->vertices[2], 4, 1, fp);
fwrite(&t->texCoords[0], 4, 1, fp); fwrite(&t->texCoords[0], 4, 1, fp);
fwrite(&t->texCoords[1], 4, 1, fp); fwrite(&t->texCoords[1], 4, 1, fp);
fwrite(&t->texCoords[2], 4, 1, fp); fwrite(&t->texCoords[2], 4, 1, fp);
} }
} }
void WriteChunk(AnimationsChunk *chunk, FILE *fp) void WriteChunk(AnimationsChunk *chunk, FILE *fp)
{ {
uint32_t size = chunk->GetSize(); uint32_t size = chunk->GetSize();
if (size == 0) if (size == 0)
return; return;
fputs("ANI", fp); fputs("ANI", fp);
fwrite(&size, 4, 1, fp); fwrite(&size, 4, 1, fp);
uint32_t count = chunk->GetCount(); uint32_t count = chunk->GetCount();
fwrite(&count, 4, 1, fp); fwrite(&count, 4, 1, fp);
for (uint32_t i = 0; i < count; ++i) for (uint32_t i = 0; i < count; ++i)
{ {
AnimationSequence *a = &chunk->animations[i]; AnimationSequence *a = &chunk->animations[i];
fwrite(a->name.c_str(), a->name.length(), 1, fp); fwrite(a->name.c_str(), a->name.length(), 1, fp);
char ch = '\0'; char ch = '\0';
fwrite(&ch, 1, 1, fp); fwrite(&ch, 1, 1, fp);
fwrite(&a->start, 4, 1, fp); fwrite(&a->start, 4, 1, fp);
fwrite(&a->end, 4, 1, fp); fwrite(&a->end, 4, 1, fp);
} }
} }

View file

@ -1,29 +1,29 @@
#ifndef __CHUNKS_CHUNKS_H_INCLUDED__ #ifndef __CHUNKS_CHUNKS_H_INCLUDED__
#define __CHUNKS_CHUNKS_H_INCLUDED__ #define __CHUNKS_CHUNKS_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include <stdio.h> #include <stdio.h>
void WriteFileHeader(FILE *fp); 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 // 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 "vertices.h"
#include "normals.h" #include "normals.h"
#include "texcoords.h" #include "texcoords.h"
#include "materials.h" #include "materials.h"
#include "triangles.h" #include "triangles.h"
#include "keyframes.h" #include "keyframes.h"
#include "keyframetriangles.h" #include "keyframetriangles.h"
#include "animations.h" #include "animations.h"
void WriteChunk(VerticesChunk *chunk, FILE *fp); void WriteChunk(VerticesChunk *chunk, FILE *fp);
void WriteChunk(NormalsChunk *chunk, FILE *fp); void WriteChunk(NormalsChunk *chunk, FILE *fp);
void WriteChunk(TexCoordsChunk *chunk, FILE *fp); void WriteChunk(TexCoordsChunk *chunk, FILE *fp);
void WriteChunk(MaterialsChunk *chunk, FILE *fp); void WriteChunk(MaterialsChunk *chunk, FILE *fp);
void WriteChunk(TrianglesChunk *chunk, FILE *fp); void WriteChunk(TrianglesChunk *chunk, FILE *fp);
void WriteChunk(KeyFramesChunk *chunk, FILE *fp); void WriteChunk(KeyFramesChunk *chunk, FILE *fp);
void WriteChunk(KeyFrameTrianglesChunk *chunk, FILE *fp); void WriteChunk(KeyFrameTrianglesChunk *chunk, FILE *fp);
void WriteChunk(AnimationsChunk *chunk, FILE *fp); void WriteChunk(AnimationsChunk *chunk, FILE *fp);
#endif #endif

View file

@ -1,55 +1,55 @@
#ifndef __CHUNKS_KEYFRAMES_H_INCLUDED__ #ifndef __CHUNKS_KEYFRAMES_H_INCLUDED__
#define __CHUNKS_KEYFRAMES_H_INCLUDED__ #define __CHUNKS_KEYFRAMES_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/keyframe.h" #include "../geometry/keyframe.h"
#include <vector> #include <vector>
struct KeyFramesChunk struct KeyFramesChunk
{ {
std::vector<KeyFrame*> frames; std::vector<KeyFrame*> frames;
uint32_t numVertices; uint32_t numVertices;
KeyFramesChunk() KeyFramesChunk()
{ {
numVertices = 0; numVertices = 0;
} }
~KeyFramesChunk() ~KeyFramesChunk()
{ {
for (uint32_t i = 0; i < frames.size(); ++i) for (uint32_t i = 0; i < frames.size(); ++i)
SAFE_DELETE(frames[i]); SAFE_DELETE(frames[i]);
} }
KeyFrame* AddFrame() KeyFrame* AddFrame()
{ {
KeyFrame *newFrame = new KeyFrame(numVertices); KeyFrame *newFrame = new KeyFrame(numVertices);
frames.push_back(newFrame); frames.push_back(newFrame);
return newFrame; return newFrame;
} }
uint32_t GetNumFrames() uint32_t GetNumFrames()
{ {
return frames.size(); return frames.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (frames.size() == 0) if (frames.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
for (uint32_t i = 0; i < frames.size(); ++i) for (uint32_t i = 0; i < frames.size(); ++i)
{ {
size += size +=
( (
(sizeof(float) * 3) // vertex (sizeof(float) * 3) // vertex
+ (sizeof(float) * 3) // normal + (sizeof(float) * 3) // normal
) * frames[i]->count; ) * frames[i]->count;
} }
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,33 +1,33 @@
#ifndef __CHUNKS_KEYFRAMETRIANGLES_H_INCLUDED__ #ifndef __CHUNKS_KEYFRAMETRIANGLES_H_INCLUDED__
#define __CHUNKS_KEYFRAMETRIANGLES_H_INCLUDED__ #define __CHUNKS_KEYFRAMETRIANGLES_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/keyframetriangle.h" #include "../geometry/keyframetriangle.h"
#include <vector> #include <vector>
struct KeyFrameTrianglesChunk struct KeyFrameTrianglesChunk
{ {
std::vector<KeyFrameTriangle> triangles; std::vector<KeyFrameTriangle> triangles;
uint32_t GetCount() uint32_t GetCount()
{ {
return triangles.size(); return triangles.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (triangles.size() == 0) if (triangles.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
size += size +=
( (
(sizeof(uint32_t) * 3) // vertex indices (sizeof(uint32_t) * 3) // vertex indices
+ (sizeof(uint32_t) * 3) // texcoord indices + (sizeof(uint32_t) * 3) // texcoord indices
) * triangles.size(); ) * triangles.size();
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,38 +1,38 @@
#ifndef __CHUNK_MATERIALS_H_INCLUDED__ #ifndef __CHUNK_MATERIALS_H_INCLUDED__
#define __CHUNK_MATERIALS_H_INCLUDED__ #define __CHUNK_MATERIALS_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../assets/material.h" #include "../assets/material.h"
#include <vector> #include <vector>
struct MaterialsChunk struct MaterialsChunk
{ {
std::vector<Material> materials; std::vector<Material> materials;
uint32_t GetCount() uint32_t GetCount()
{ {
return materials.size(); return materials.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (materials.size() == 0) if (materials.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
for (uint32_t i = 0; i < materials.size(); ++i) for (uint32_t i = 0; i < materials.size(); ++i)
{ {
size += materials[i].name.length() + 1; // include null terminator size += materials[i].name.length() + 1; // include null terminator
size += sizeof(float) * 4; // ambient size += sizeof(float) * 4; // ambient
size += sizeof(float) * 4; // diffuse size += sizeof(float) * 4; // diffuse
size += sizeof(float) * 4; // specular size += sizeof(float) * 4; // specular
size += sizeof(float) * 4; // emissive size += sizeof(float) * 4; // emissive
size += sizeof(float); // shininess size += sizeof(float); // shininess
size += sizeof(float); // opacity size += sizeof(float); // opacity
} }
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,31 +1,31 @@
#ifndef __CHUNKS_NORMALS_H_INCLUDED__ #ifndef __CHUNKS_NORMALS_H_INCLUDED__
#define __CHUNKS_NORMALS_H_INCLUDED__ #define __CHUNKS_NORMALS_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include <vector> #include <vector>
struct NormalsChunk struct NormalsChunk
{ {
std::vector<Vector3> normals; std::vector<Vector3> normals;
uint32_t GetCount() uint32_t GetCount()
{ {
return normals.size(); return normals.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (normals.size() == 0) if (normals.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
size += size +=
(sizeof(float) * 3) // x, y, z (sizeof(float) * 3) // x, y, z
* normals.size(); * normals.size();
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,31 +1,31 @@
#ifndef __CHUNKS_TEXCOORDS_H_INCLUDED__ #ifndef __CHUNKS_TEXCOORDS_H_INCLUDED__
#define __CHUNKS_TEXCOORDS_H_INCLUDED__ #define __CHUNKS_TEXCOORDS_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/vector2.h" #include "../geometry/vector2.h"
#include <vector> #include <vector>
struct TexCoordsChunk struct TexCoordsChunk
{ {
std::vector<Vector2> texCoords; std::vector<Vector2> texCoords;
uint32_t GetCount() uint32_t GetCount()
{ {
return texCoords.size(); return texCoords.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (texCoords.size() == 0) if (texCoords.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
size += size +=
(sizeof(float) * 2) // u, v (sizeof(float) * 2) // u, v
* texCoords.size(); * texCoords.size();
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,35 +1,35 @@
#ifndef __CHUNKS_TRIANGLES_H_INCLUDED__ #ifndef __CHUNKS_TRIANGLES_H_INCLUDED__
#define __CHUNKS_TRIANGLES_H_INCLUDED__ #define __CHUNKS_TRIANGLES_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/triangle.h" #include "../geometry/triangle.h"
#include <vector> #include <vector>
struct TrianglesChunk struct TrianglesChunk
{ {
std::vector<Triangle> triangles; std::vector<Triangle> triangles;
uint32_t GetCount() uint32_t GetCount()
{ {
return triangles.size(); return triangles.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (triangles.size() == 0) if (triangles.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
size += size +=
( (
(4 * 3) // vertex indices (4 * 3) // vertex indices
+ (4 * 3) // normal indices + (4 * 3) // normal indices
+ (4 * 3) // texcoord indices + (4 * 3) // texcoord indices
+ 4 // material index + 4 // material index
) * triangles.size(); ) * triangles.size();
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,31 +1,31 @@
#ifndef __CHUNKS_VERTICES_H_INCLUDED__ #ifndef __CHUNKS_VERTICES_H_INCLUDED__
#define __CHUNKS_VERTICES_H_INCLUDED__ #define __CHUNKS_VERTICES_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include <vector> #include <vector>
struct VerticesChunk struct VerticesChunk
{ {
std::vector<Vector3> vertices; std::vector<Vector3> vertices;
uint32_t GetCount() uint32_t GetCount()
{ {
return vertices.size(); return vertices.size();
} }
uint32_t GetSize() uint32_t GetSize()
{ {
if (vertices.size() == 0) if (vertices.size() == 0)
return 0; return 0;
uint32_t size = 4; // count uint32_t size = 4; // count
size += size +=
(sizeof(float) * 3) // x, y, z (sizeof(float) * 3) // x, y, z
* vertices.size(); * vertices.size();
return size; return size;
} }
}; };
#endif #endif

View file

@ -1,27 +1,27 @@
#ifndef __COMMON_H_INCLUDED__ #ifndef __COMMON_H_INCLUDED__
#define __COMMON_H_INCLUDED__ #define __COMMON_H_INCLUDED__
#include <stdint.h> #include <stdint.h>
#if !defined(TRUE) && !defined(FALSE) #if !defined(TRUE) && !defined(FALSE)
typedef int32_t BOOL; typedef int32_t BOOL;
const BOOL TRUE = 1; const BOOL TRUE = 1;
const BOOL FALSE = 0; const BOOL FALSE = 0;
#endif #endif
#ifndef SAFE_RELEASE #ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = NULL; } #define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = NULL; }
#endif #endif
#ifndef SAFE_DELETE #ifndef SAFE_DELETE
#define SAFE_DELETE(x) if (x) { delete (x); (x) = NULL; } #define SAFE_DELETE(x) if (x) { delete (x); (x) = NULL; }
#endif #endif
#ifndef SAFE_DELETE_ARRAY #ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(x) if (x) { delete [] (x); (x) = NULL; } #define SAFE_DELETE_ARRAY(x) if (x) { delete [] (x); (x) = NULL; }
#endif #endif
#define MAX(a, b) ( (a) > (b) ? (a) : (b) ) #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
#define MIN(a, b) ( (a) < (b) ? (a) : (b) ) #define MIN(a, b) ( (a) < (b) ? (a) : (b) )
#endif #endif

View file

@ -1,19 +1,19 @@
#ifndef __GEOMETRY_COMMON_H_INCLUDED__ #ifndef __GEOMETRY_COMMON_H_INCLUDED__
#define __GEOMETRY_COMMON_H_INCLUDED__ #define __GEOMETRY_COMMON_H_INCLUDED__
#include <math.h> #include <math.h>
#define PI 3.141593f #define PI 3.141593f
#define PI_OVER_180 (PI / 180.0f) #define PI_OVER_180 (PI / 180.0f)
#define DEG_TO_RAD(x) ((x) * PI_OVER_180) #define DEG_TO_RAD(x) ((x) * PI_OVER_180)
#define RAD_TO_DEG(x) ((x) * (1.0f / (PI_OVER_180))) #define RAD_TO_DEG(x) ((x) * (1.0f / (PI_OVER_180)))
#define TOLERANCE 0.00001f #define TOLERANCE 0.00001f
#define IS_CLOSE_ENOUGH(a, b) (fabs((a - b) / ((b == 0.0f) ? 1.0f : b)) < EPSILON) #define IS_CLOSE_ENOUGH(a, b) (fabs((a - b) / ((b == 0.0f) ? 1.0f : b)) < EPSILON)
#define EPSILON 0.0005f #define EPSILON 0.0005f
#define ISPOWEROF2(x) (((x) != 0) && !((x) & ((x) - 1))) #define ISPOWEROF2(x) (((x) != 0) && !((x) & ((x) - 1)))
#endif #endif

View file

@ -1,28 +1,28 @@
#ifndef __GEOMETRY_KEYFRAME_H_INCLUDED__ #ifndef __GEOMETRY_KEYFRAME_H_INCLUDED__
#define __GEOMETRY_KEYFRAME_H_INCLUDED__ #define __GEOMETRY_KEYFRAME_H_INCLUDED__
#include "../common.h" #include "../common.h"
#include "vector3.h" #include "vector3.h"
class KeyFrame class KeyFrame
{ {
public: public:
uint32_t count; uint32_t count;
Vector3 *vertices; Vector3 *vertices;
Vector3 *normals; Vector3 *normals;
KeyFrame(uint32_t numVertices) KeyFrame(uint32_t numVertices)
{ {
count = numVertices; count = numVertices;
vertices = new Vector3[count]; vertices = new Vector3[count];
normals = new Vector3[count]; normals = new Vector3[count];
} }
~KeyFrame() ~KeyFrame()
{ {
SAFE_DELETE_ARRAY(vertices); SAFE_DELETE_ARRAY(vertices);
SAFE_DELETE_ARRAY(normals); SAFE_DELETE_ARRAY(normals);
} }
}; };
#endif #endif

View file

@ -1,13 +1,13 @@
#ifndef __GEOMETRY_KEYFRAMETRIANGLE_H_INCLUDED__ #ifndef __GEOMETRY_KEYFRAMETRIANGLE_H_INCLUDED__
#define __GEOMETRY_KEYFRAMETRIANGLE_H_INCLUDED__ #define __GEOMETRY_KEYFRAMETRIANGLE_H_INCLUDED__
#include "../common.h" #include "../common.h"
class KeyFrameTriangle class KeyFrameTriangle
{ {
public: public:
uint32_t vertices[3]; uint32_t vertices[3];
uint32_t texCoords[3]; uint32_t texCoords[3];
}; };
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,491 +1,491 @@
#ifndef __GEOMETRY_QUATERNION_H_INCLUDED__ #ifndef __GEOMETRY_QUATERNION_H_INCLUDED__
#define __GEOMETRY_QUATERNION_H_INCLUDED__ #define __GEOMETRY_QUATERNION_H_INCLUDED__
#include <math.h> #include <math.h>
#include "common.h" #include "common.h"
#include "vector3.h" #include "vector3.h"
#include "matrix4x4.h" #include "matrix4x4.h"
/** /**
* Represents a quaternion to store an orientation or angular * Represents a quaternion to store an orientation or angular
* displacement and provides methods for conversion/manipulation * displacement and provides methods for conversion/manipulation
* <p>Referenced/based on code from:</p> * <p>Referenced/based on code from:</p>
* <ul> * <ul>
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li> * <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
* <li>More OpenGL Game Programming (Dave Astle, 2006)</li> * <li>More OpenGL Game Programming (Dave Astle, 2006)</li>
* <li>http://www.dhpoware.com/source/mathlib.html</li> * <li>http://www.dhpoware.com/source/mathlib.html</li>
* </ul> * </ul>
* @author Gered * @author Gered
*/ */
class Quaternion class Quaternion
{ {
public: public:
Quaternion() {} Quaternion() {}
Quaternion(float w, float x, float y, float z) Quaternion(float w, float x, float y, float z)
{ {
this->w = w; this->w = w;
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z; this->z = z;
} }
Quaternion(float w, const Vector3 &v) Quaternion(float w, const Vector3 &v)
{ {
this->w = w; this->w = w;
this->x = v.x; this->x = v.x;
this->y = v.y; this->y = v.y;
this->z = v.z; this->z = v.z;
} }
Quaternion(const float *q) Quaternion(const float *q)
{ {
w = q[0]; w = q[0];
x = q[1]; x = q[1];
y = q[2]; y = q[2];
z = q[3]; z = q[3];
} }
~Quaternion() {} ~Quaternion() {}
void Set(float w, float x, float y, float z); void Set(float w, float x, float y, float z);
Matrix4x4 ToMatrix() const; Matrix4x4 ToMatrix() const;
Vector3 GetVector() const; Vector3 GetVector() const;
static Quaternion Cross(const Quaternion &a, const Quaternion &b); static Quaternion Cross(const Quaternion &a, const Quaternion &b);
static float Dot(const Quaternion &a, const Quaternion &b); static float Dot(const Quaternion &a, const Quaternion &b);
static float Length(const Quaternion &q); static float Length(const Quaternion &q);
static float LengthSquared(const Quaternion &q); static float LengthSquared(const Quaternion &q);
static Quaternion Normalize(const Quaternion &q); static Quaternion Normalize(const Quaternion &q);
static Quaternion Conjugate(const Quaternion &q); static Quaternion Conjugate(const Quaternion &q);
static Quaternion Inverse(const Quaternion &q); static Quaternion Inverse(const Quaternion &q);
static Quaternion CreateFromEulerAngles(float x, float y, float z); static Quaternion CreateFromEulerAngles(float x, float y, float z);
static Quaternion CreateFromAxisAngle(float angle, const Vector3 &axis); static Quaternion CreateFromAxisAngle(float angle, const Vector3 &axis);
static Quaternion CreateFromRotationMatrix(const Matrix4x4 &matrix); static Quaternion CreateFromRotationMatrix(const Matrix4x4 &matrix);
static void ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis); static void ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis);
static Quaternion Lerp(const Quaternion &a, const Quaternion &b, float interpolation); static Quaternion Lerp(const Quaternion &a, const Quaternion &b, float interpolation);
static Quaternion Slerp(const Quaternion &a, const Quaternion &b, float interpolation); static Quaternion Slerp(const Quaternion &a, const Quaternion &b, float interpolation);
float w; float w;
float x; float x;
float y; float y;
float z; float z;
}; };
Quaternion operator+(const Quaternion &left, const Quaternion &right); Quaternion operator+(const Quaternion &left, const Quaternion &right);
Quaternion &operator+=(Quaternion &left, const Quaternion &right); Quaternion &operator+=(Quaternion &left, const Quaternion &right);
Quaternion operator-(const Quaternion &left, const Quaternion &right); Quaternion operator-(const Quaternion &left, const Quaternion &right);
Quaternion &operator-=(Quaternion &left, const Quaternion &right); Quaternion &operator-=(Quaternion &left, const Quaternion &right);
Quaternion operator*(const Quaternion &left, float right); Quaternion operator*(const Quaternion &left, float right);
Quaternion &operator*=(Quaternion &left, float right); Quaternion &operator*=(Quaternion &left, float right);
Quaternion operator*(const Quaternion &left, const Quaternion &right); Quaternion operator*(const Quaternion &left, const Quaternion &right);
Quaternion &operator*=(Quaternion &left, const Quaternion &right); Quaternion &operator*=(Quaternion &left, const Quaternion &right);
Quaternion operator/(const Quaternion &left, float right); Quaternion operator/(const Quaternion &left, float right);
Quaternion &operator/=(Quaternion &left, float right); Quaternion &operator/=(Quaternion &left, float right);
Vector3 operator*(const Vector3 &left, const Quaternion &right); Vector3 operator*(const Vector3 &left, const Quaternion &right);
#define IDENTITY_QUATERNION Quaternion(1.0f, 0.0f, 0.0f, 0.0f) #define IDENTITY_QUATERNION Quaternion(1.0f, 0.0f, 0.0f, 0.0f)
inline void Quaternion::Set(float w, float x, float y, float z) inline void Quaternion::Set(float w, float x, float y, float z)
{ {
this->w = w; this->w = w;
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z; this->z = z;
} }
/** /**
* Converts a quaternion to a rotation matrix * Converts a quaternion to a rotation matrix
* @return Matrix4x4 * @return Matrix4x4
*/ */
inline Matrix4x4 Quaternion::ToMatrix() const inline Matrix4x4 Quaternion::ToMatrix() const
{ {
Matrix4x4 output; Matrix4x4 output;
output.m[_11] = 1.0f - (2.0f * ((y * y) + (z * z))); output.m[_11] = 1.0f - (2.0f * ((y * y) + (z * z)));
output.m[_21] = 2.0f * ((x * y) + (z * w)); output.m[_21] = 2.0f * ((x * y) + (z * w));
output.m[_31] = 2.0f * ((z * x) - (y * w)); output.m[_31] = 2.0f * ((z * x) - (y * w));
output.m[_41] = 0.0f; output.m[_41] = 0.0f;
output.m[_12] = 2.0f * ((x * y) - (z * w)); output.m[_12] = 2.0f * ((x * y) - (z * w));
output.m[_22] = 1.0f - (2.0f * ((z * z) + (x * x))); output.m[_22] = 1.0f - (2.0f * ((z * z) + (x * x)));
output.m[_32] = 2.0f * ((y * z) + (x * w)); output.m[_32] = 2.0f * ((y * z) + (x * w));
output.m[_42] = 0.0f; output.m[_42] = 0.0f;
output.m[_13] = 2.0f * ((z * x) + (y * w)); output.m[_13] = 2.0f * ((z * x) + (y * w));
output.m[_23] = 2.0f * ((y * z) - (x * w)); output.m[_23] = 2.0f * ((y * z) - (x * w));
output.m[_33] = 1.0f - (2.0f * ((y * y) + (x * x))); output.m[_33] = 1.0f - (2.0f * ((y * y) + (x * x)));
output.m[_43] = 0.0f; output.m[_43] = 0.0f;
output.m[_14] = 0.0f; output.m[_14] = 0.0f;
output.m[_24] = 0.0f; output.m[_24] = 0.0f;
output.m[_34] = 0.0f; output.m[_34] = 0.0f;
output.m[_44] = 1.0f; output.m[_44] = 1.0f;
return output; return output;
} }
/** /**
* @return Vector3 the vector component of the quaternion. * @return Vector3 the vector component of the quaternion.
*/ */
inline Vector3 Quaternion::GetVector() const inline Vector3 Quaternion::GetVector() const
{ {
return Vector3(x, y, z); return Vector3(x, y, z);
} }
/** /**
* Computes the cross product of two quaternions * Computes the cross product of two quaternions
* @param a first quaternion * @param a first quaternion
* @param b second quaternion * @param b second quaternion
* @return Quaternion the cross product * @return Quaternion the cross product
*/ */
inline Quaternion Quaternion::Cross(const Quaternion &a, const Quaternion &b) inline Quaternion Quaternion::Cross(const Quaternion &a, const Quaternion &b)
{ {
return a * b; return a * b;
} }
/** /**
* Computes the dot product of 2 quaternions. * Computes the dot product of 2 quaternions.
* @param a first quaternion * @param a first quaternion
* @param b second quaternion * @param b second quaternion
* @return float the dot product * @return float the dot product
*/ */
inline float Quaternion::Dot(const Quaternion &a, const Quaternion &b) 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); return (a.w * b.w) + (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
} }
/** /**
* Computes the length (magnitude) of a quaternion. * Computes the length (magnitude) of a quaternion.
* @param q quaternion to retrieve the length of * @param q quaternion to retrieve the length of
* @return float the length * @return float the length
*/ */
inline float Quaternion::Length(const Quaternion &q) 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)); 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 * Computes the squared length of a quaternion (the length minus the
* sqrt call). * sqrt call).
* @param q quaternion to retrieve the squared length of * @param q quaternion to retrieve the squared length of
* @return float the squared length * @return float the squared length
*/ */
inline float Quaternion::LengthSquared(const Quaternion &q) inline float Quaternion::LengthSquared(const Quaternion &q)
{ {
return (q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z); return (q.w * q.w) + (q.x * q.x) + (q.y * q.y) + (q.z * q.z);
} }
/** /**
* Normalizes a quaternion (only if necessary) * Normalizes a quaternion (only if necessary)
* @param q quaternion to be normalized * @param q quaternion to be normalized
* @return Quaternion normalized quaternion * @return Quaternion normalized quaternion
*/ */
inline Quaternion Quaternion::Normalize(const Quaternion &q) inline Quaternion Quaternion::Normalize(const Quaternion &q)
{ {
float inverseLength = 1.0f / Length(q); float inverseLength = 1.0f / Length(q);
return Quaternion( return Quaternion(
q.w * inverseLength, q.w * inverseLength,
q.x * inverseLength, q.x * inverseLength,
q.y * inverseLength, q.y * inverseLength,
q.z * inverseLength q.z * inverseLength
); );
} }
/** /**
* Computes the conjugate of a quaternion. If the quaternion * Computes the conjugate of a quaternion. If the quaternion
* is unit length, this also returns the inverse. * is unit length, this also returns the inverse.
* @param q quaternion to retrieve the conjugate of * @param q quaternion to retrieve the conjugate of
* @return Quaternion conjugate * @return Quaternion conjugate
*/ */
inline Quaternion Quaternion::Conjugate(const Quaternion &q) inline Quaternion Quaternion::Conjugate(const Quaternion &q)
{ {
return Quaternion(q.w, -q.x, -q.y, -q.z); return Quaternion(q.w, -q.x, -q.y, -q.z);
} }
/** /**
* Computes the inverse of a given quaternion * Computes the inverse of a given quaternion
* @param q quaternion to retrieve the inverse of * @param q quaternion to retrieve the inverse of
* @return Quaternion inverse of the quaternion * @return Quaternion inverse of the quaternion
*/ */
inline Quaternion Quaternion::Inverse(const Quaternion &q) inline Quaternion Quaternion::Inverse(const Quaternion &q)
{ {
float inverseSquaredLength = 1.0f / LengthSquared(q); float inverseSquaredLength = 1.0f / LengthSquared(q);
return Quaternion( return Quaternion(
q.w * inverseSquaredLength, q.w * inverseSquaredLength,
-q.x * inverseSquaredLength, -q.x * inverseSquaredLength,
-q.y * inverseSquaredLength, -q.y * inverseSquaredLength,
-q.z * inverseSquaredLength -q.z * inverseSquaredLength
); );
} }
/** /**
* Converts euler angles to a quaternion * Converts euler angles to a quaternion
* @param x x angle of rotation (specified in radians) * @param x x angle of rotation (specified in radians)
* @param y y angle of rotation (specified in radians) * @param y y angle of rotation (specified in radians)
* @param z z angle of rotation (specified in radians) * @param z z angle of rotation (specified in radians)
* @return Quaternion quaternion equivalent to the euler angle * @return Quaternion quaternion equivalent to the euler angle
* orientation * orientation
*/ */
inline Quaternion Quaternion::CreateFromEulerAngles(float x, float y, float z) 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 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 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)); Quaternion qz(cosf(z / 2.0f), 0.0f, 0.0f, sinf(z / 2.0f));
return Normalize(qz * qy * qx); return Normalize(qz * qy * qx);
} }
/** /**
* Converts an axis angle to a quaternion * Converts an axis angle to a quaternion
* @param angle the angle to rotate be (specified in radians) * @param angle the angle to rotate be (specified in radians)
* @param axis the axis being rotated about * @param axis the axis being rotated about
* @return Quaternion quaternion equivalent to the axis angle * @return Quaternion quaternion equivalent to the axis angle
* orientation * orientation
*/ */
inline Quaternion Quaternion::CreateFromAxisAngle(float angle, const Vector3 &axis) inline Quaternion Quaternion::CreateFromAxisAngle(float angle, const Vector3 &axis)
{ {
Quaternion result; Quaternion result;
float c = cosf(angle / 2.0f); float c = cosf(angle / 2.0f);
float s = sinf(angle / 2.0f); float s = sinf(angle / 2.0f);
result.w = c; result.w = c;
result.x = axis.x * s; result.x = axis.x * s;
result.y = axis.y * s; result.y = axis.y * s;
result.z = axis.z * s; result.z = axis.z * s;
return Normalize(result); return Normalize(result);
} }
/** /**
* Converts a rotation matrix to a quaternion * Converts a rotation matrix to a quaternion
* @param matrix matrix to be converted * @param matrix matrix to be converted
* @return Quaternion quaternion equivalent of the rotation * @return Quaternion quaternion equivalent of the rotation
* matrix * matrix
*/ */
inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix4x4 &matrix) inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix4x4 &matrix)
{ {
Quaternion result; Quaternion result;
float n = matrix.m[_11] + matrix.m[_22] + matrix.m[_33]; float n = matrix.m[_11] + matrix.m[_22] + matrix.m[_33];
if (n > 0.0f) if (n > 0.0f)
{ {
float a = sqrtf(n + 1.0f); float a = sqrtf(n + 1.0f);
result.w = a / 2.0f; result.w = a / 2.0f;
a = 0.5f / a; a = 0.5f / a;
result.x = (matrix.m[_32] - matrix.m[_23]) * a; result.x = (matrix.m[_32] - matrix.m[_23]) * a;
result.y = (matrix.m[_13] - matrix.m[_31]) * a; result.y = (matrix.m[_13] - matrix.m[_31]) * a;
result.z = (matrix.m[_21] - matrix.m[_12]) * a; result.z = (matrix.m[_21] - matrix.m[_12]) * a;
} }
else if ((matrix.m[_11] >= matrix.m[_22]) && (matrix.m[_11] >= matrix.m[_33])) 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 a = sqrtf(1.0f + matrix.m[_11] - matrix.m[_22] - matrix.m[_33]);
float b = 0.5f / a; float b = 0.5f / a;
result.x = 0.5f * a; result.x = 0.5f * a;
result.y = (matrix.m[_21] + matrix.m[_12]) * b; result.y = (matrix.m[_21] + matrix.m[_12]) * b;
result.z = (matrix.m[_31] + matrix.m[_13]) * b; result.z = (matrix.m[_31] + matrix.m[_13]) * b;
result.w = (matrix.m[_32] - matrix.m[_23]) * b; result.w = (matrix.m[_32] - matrix.m[_23]) * b;
} }
else if (matrix.m[_22] > matrix.m[_33]) else if (matrix.m[_22] > matrix.m[_33])
{ {
float a = sqrtf(1.0f + matrix.m[_22] - matrix.m[_11] - matrix.m[_33]); float a = sqrtf(1.0f + matrix.m[_22] - matrix.m[_11] - matrix.m[_33]);
float b = 0.5f / a; float b = 0.5f / a;
result.x = (matrix.m[_12] + matrix.m[_21]) * b; result.x = (matrix.m[_12] + matrix.m[_21]) * b;
result.y = 0.5f * a; result.y = 0.5f * a;
result.z = (matrix.m[_23] + matrix.m[_32]) * b; result.z = (matrix.m[_23] + matrix.m[_32]) * b;
result.w = (matrix.m[_13] - matrix.m[_31]) * b; result.w = (matrix.m[_13] - matrix.m[_31]) * b;
} }
else else
{ {
float a = sqrtf(1.0f + matrix.m[_33] - matrix.m[_11] - matrix.m[_22]); float a = sqrtf(1.0f + matrix.m[_33] - matrix.m[_11] - matrix.m[_22]);
float b = 0.5f / a; float b = 0.5f / a;
result.x = (matrix.m[_13] + matrix.m[_31]) * b; result.x = (matrix.m[_13] + matrix.m[_31]) * b;
result.y = (matrix.m[_23] + matrix.m[_32]) * b; result.y = (matrix.m[_23] + matrix.m[_32]) * b;
result.z = 0.5f * a; result.z = 0.5f * a;
result.w = (matrix.m[_21] - matrix.m[_12]) * b; result.w = (matrix.m[_21] - matrix.m[_12]) * b;
} }
return Normalize(result); return Normalize(result);
} }
/** /**
* Converts a quaternion to an axis-angle representation. * Converts a quaternion to an axis-angle representation.
* @param q the normalized quaternion to convert * @param q the normalized quaternion to convert
* @param angle the angle (in radians) * @param angle the angle (in radians)
* @param axis a vector that will contain the axis * @param axis a vector that will contain the axis
*/ */
inline void Quaternion::ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis) inline void Quaternion::ExtractAxisAngle(const Quaternion &q, float *angle, Vector3 *axis)
{ {
*angle = 2.0f * acosf(q.w); *angle = 2.0f * acosf(q.w);
float n = sqrtf(1.0f - (q.w * q.w)); float n = sqrtf(1.0f - (q.w * q.w));
if (n > 0.0001f) if (n > 0.0001f)
*axis = q.GetVector() / n; *axis = q.GetVector() / n;
else else
*axis = X_AXIS; *axis = X_AXIS;
} }
/** /**
* Linearly interpolates between two quaternions. * Linearly interpolates between two quaternions.
* @param a the first quaternion * @param a the first quaternion
* @param b the second quaternion * @param b the second quaternion
* @param interpolation the amount to interpolate * @param interpolation the amount to interpolate
* @return Quaternion the interpolated quaternion * @return Quaternion the interpolated quaternion
*/ */
inline Quaternion Quaternion::Lerp(const Quaternion &a, const Quaternion &b, float interpolation) inline Quaternion Quaternion::Lerp(const Quaternion &a, const Quaternion &b, float interpolation)
{ {
return (a * (1.0f - interpolation)) + (b * interpolation); return (a * (1.0f - interpolation)) + (b * interpolation);
} }
/** /**
* Interpolates between two quaternions using spherical * Interpolates between two quaternions using spherical
* interpolation. * interpolation.
* @param a the first quaternion * @param a the first quaternion
* @param b the second quaternion * @param b the second quaternion
* @param interpolation the amount to interpolate * @param interpolation the amount to interpolate
* @return Quaternion the interpolated quaternion * @return Quaternion the interpolated quaternion
*/ */
inline Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b, float interpolation) inline Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b, float interpolation)
{ {
if (LengthSquared(a) == 0.0f) if (LengthSquared(a) == 0.0f)
{ {
if (LengthSquared(b) == 0.0f) if (LengthSquared(b) == 0.0f)
return IDENTITY_QUATERNION; return IDENTITY_QUATERNION;
else else
return b; return b;
} }
else if (LengthSquared(b) == 0.0f) else if (LengthSquared(b) == 0.0f)
return a; return a;
Quaternion q1 = a; Quaternion q1 = a;
Quaternion q2 = b; Quaternion q2 = b;
float cosHalfAngle = q1.w * q2.w + Vector3::Dot(q1.GetVector(), q2.GetVector()); float cosHalfAngle = q1.w * q2.w + Vector3::Dot(q1.GetVector(), q2.GetVector());
if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f)
return q1; return q1;
else if (cosHalfAngle < 0.0f) else if (cosHalfAngle < 0.0f)
{ {
q2.x = -q2.x; q2.x = -q2.x;
q2.y = -q2.y; q2.y = -q2.y;
q2.z = -q2.z; q2.z = -q2.z;
q2.w = -q2.w; q2.w = -q2.w;
cosHalfAngle = -cosHalfAngle; cosHalfAngle = -cosHalfAngle;
} }
float blendA; float blendA;
float blendB; float blendB;
if (cosHalfAngle < 0.99f) if (cosHalfAngle < 0.99f)
{ {
float halfAngle = acosf(cosHalfAngle); float halfAngle = acosf(cosHalfAngle);
float sinHalfAngle = sinf(halfAngle); float sinHalfAngle = sinf(halfAngle);
float oneOverSinHalfAngle = 1.0f / sinHalfAngle; float oneOverSinHalfAngle = 1.0f / sinHalfAngle;
blendA = sinf(halfAngle * (1.0f - interpolation)) * oneOverSinHalfAngle; blendA = sinf(halfAngle * (1.0f - interpolation)) * oneOverSinHalfAngle;
blendB = sinf(halfAngle * interpolation) * oneOverSinHalfAngle; blendB = sinf(halfAngle * interpolation) * oneOverSinHalfAngle;
} }
else else
{ {
blendA = 1.0f - interpolation; blendA = 1.0f - interpolation;
blendB = interpolation; blendB = interpolation;
} }
Quaternion result(q1.w * blendA + q2.w * blendB, q1.GetVector() * blendA + q2.GetVector() * blendB); Quaternion result(q1.w * blendA + q2.w * blendB, q1.GetVector() * blendA + q2.GetVector() * blendB);
if (LengthSquared(result) > 0.0f) if (LengthSquared(result) > 0.0f)
return Normalize(result); return Normalize(result);
else else
return IDENTITY_QUATERNION; return IDENTITY_QUATERNION;
} }
inline Quaternion operator+(const Quaternion &left, const Quaternion &right) inline Quaternion operator+(const Quaternion &left, const Quaternion &right)
{ {
return Quaternion( return Quaternion(
left.w + right.w, left.w + right.w,
left.x + right.x, left.x + right.x,
left.y + right.y, left.y + right.y,
left.z + right.z left.z + right.z
); );
} }
inline Quaternion &operator+=(Quaternion &left, const Quaternion &right) inline Quaternion &operator+=(Quaternion &left, const Quaternion &right)
{ {
left = left + right; left = left + right;
return left; return left;
} }
inline Quaternion operator-(const Quaternion &left, const Quaternion &right) inline Quaternion operator-(const Quaternion &left, const Quaternion &right)
{ {
return Quaternion( return Quaternion(
left.w - right.w, left.w - right.w,
left.x - right.x, left.x - right.x,
left.y - right.y, left.y - right.y,
left.z - right.z left.z - right.z
); );
} }
inline Quaternion &operator-=(Quaternion &left, const Quaternion &right) inline Quaternion &operator-=(Quaternion &left, const Quaternion &right)
{ {
left = left - right; left = left - right;
return left; return left;
} }
inline Quaternion operator*(const Quaternion &left, float right) inline Quaternion operator*(const Quaternion &left, float right)
{ {
return Quaternion( return Quaternion(
left.w * right, left.w * right,
left.x * right, left.x * right,
left.y * right, left.y * right,
left.z * right left.z * right
); );
} }
inline Quaternion &operator*=(Quaternion &left, float right) inline Quaternion &operator*=(Quaternion &left, float right)
{ {
left = left * right; left = left * right;
return left; return left;
} }
inline Quaternion operator*(const Quaternion &left, const Quaternion &right) inline Quaternion operator*(const Quaternion &left, const Quaternion &right)
{ {
return Quaternion( return Quaternion(
(left.w * right.w) - (left.x * right.x) - (left.y * right.y) - (left.z * right.z), (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.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.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) (left.w * right.z) + (left.z * right.w) + (left.x * right.y) - (left.y * right.x)
); );
} }
inline Quaternion &operator*=(Quaternion &left, const Quaternion &right) inline Quaternion &operator*=(Quaternion &left, const Quaternion &right)
{ {
left = left * right; left = left * right;
return left; return left;
} }
inline Quaternion operator/(const Quaternion &left, float right) inline Quaternion operator/(const Quaternion &left, float right)
{ {
return Quaternion( return Quaternion(
left.w / right, left.w / right,
left.x / right, left.x / right,
left.y / right, left.y / right,
left.z / right left.z / right
); );
} }
inline Quaternion &operator/=(Quaternion &left, float right) inline Quaternion &operator/=(Quaternion &left, float right)
{ {
left = left / right; left = left / right;
return left; return left;
} }
inline Vector3 operator*(const Vector3 &left, const Quaternion &right) inline Vector3 operator*(const Vector3 &left, const Quaternion &right)
{ {
return Vector3( 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 * ((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.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)))) ((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 #endif

View file

@ -1,15 +1,15 @@
#ifndef __GEOMETRY_TRIANGLE_H_INCLUDED__ #ifndef __GEOMETRY_TRIANGLE_H_INCLUDED__
#define __GEOMETRY_TRIANGLE_H_INCLUDED__ #define __GEOMETRY_TRIANGLE_H_INCLUDED__
#include "../common.h" #include "../common.h"
class Triangle class Triangle
{ {
public: public:
uint32_t vertices[3]; uint32_t vertices[3];
uint32_t normals[3]; uint32_t normals[3];
uint32_t texCoords[3]; uint32_t texCoords[3];
uint32_t materialIndex; uint32_t materialIndex;
}; };
#endif #endif

View file

@ -1,236 +1,236 @@
#ifndef __GEOMETRY_VECTOR2_H_INCLUDED__ #ifndef __GEOMETRY_VECTOR2_H_INCLUDED__
#define __GEOMETRY_VECTOR2_H_INCLUDED__ #define __GEOMETRY_VECTOR2_H_INCLUDED__
#include <math.h> #include <math.h>
/** /**
* Represents a 2D vector and provides common methods for vector math. * Represents a 2D vector and provides common methods for vector math.
* <p>Referenced/based on code from:</p> * <p>Referenced/based on code from:</p>
* <ul> * <ul>
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li> * <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
* <li>http://www.dhpoware.com/source/mathlib.html</li> * <li>http://www.dhpoware.com/source/mathlib.html</li>
* </ul> * </ul>
* @author Gered * @author Gered
*/ */
class Vector2 class Vector2
{ {
public: public:
Vector2() {} Vector2() {}
Vector2(float x, float y) Vector2(float x, float y)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
} }
Vector2(const float *v) Vector2(const float *v)
{ {
x = v[0]; x = v[0];
y = v[1]; y = v[1];
} }
~Vector2() {} ~Vector2() {}
void Set(float x, float y); void Set(float x, float y);
static float Distance(const Vector2 &a, const Vector2 &b); static float Distance(const Vector2 &a, const Vector2 &b);
static float Dot(const Vector2 &a, const Vector2 &b); static float Dot(const Vector2 &a, const Vector2 &b);
static float Length(const Vector2 &v); static float Length(const Vector2 &v);
static float LengthSquared(const Vector2 &v); static float LengthSquared(const Vector2 &v);
static Vector2 Normalize(const Vector2 &v); static Vector2 Normalize(const Vector2 &v);
static Vector2 SetLength(const Vector2 &v, float length); static Vector2 SetLength(const Vector2 &v, float length);
float x; float x;
float y; float y;
}; };
bool operator==(const Vector2 &left, const Vector2 &right); bool operator==(const Vector2 &left, const Vector2 &right);
Vector2 operator-(const Vector2 &left); Vector2 operator-(const Vector2 &left);
Vector2 operator+(const Vector2 &left, const Vector2 &right); Vector2 operator+(const Vector2 &left, const Vector2 &right);
Vector2 &operator+=(Vector2 &left, const Vector2 &right); Vector2 &operator+=(Vector2 &left, const Vector2 &right);
Vector2 operator-(const Vector2 &left, const Vector2 &right); Vector2 operator-(const Vector2 &left, const Vector2 &right);
Vector2 &operator-=(Vector2 &left, const Vector2 &right); Vector2 &operator-=(Vector2 &left, const Vector2 &right);
Vector2 operator*(const Vector2 &left, float right); Vector2 operator*(const Vector2 &left, float right);
Vector2 &operator*=(Vector2 &left, float right); Vector2 &operator*=(Vector2 &left, float right);
Vector2 operator/(const Vector2 &left, float right); Vector2 operator/(const Vector2 &left, float right);
Vector2 &operator/=(Vector2 &left, float right); Vector2 &operator/=(Vector2 &left, float right);
Vector2 operator*(const Vector2 &left, const Vector2 &right); Vector2 operator*(const Vector2 &left, const Vector2 &right);
Vector2 &operator*=(Vector2 &left, const Vector2 &right); Vector2 &operator*=(Vector2 &left, const Vector2 &right);
Vector2 operator/(const Vector2 &left, const Vector2 &right); Vector2 operator/(const Vector2 &left, const Vector2 &right);
Vector2 &operator/=(Vector2 &left, const Vector2 &right); Vector2 &operator/=(Vector2 &left, const Vector2 &right);
inline void Vector2::Set(float x, float y) inline void Vector2::Set(float x, float y)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
} }
/** /**
* Calculates the distance between two points. * Calculates the distance between two points.
* @param a the first point * @param a the first point
* @param b the second point * @param b the second point
* @return the distance between both points * @return the distance between both points
*/ */
inline float Vector2::Distance(const Vector2 &a, const Vector2 &b) inline float Vector2::Distance(const Vector2 &a, const Vector2 &b)
{ {
return sqrtf( return sqrtf(
((b.x - a.x) * (b.x - a.x)) + ((b.x - a.x) * (b.x - a.x)) +
((b.y - a.y) * (b.y - a.y)) ((b.y - a.y) * (b.y - a.y))
); );
} }
/** /**
* Computes the dot product of 2 vectors. * Computes the dot product of 2 vectors.
* @param a first vector * @param a first vector
* @param b second vector * @param b second vector
* @return the dot product * @return the dot product
*/ */
inline float Vector2::Dot(const Vector2 &a, const Vector2 &b) inline float Vector2::Dot(const Vector2 &a, const Vector2 &b)
{ {
return return
(a.x * b.y) + (a.x * b.y) +
(a.y * b.y); (a.y * b.y);
} }
/** /**
* Returns the length (magnitude) of a vector. * Returns the length (magnitude) of a vector.
* @param v vector to calculate the length of * @param v vector to calculate the length of
* @return the vector length * @return the vector length
*/ */
inline float Vector2::Length(const Vector2 &v) inline float Vector2::Length(const Vector2 &v)
{ {
return sqrtf( return sqrtf(
(v.x * v.x) + (v.x * v.x) +
(v.y * v.y) (v.y * v.y)
); );
} }
/** /**
* Returns the squared length of a vector (the magnitude minus the sqrt * Returns the squared length of a vector (the magnitude minus the sqrt
* call). * call).
* @param v vector to calculate the squared length of * @param v vector to calculate the squared length of
* @return squared length of the vector * @return squared length of the vector
*/ */
inline float Vector2::LengthSquared(const Vector2 &v) inline float Vector2::LengthSquared(const Vector2 &v)
{ {
return return
(v.x * v.x) + (v.x * v.x) +
(v.y * v.y); (v.y * v.y);
} }
/** /**
* Normalizes a vector. * Normalizes a vector.
* @param v vector to normalize * @param v vector to normalize
* @return the normalized vector * @return the normalized vector
*/ */
inline Vector2 Vector2::Normalize(const Vector2 &v) inline Vector2 Vector2::Normalize(const Vector2 &v)
{ {
float inverseLength = 1.0f / Length(v); float inverseLength = 1.0f / Length(v);
return Vector2( return Vector2(
v.x * inverseLength, v.x * inverseLength,
v.y * inverseLength v.y * inverseLength
); );
} }
/** /**
* Adjusts a vector so that it's length is equal to the given length. * Adjusts a vector so that it's length is equal to the given length.
* @param v the original vector to be adjusted * @param v the original vector to be adjusted
* @param length desired vector length (magnitude) * @param length desired vector length (magnitude)
* @return the resulting vector after it's length has been converted to the * @return the resulting vector after it's length has been converted to the
* desired amount * desired amount
*/ */
inline Vector2 Vector2::SetLength(const Vector2 &v, float length) inline Vector2 Vector2::SetLength(const Vector2 &v, float length)
{ {
return v * (length / Length(v)); return v * (length / Length(v));
} }
inline bool operator==(const Vector2 &left, const Vector2 &right) inline bool operator==(const Vector2 &left, const Vector2 &right)
{ {
return (left.x == right.x && left.y == right.y); return (left.x == right.x && left.y == right.y);
} }
inline Vector2 operator-(const Vector2 &left) inline Vector2 operator-(const Vector2 &left)
{ {
return Vector2(-left.x, -left.y); return Vector2(-left.x, -left.y);
} }
inline Vector2 operator+(const Vector2 &left, const Vector2 &right) inline Vector2 operator+(const Vector2 &left, const Vector2 &right)
{ {
return Vector2(left.x + right.x, left.y + right.y); return Vector2(left.x + right.x, left.y + right.y);
} }
inline Vector2 &operator+=(Vector2 &left, const Vector2 &right) inline Vector2 &operator+=(Vector2 &left, const Vector2 &right)
{ {
left.x += right.x; left.x += right.x;
left.y += right.y; left.y += right.y;
return left; return left;
} }
inline Vector2 operator-(const Vector2 &left, const Vector2 &right) inline Vector2 operator-(const Vector2 &left, const Vector2 &right)
{ {
return Vector2(left.x - right.x, left.y - right.y); return Vector2(left.x - right.x, left.y - right.y);
} }
inline Vector2 &operator-=(Vector2 &left, const Vector2 &right) inline Vector2 &operator-=(Vector2 &left, const Vector2 &right)
{ {
left.x -= right.x; left.x -= right.x;
left.y -= right.y; left.y -= right.y;
return left; return left;
} }
inline Vector2 operator*(const Vector2 &left, float right) inline Vector2 operator*(const Vector2 &left, float right)
{ {
return Vector2(left.x * right, left.y * right); return Vector2(left.x * right, left.y * right);
} }
inline Vector2 &operator*=(Vector2 &left, float right) inline Vector2 &operator*=(Vector2 &left, float right)
{ {
left.x *= right; left.x *= right;
left.y *= right; left.y *= right;
return left; return left;
} }
inline Vector2 operator/(const Vector2 &left, float right) inline Vector2 operator/(const Vector2 &left, float right)
{ {
return Vector2(left.x / right, left.y / right); return Vector2(left.x / right, left.y / right);
} }
inline Vector2 &operator/=(Vector2 &left, float right) inline Vector2 &operator/=(Vector2 &left, float right)
{ {
left.x /= right; left.x /= right;
left.y /= right; left.y /= right;
return left; return left;
} }
inline Vector2 operator*(const Vector2 &left, const Vector2 &right) inline Vector2 operator*(const Vector2 &left, const Vector2 &right)
{ {
return Vector2(left.x * right.x, left.y * right.y); return Vector2(left.x * right.x, left.y * right.y);
} }
inline Vector2 &operator*=(Vector2 &left, const Vector2 &right) inline Vector2 &operator*=(Vector2 &left, const Vector2 &right)
{ {
left.x *= right.x; left.x *= right.x;
left.y *= right.y; left.y *= right.y;
return left; return left;
} }
inline Vector2 operator/(const Vector2 &left, const Vector2 &right) inline Vector2 operator/(const Vector2 &left, const Vector2 &right)
{ {
return Vector2(left.x / right.x, left.y / right.y); return Vector2(left.x / right.x, left.y / right.y);
} }
inline Vector2 &operator/=(Vector2 &left, const Vector2 &right) inline Vector2 &operator/=(Vector2 &left, const Vector2 &right)
{ {
left.x /= right.x; left.x /= right.x;
left.y /= right.y; left.y /= right.y;
return left; return left;
} }
#endif #endif

View file

@ -1,341 +1,341 @@
#ifndef __GEOMETRY_VECTOR3_H_INCLUDED__ #ifndef __GEOMETRY_VECTOR3_H_INCLUDED__
#define __GEOMETRY_VECTOR3_H_INCLUDED__ #define __GEOMETRY_VECTOR3_H_INCLUDED__
#include <math.h> #include <math.h>
#include "../common.h" #include "../common.h"
/** /**
* <p>Represents a 3D vector and provides common methods for vector math.</p> * <p>Represents a 3D vector and provides common methods for vector math.</p>
* <p>Referenced/based on code from:</p> * <p>Referenced/based on code from:</p>
* <ul> * <ul>
* <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li> * <li>3D Math Primer for Graphics and Game Development (Dunn & Parberry, 2002)</li>
* <li>http://www.dhpoware.com/source/mathlib.html</li> * <li>http://www.dhpoware.com/source/mathlib.html</li>
* <li>http://www.peroxide.dk/papers/collision/collision.pdf</li> * <li>http://www.peroxide.dk/papers/collision/collision.pdf</li>
* </ul> * </ul>
* @author Gered * @author Gered
*/ */
class Vector3 class Vector3
{ {
public: public:
Vector3() {} Vector3() {}
Vector3(float x, float y, float z) Vector3(float x, float y, float z)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z; this->z = z;
} }
Vector3(const float *v) Vector3(const float *v)
{ {
x = v[0]; x = v[0];
y = v[1]; y = v[1];
z = v[2]; z = v[2];
} }
~Vector3() {} ~Vector3() {}
void Set(float x, float y, float z); void Set(float x, float y, float z);
static Vector3 Cross(const Vector3 &a, const Vector3 &b); static Vector3 Cross(const Vector3 &a, const Vector3 &b);
static float Distance(const Vector3 &a, const Vector3 &b); static float Distance(const Vector3 &a, const Vector3 &b);
static float Dot(const Vector3 &a, const Vector3 &b); static float Dot(const Vector3 &a, const Vector3 &b);
static BOOL IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c); static BOOL IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c);
static float Length(const Vector3 &v); static float Length(const Vector3 &v);
static float LengthSquared(const Vector3 &v); static float LengthSquared(const Vector3 &v);
static Vector3 Normalize(const Vector3 &v); static Vector3 Normalize(const Vector3 &v);
static Vector3 SetLength(const Vector3 &v, float length); static Vector3 SetLength(const Vector3 &v, float length);
static Vector3 SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c); static Vector3 SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c);
static Vector3 Lerp(const Vector3 &a, const Vector3 &b, float interpolation); static Vector3 Lerp(const Vector3 &a, const Vector3 &b, float interpolation);
float x; float x;
float y; float y;
float z; float z;
}; };
bool operator==(const Vector3 &left, const Vector3 &right); bool operator==(const Vector3 &left, const Vector3 &right);
Vector3 operator-(const Vector3 &left); Vector3 operator-(const Vector3 &left);
Vector3 operator+(const Vector3 &left, const Vector3 &right); Vector3 operator+(const Vector3 &left, const Vector3 &right);
Vector3 &operator+=(Vector3 &left, const Vector3 &right); Vector3 &operator+=(Vector3 &left, const Vector3 &right);
Vector3 operator-(const Vector3 &left, const Vector3 &right); Vector3 operator-(const Vector3 &left, const Vector3 &right);
Vector3 &operator-=(Vector3 &left, const Vector3 &right); Vector3 &operator-=(Vector3 &left, const Vector3 &right);
Vector3 operator*(const Vector3 &left, float right); Vector3 operator*(const Vector3 &left, float right);
Vector3 &operator*=(Vector3 &left, float right); Vector3 &operator*=(Vector3 &left, float right);
Vector3 operator/(const Vector3 &left, float right); Vector3 operator/(const Vector3 &left, float right);
Vector3 &operator/=(Vector3 &left, float right); Vector3 &operator/=(Vector3 &left, float right);
Vector3 operator*(const Vector3 &left, const Vector3 &right); Vector3 operator*(const Vector3 &left, const Vector3 &right);
Vector3 &operator*=(Vector3 &left, const Vector3 &right); Vector3 &operator*=(Vector3 &left, const Vector3 &right);
Vector3 operator/(const Vector3 &left, const Vector3 &right); Vector3 operator/(const Vector3 &left, const Vector3 &right);
Vector3 &operator/=(Vector3 &left, const Vector3 &right); Vector3 &operator/=(Vector3 &left, const Vector3 &right);
#define ZERO_VECTOR Vector3(0.0f, 0.0f, 0.0f) #define ZERO_VECTOR Vector3(0.0f, 0.0f, 0.0f)
#define X_AXIS Vector3(1.0f, 0.0f, 0.0f) #define X_AXIS Vector3(1.0f, 0.0f, 0.0f)
#define Y_AXIS Vector3(0.0f, 1.0f, 0.0f) #define Y_AXIS Vector3(0.0f, 1.0f, 0.0f)
#define Z_AXIS Vector3(0.0f, 0.0f, 1.0f) #define Z_AXIS Vector3(0.0f, 0.0f, 1.0f)
#define UP Vector3(0.0f, 1.0f, 0.0f) #define UP Vector3(0.0f, 1.0f, 0.0f)
#define DOWN Vector3(0.0f, -1.0f, 0.0f) #define DOWN Vector3(0.0f, -1.0f, 0.0f)
#define FORWARD Vector3(0.0f, 0.0f, -1.0f) #define FORWARD Vector3(0.0f, 0.0f, -1.0f)
#define BACKWARD Vector3(0.0f, 0.0f, 1.0f) #define BACKWARD Vector3(0.0f, 0.0f, 1.0f)
#define LEFT Vector3(-1.0f, 0.0f, 0.0f) #define LEFT Vector3(-1.0f, 0.0f, 0.0f)
#define RIGHT Vector3(1.0f, 0.0f, 0.0f) #define RIGHT Vector3(1.0f, 0.0f, 0.0f)
inline void Vector3::Set(float x, float y, float z) inline void Vector3::Set(float x, float y, float z)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z; this->z = z;
} }
/** /**
* Computes the cross product of 2 vectors. * Computes the cross product of 2 vectors.
* @param a first vector * @param a first vector
* @param b second vector * @param b second vector
* @return the cross product * @return the cross product
*/ */
inline Vector3 Vector3::Cross(const Vector3 &a, const Vector3 &b) inline Vector3 Vector3::Cross(const Vector3 &a, const Vector3 &b)
{ {
return Vector3( return Vector3(
(a.y * b.z) - (a.z * b.y), (a.y * b.z) - (a.z * b.y),
(a.z * b.x) - (a.x * b.z), (a.z * b.x) - (a.x * b.z),
(a.x * b.y) - (a.y * b.x) (a.x * b.y) - (a.y * b.x)
); );
} }
/** /**
* Calculates the distance between two points. * Calculates the distance between two points.
* @param a the first point * @param a the first point
* @param b the second point * @param b the second point
* @return the distance between both points * @return the distance between both points
*/ */
inline float Vector3::Distance(const Vector3 &a, const Vector3 &b) inline float Vector3::Distance(const Vector3 &a, const Vector3 &b)
{ {
return sqrtf( return sqrtf(
((b.x - a.x) * (b.x - a.x)) + ((b.x - a.x) * (b.x - a.x)) +
((b.y - a.y) * (b.y - a.y)) + ((b.y - a.y) * (b.y - a.y)) +
((b.z - a.z) * (b.z - a.z)) ((b.z - a.z) * (b.z - a.z))
); );
} }
/** /**
* Computes the dot product of 2 vectors. * Computes the dot product of 2 vectors.
* @param a first vector * @param a first vector
* @param b second vector * @param b second vector
* @return the dot product * @return the dot product
*/ */
inline float Vector3::Dot(const Vector3 &a, const Vector3 &b) inline float Vector3::Dot(const Vector3 &a, const Vector3 &b)
{ {
return return
(a.x * b.x) + (a.x * b.x) +
(a.y * b.y) + (a.y * b.y) +
(a.z * b.z); (a.z * b.z);
} }
/** /**
* Checks if a given point lies inside a triangle or not. * Checks if a given point lies inside a triangle or not.
* @param point point to test * @param point point to test
* @param a first vector of the triangle * @param a first vector of the triangle
* @param b second vector of the triangle * @param b second vector of the triangle
* @param c third vector of the triangle * @param c third vector of the triangle
* @return TRUE if the point lies inside the triangle * @return TRUE if the point lies inside the triangle
*/ */
inline BOOL Vector3::IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c) inline BOOL Vector3::IsPointInTriangle(const Vector3 &point, const Vector3 &a, const Vector3 &b, const Vector3 &c)
{ {
Vector3 v0 = c - a; Vector3 v0 = c - a;
Vector3 v1 = b - a; Vector3 v1 = b - a;
Vector3 v2 = point - a; Vector3 v2 = point - a;
float dot00 = (v0.x * v0.x) + (v0.y * v0.y) + (v0.z * v0.z); float dot00 = (v0.x * v0.x) + (v0.y * v0.y) + (v0.z * v0.z);
float dot01 = (v0.x * v1.x) + (v0.y * v1.y) + (v0.z * v1.z); float dot01 = (v0.x * v1.x) + (v0.y * v1.y) + (v0.z * v1.z);
float dot02 = (v0.x * v2.x) + (v0.y * v2.y) + (v0.z * v2.z); float dot02 = (v0.x * v2.x) + (v0.y * v2.y) + (v0.z * v2.z);
float dot11 = (v1.x * v1.x) + (v1.y * v1.y) + (v1.z * v1.z); float dot11 = (v1.x * v1.x) + (v1.y * v1.y) + (v1.z * v1.z);
float dot12 = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z); float dot12 = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
float denom = dot00 * dot11 - dot01 * dot01; float denom = dot00 * dot11 - dot01 * dot01;
if (denom == 0) if (denom == 0)
return FALSE; return FALSE;
float u = (dot11 * dot02 - dot01 * dot12) / denom; float u = (dot11 * dot02 - dot01 * dot12) / denom;
float v = (dot00 * dot12 - dot01 * dot02) / denom; float v = (dot00 * dot12 - dot01 * dot02) / denom;
if (u >= 0 && v >= 0 && u + v <= 1) if (u >= 0 && v >= 0 && u + v <= 1)
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
} }
/** /**
* Returns the length (magnitude) of a vector. * Returns the length (magnitude) of a vector.
* @param v vector to calculate the length of * @param v vector to calculate the length of
* @return the vector length * @return the vector length
*/ */
inline float Vector3::Length(const Vector3 &v) inline float Vector3::Length(const Vector3 &v)
{ {
return sqrtf( return sqrtf(
(v.x * v.x) + (v.x * v.x) +
(v.y * v.y) + (v.y * v.y) +
(v.z * v.z) (v.z * v.z)
); );
} }
/** /**
* Returns the squared length of a vector (the magnitude minus the sqrt * Returns the squared length of a vector (the magnitude minus the sqrt
* call). * call).
* @param v vector to calculate the squared length of * @param v vector to calculate the squared length of
* @return squared length of the vector * @return squared length of the vector
*/ */
inline float Vector3::LengthSquared(const Vector3 &v) inline float Vector3::LengthSquared(const Vector3 &v)
{ {
return return
(v.x * v.x) + (v.x * v.x) +
(v.y * v.y) + (v.y * v.y) +
(v.z * v.z); (v.z * v.z);
} }
/** /**
* Normalizes a vector. * Normalizes a vector.
* @param v vector to normalize * @param v vector to normalize
* @return the normalized vector * @return the normalized vector
*/ */
inline Vector3 Vector3::Normalize(const Vector3 &v) inline Vector3 Vector3::Normalize(const Vector3 &v)
{ {
float inverseLength = 1.0f / Length(v); float inverseLength = 1.0f / Length(v);
return Vector3( return Vector3(
v.x * inverseLength, v.x * inverseLength,
v.y * inverseLength, v.y * inverseLength,
v.z * inverseLength v.z * inverseLength
); );
} }
/** /**
* Adjusts a vector so that it's length is equal to the given * Adjusts a vector so that it's length is equal to the given
* length. * length.
* @param v the original vector to be adjusted * @param v the original vector to be adjusted
* @param length desired vector length (magnitude) * @param length desired vector length (magnitude)
* @return the resulting vector after it's length has been converted to the * @return the resulting vector after it's length has been converted to the
* desired amount * desired amount
*/ */
inline Vector3 Vector3::SetLength(const Vector3 &v, float length) inline Vector3 Vector3::SetLength(const Vector3 &v, float length)
{ {
return v * (length / Length(v)); return v * (length / Length(v));
} }
/** /**
* Calculates a normal vector for the given 3 vectors making up a * Calculates a normal vector for the given 3 vectors making up a
* triangle (counter clockwise order). * triangle (counter clockwise order).
* @param a first vertex * @param a first vertex
* @param b second vertex * @param b second vertex
* @param c third vertex * @param c third vertex
* @return normal vector for the triangle * @return normal vector for the triangle
*/ */
inline Vector3 Vector3::SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c) inline Vector3 Vector3::SurfaceNormal(const Vector3 &a, const Vector3 &b, const Vector3 &c)
{ {
return Normalize(Cross((b - a), (c - a))); return Normalize(Cross((b - a), (c - a)));
} }
/** /**
* Linearly interpolates between two vectors. * Linearly interpolates between two vectors.
* @param a the first vector * @param a the first vector
* @param b the second vector * @param b the second vector
* @param interpolation the amount to interpolate * @param interpolation the amount to interpolate
* @return Vector3 the interpolated vector * @return Vector3 the interpolated vector
*/ */
inline Vector3 Vector3::Lerp(const Vector3 &a, const Vector3 &b, float interpolation) inline Vector3 Vector3::Lerp(const Vector3 &a, const Vector3 &b, float interpolation)
{ {
return a + (b - a) * interpolation; return a + (b - a) * interpolation;
} }
inline bool operator==(const Vector3 &left, const Vector3 &right) inline bool operator==(const Vector3 &left, const Vector3 &right)
{ {
return (left.x == right.x && left.y == right.y && left.z == right.z); return (left.x == right.x && left.y == right.y && left.z == right.z);
} }
inline Vector3 operator-(const Vector3 &left) inline Vector3 operator-(const Vector3 &left)
{ {
return Vector3(-left.x, -left.y, -left.z); return Vector3(-left.x, -left.y, -left.z);
} }
inline Vector3 operator+(const Vector3 &left, const Vector3 &right) inline Vector3 operator+(const Vector3 &left, const Vector3 &right)
{ {
return Vector3(left.x + right.x, left.y + right.y, left.z + right.z); return Vector3(left.x + right.x, left.y + right.y, left.z + right.z);
} }
inline Vector3 &operator+=(Vector3 &left, const Vector3 &right) inline Vector3 &operator+=(Vector3 &left, const Vector3 &right)
{ {
left.x += right.x; left.x += right.x;
left.y += right.y; left.y += right.y;
left.z += right.z; left.z += right.z;
return left; return left;
} }
inline Vector3 operator-(const Vector3 &left, const Vector3 &right) inline Vector3 operator-(const Vector3 &left, const Vector3 &right)
{ {
return Vector3(left.x - right.x, left.y - right.y, left.z - right.z); return Vector3(left.x - right.x, left.y - right.y, left.z - right.z);
} }
inline Vector3 &operator-=(Vector3 &left, const Vector3 &right) inline Vector3 &operator-=(Vector3 &left, const Vector3 &right)
{ {
left.x -= right.x; left.x -= right.x;
left.y -= right.y; left.y -= right.y;
left.z -= right.z; left.z -= right.z;
return left; return left;
} }
inline Vector3 operator*(const Vector3 &left, float right) inline Vector3 operator*(const Vector3 &left, float right)
{ {
return Vector3(left.x * right, left.y * right, left.z * right); return Vector3(left.x * right, left.y * right, left.z * right);
} }
inline Vector3 &operator*=(Vector3 &left, float right) inline Vector3 &operator*=(Vector3 &left, float right)
{ {
left.x *= right; left.x *= right;
left.y *= right; left.y *= right;
left.z *= right; left.z *= right;
return left; return left;
} }
inline Vector3 operator/(const Vector3 &left, float right) inline Vector3 operator/(const Vector3 &left, float right)
{ {
return Vector3(left.x / right, left.y / right, left.z / right); return Vector3(left.x / right, left.y / right, left.z / right);
} }
inline Vector3 &operator/=(Vector3 &left, float right) inline Vector3 &operator/=(Vector3 &left, float right)
{ {
left.x /= right; left.x /= right;
left.y /= right; left.y /= right;
left.z /= right; left.z /= right;
return left; return left;
} }
inline Vector3 operator*(const Vector3 &left, const Vector3 &right) inline Vector3 operator*(const Vector3 &left, const Vector3 &right)
{ {
return Vector3(left.x * right.x, left.y * right.y, left.z * right.z); return Vector3(left.x * right.x, left.y * right.y, left.z * right.z);
} }
inline Vector3 &operator*=(Vector3 &left, const Vector3 &right) inline Vector3 &operator*=(Vector3 &left, const Vector3 &right)
{ {
left.x *= right.x; left.x *= right.x;
left.y *= right.y; left.y *= right.y;
left.z *= right.z; left.z *= right.z;
return left; return left;
} }
inline Vector3 operator/(const Vector3 &left, const Vector3 &right) inline Vector3 operator/(const Vector3 &left, const Vector3 &right)
{ {
return Vector3(left.x / right.x, left.y / right.y, left.z / right.z); return Vector3(left.x / right.x, left.y / right.y, left.z / right.z);
} }
inline Vector3 &operator/=(Vector3 &left, const Vector3 &right) inline Vector3 &operator/=(Vector3 &left, const Vector3 &right)
{ {
left.x /= right.x; left.x /= right.x;
left.y /= right.y; left.y /= right.y;
left.z /= right.z; left.z /= right.z;
return left; return left;
} }
#endif #endif

View file

@ -1,117 +1,117 @@
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include <exception> #include <exception>
#include "md2/md2.h" #include "md2/md2.h"
#include "obj/obj.h" #include "obj/obj.h"
#include "sm/sm.h" #include "sm/sm.h"
#include "ms3d/ms3d.h" #include "ms3d/ms3d.h"
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("MESH Converter\n"); printf("MESH Converter\n");
if (argc == 1) if (argc == 1)
{ {
printf("No input file specified.\n"); printf("No input file specified.\n");
printf("Usage: meshconverter.exe [inputfile]\n\n"); printf("Usage: meshconverter.exe [inputfile]\n\n");
return 1; return 1;
} }
std::string file = argv[1]; std::string file = argv[1];
std::string extension; std::string extension;
try try
{ {
extension = file.substr(file.find_last_of('.'), std::string::npos); extension = file.substr(file.find_last_of('.'), std::string::npos);
for (int i = 0; i < extension.size(); ++i) for (int i = 0; i < extension.size(); ++i)
extension[i] = tolower(extension[i]); extension[i] = tolower(extension[i]);
} }
catch (std::exception &e) catch (std::exception &e)
{ {
extension = ""; extension = "";
} }
std::string meshFile = ""; std::string meshFile = "";
if (extension.length() > 0) if (extension.length() > 0)
{ {
meshFile = file; meshFile = file;
meshFile.erase(meshFile.find_last_of('.'), std::string::npos); meshFile.erase(meshFile.find_last_of('.'), std::string::npos);
meshFile.append(".mesh"); meshFile.append(".mesh");
} }
if (extension == ".obj") if (extension == ".obj")
{ {
printf("Using OBJ converter.\n"); printf("Using OBJ converter.\n");
Obj *obj = new Obj(); Obj *obj = new Obj();
if (!obj->Load(file, "./")) if (!obj->Load(file, "./"))
{ {
printf("Error loading OBJ file.\n\n"); printf("Error loading OBJ file.\n\n");
return 1; return 1;
} }
if (!obj->ConvertToMesh(meshFile)) if (!obj->ConvertToMesh(meshFile))
{ {
printf("Error converting OBJ to MESH.\n\n"); printf("Error converting OBJ to MESH.\n\n");
return 1; return 1;
} }
} }
else if (extension == ".md2") else if (extension == ".md2")
{ {
printf("Using MD2 converter.\n"); printf("Using MD2 converter.\n");
Md2 *md2 = new Md2(); Md2 *md2 = new Md2();
if (!md2->Load(file)) if (!md2->Load(file))
{ {
printf("Error loading MD2 file.\n\n"); printf("Error loading MD2 file.\n\n");
return 1; return 1;
} }
if (!md2->ConvertToMesh(meshFile)) if (!md2->ConvertToMesh(meshFile))
{ {
printf("Error converting MD2 to MESH.\n\n"); printf("Error converting MD2 to MESH.\n\n");
return 1; return 1;
} }
} }
else if (extension == ".sm") else if (extension == ".sm")
{ {
printf("Using SM converter.\n"); printf("Using SM converter.\n");
StaticModel *sm = new StaticModel(); StaticModel *sm = new StaticModel();
if (!sm->Load(file)) if (!sm->Load(file))
{ {
printf("Error loading SM file.\n\n"); printf("Error loading SM file.\n\n");
return 1; return 1;
} }
if (!sm->ConvertToMesh(meshFile)) if (!sm->ConvertToMesh(meshFile))
{ {
printf("Error converting SM to MESH.\n\n"); printf("Error converting SM to MESH.\n\n");
return 1; return 1;
} }
} }
else if (extension == ".ms3d") else if (extension == ".ms3d")
{ {
printf("Using MS3D converter.\n"); printf("Using MS3D converter.\n");
Ms3d *ms3d = new Ms3d(); Ms3d *ms3d = new Ms3d();
if (!ms3d->Load(file)) if (!ms3d->Load(file))
{ {
printf("Error loading MS3D file.\n\n"); printf("Error loading MS3D file.\n\n");
return 1; return 1;
} }
if (!ms3d->ConvertToMesh(meshFile)) if (!ms3d->ConvertToMesh(meshFile))
{ {
printf("Error converting MS3D to MESH.\n\n"); printf("Error converting MS3D to MESH.\n\n");
return 1; return 1;
} }
} }
else else
{ {
printf("Unrecognized file type.\n\n"); printf("Unrecognized file type.\n\n");
return 1; return 1;
} }
printf("Finished converting to %s\n", meshFile.c_str()); printf("Finished converting to %s\n", meshFile.c_str());
return 0; return 0;
} }

View file

@ -1,358 +1,358 @@
#include "md2.h" #include "md2.h"
#include <stdio.h> #include <stdio.h>
#include "../chunks/chunks.h" #include "../chunks/chunks.h"
Md2::Md2() Md2::Md2()
{ {
m_numFrames = 0; m_numFrames = 0;
m_numPolys = 0; m_numPolys = 0;
m_numTexCoords = 0; m_numTexCoords = 0;
m_numVertices = 0; m_numVertices = 0;
m_numSkins = 0; m_numSkins = 0;
m_frames = NULL; m_frames = NULL;
m_polys = NULL; m_polys = NULL;
m_texCoords = NULL; m_texCoords = NULL;
m_skins = NULL; m_skins = NULL;
} }
void Md2::Release() void Md2::Release()
{ {
delete[] m_frames; delete[] m_frames;
delete[] m_polys; delete[] m_polys;
delete[] m_texCoords; delete[] m_texCoords;
delete[] m_skins; delete[] m_skins;
m_numFrames = 0; m_numFrames = 0;
m_numPolys = 0; m_numPolys = 0;
m_numTexCoords = 0; m_numTexCoords = 0;
m_numVertices = 0; m_numVertices = 0;
m_numSkins = 0; m_numSkins = 0;
m_frames = NULL; m_frames = NULL;
m_polys = NULL; m_polys = NULL;
m_texCoords = NULL; m_texCoords = NULL;
m_skins = NULL; m_skins = NULL;
} }
bool Md2::Load(const std::string &file) bool Md2::Load(const std::string &file)
{ {
FILE *fp; FILE *fp;
unsigned char c; unsigned char c;
unsigned short u, v, t; unsigned short u, v, t;
float x, y, z; float x, y, z;
Md2Header header; Md2Header header;
Vector3 scale, translate; Vector3 scale, translate;
fp = fopen(file.c_str(), "rb"); fp = fopen(file.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
// Simple filetype verification // Simple filetype verification
fread(&header.ident, 4, 1, fp); fread(&header.ident, 4, 1, fp);
if (header.ident[0] != 'I' || header.ident[1] != 'D' || header.ident[2] != 'P' || header.ident[3] != '2') if (header.ident[0] != 'I' || header.ident[1] != 'D' || header.ident[2] != 'P' || header.ident[3] != '2')
{ {
fclose(fp); fclose(fp);
return false; return false;
} }
fread(&header.version, 4, 1, fp); fread(&header.version, 4, 1, fp);
if (header.version != 8) if (header.version != 8)
{ {
fclose(fp); fclose(fp);
return false; return false;
} }
Release(); Release();
// Read rest of the MD2 header // Read rest of the MD2 header
fread(&header.skinWidth, 4, 1, fp); fread(&header.skinWidth, 4, 1, fp);
fread(&header.skinHeight, 4, 1, fp); fread(&header.skinHeight, 4, 1, fp);
fread(&header.frameSize, 4, 1, fp); fread(&header.frameSize, 4, 1, fp);
fread(&header.numSkins, 4, 1, fp); fread(&header.numSkins, 4, 1, fp);
fread(&header.numVertices, 4, 1, fp); fread(&header.numVertices, 4, 1, fp);
fread(&header.numTexCoords, 4, 1, fp); fread(&header.numTexCoords, 4, 1, fp);
fread(&header.numPolys, 4, 1, fp); fread(&header.numPolys, 4, 1, fp);
fread(&header.numGlCmds, 4, 1, fp); fread(&header.numGlCmds, 4, 1, fp);
fread(&header.numFrames, 4, 1, fp); fread(&header.numFrames, 4, 1, fp);
fread(&header.offsetSkins, 4, 1, fp); fread(&header.offsetSkins, 4, 1, fp);
fread(&header.offsetTexCoords, 4, 1, fp); fread(&header.offsetTexCoords, 4, 1, fp);
fread(&header.offsetPolys, 4, 1, fp); fread(&header.offsetPolys, 4, 1, fp);
fread(&header.offsetFrames, 4, 1, fp); fread(&header.offsetFrames, 4, 1, fp);
fread(&header.offsetGlCmds, 4, 1, fp); fread(&header.offsetGlCmds, 4, 1, fp);
fread(&header.offsetEnd, 4, 1, fp); fread(&header.offsetEnd, 4, 1, fp);
// Allocate memory // Allocate memory
if (header.numSkins > 0) if (header.numSkins > 0)
{ {
m_skins = new std::string[header.numSkins]; m_skins = new std::string[header.numSkins];
//ASSERT(m_skins != NULL); //ASSERT(m_skins != NULL);
} }
m_texCoords = new Vector2[header.numTexCoords]; m_texCoords = new Vector2[header.numTexCoords];
m_polys = new Md2Polygon[header.numPolys]; m_polys = new Md2Polygon[header.numPolys];
m_frames = new Md2Frame[header.numFrames]; m_frames = new Md2Frame[header.numFrames];
//ASSERT(m_texCoords != NULL); //ASSERT(m_texCoords != NULL);
//ASSERT(m_polys != NULL); //ASSERT(m_polys != NULL);
//ASSERT(m_frames != NULL); //ASSERT(m_frames != NULL);
// Save model properties // Save model properties
m_numFrames = header.numFrames; m_numFrames = header.numFrames;
m_numPolys = header.numPolys; m_numPolys = header.numPolys;
m_numSkins = header.numSkins; m_numSkins = header.numSkins;
m_numTexCoords = header.numTexCoords; m_numTexCoords = header.numTexCoords;
m_numVertices = header.numVertices; m_numVertices = header.numVertices;
// Read skin info // Read skin info
fseek(fp, header.offsetSkins, SEEK_SET); fseek(fp, header.offsetSkins, SEEK_SET);
for (int i = 0; i < header.numSkins; ++i) for (int i = 0; i < header.numSkins; ++i)
{ {
// Not wasting the full 64 characters stored in the file here // Not wasting the full 64 characters stored in the file here
for (int j = 0; j < MD2_SKIN_NAME_LENGTH; ++j) for (int j = 0; j < MD2_SKIN_NAME_LENGTH; ++j)
{ {
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
if (!c) if (!c)
{ {
fseek(fp, MD2_SKIN_NAME_LENGTH - j - 1, SEEK_CUR); fseek(fp, MD2_SKIN_NAME_LENGTH - j - 1, SEEK_CUR);
break; break;
} }
else else
m_skins[i].append(1, c); m_skins[i].append(1, c);
} }
} }
// Read texture coordinates // Read texture coordinates
fseek(fp, header.offsetTexCoords, SEEK_SET); fseek(fp, header.offsetTexCoords, SEEK_SET);
for (int i = 0; i < header.numTexCoords; ++i) for (int i = 0; i < header.numTexCoords; ++i)
{ {
fread(&u, 2, 1, fp); fread(&u, 2, 1, fp);
fread(&v, 2, 1, fp); fread(&v, 2, 1, fp);
m_texCoords[i].x = u / (float)header.skinWidth; m_texCoords[i].x = u / (float)header.skinWidth;
m_texCoords[i].y = v / (float)header.skinHeight; m_texCoords[i].y = v / (float)header.skinHeight;
} }
// Read polygons (this is all just indexes into m_texCoords and m_frames[].vertices) // Read polygons (this is all just indexes into m_texCoords and m_frames[].vertices)
fseek(fp, header.offsetPolys, SEEK_SET); fseek(fp, header.offsetPolys, SEEK_SET);
for (int i = 0; i < header.numPolys; ++i) for (int i = 0; i < header.numPolys; ++i)
{ {
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].vertex[0] = t; m_polys[i].vertex[0] = t;
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].vertex[2] = t; m_polys[i].vertex[2] = t;
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].vertex[1] = t; m_polys[i].vertex[1] = t;
// HACK: Not sure why some of these indexes are invalid? This seems to fix the problem // HACK: Not sure why some of these indexes are invalid? This seems to fix the problem
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].texCoord[0] = (t == 65535 ? 0 : t); m_polys[i].texCoord[0] = (t == 65535 ? 0 : t);
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].texCoord[2] = (t == 65535 ? 0 : t); m_polys[i].texCoord[2] = (t == 65535 ? 0 : t);
fread(&t, 2, 1, fp); fread(&t, 2, 1, fp);
m_polys[i].texCoord[1] = (t == 65535 ? 0 : t); m_polys[i].texCoord[1] = (t == 65535 ? 0 : t);
} }
// Read frames // Read frames
fseek(fp, header.offsetFrames, SEEK_SET); fseek(fp, header.offsetFrames, SEEK_SET);
for (int i = 0; i < header.numFrames; ++i) for (int i = 0; i < header.numFrames; ++i)
{ {
// Allocate enough memory for this frame's vertex/normal indexes // Allocate enough memory for this frame's vertex/normal indexes
m_frames[i].vertices = new Vector3[header.numVertices]; m_frames[i].vertices = new Vector3[header.numVertices];
//m_frames[i].normals = new Vector3[header.numPolys]; //m_frames[i].normals = new Vector3[header.numPolys];
m_frames[i].normals = new Vector3[header.numVertices]; m_frames[i].normals = new Vector3[header.numVertices];
//ASSERT(m_frames[i].vertices != NULL); //ASSERT(m_frames[i].vertices != NULL);
//ASSERT(m_frames[i].normals != NULL); //ASSERT(m_frames[i].normals != NULL);
fread(&scale.x, 4, 1, fp); fread(&scale.x, 4, 1, fp);
fread(&scale.y, 4, 1, fp); fread(&scale.y, 4, 1, fp);
fread(&scale.z, 4, 1, fp); fread(&scale.z, 4, 1, fp);
fread(&translate.x, 4, 1, fp); fread(&translate.x, 4, 1, fp);
fread(&translate.y, 4, 1, fp); fread(&translate.y, 4, 1, fp);
fread(&translate.z, 4, 1, fp); fread(&translate.z, 4, 1, fp);
// Store the text name of the frame (we won't waste the full 16 characters // Store the text name of the frame (we won't waste the full 16 characters
// reserved in the file here) // reserved in the file here)
for (int j = 0; j < MD2_FRAME_NAME_LENGTH; ++j) for (int j = 0; j < MD2_FRAME_NAME_LENGTH; ++j)
{ {
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
if (!c) if (!c)
{ {
fseek(fp, MD2_FRAME_NAME_LENGTH - j - 1, SEEK_CUR); fseek(fp, MD2_FRAME_NAME_LENGTH - j - 1, SEEK_CUR);
break; break;
} }
else else
m_frames[i].name += c; m_frames[i].name += c;
} }
// Read vertices, and decompress as we load them for performance when rendering // Read vertices, and decompress as we load them for performance when rendering
for (int j = 0; j < header.numVertices; ++j) for (int j = 0; j < header.numVertices; ++j)
{ {
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
x = (float)c; x = (float)c;
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
y = (float)c; y = (float)c;
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
z = (float)c; z = (float)c;
// Convert to OpenGL's coordinate system, otherwise models will need to be rotated to be drawn upright // Convert to OpenGL's coordinate system, otherwise models will need to be rotated to be drawn upright
m_frames[i].vertices[j].x = (x * scale.x) + translate.x; m_frames[i].vertices[j].x = (x * scale.x) + translate.x;
m_frames[i].vertices[j].y = (z * scale.z) + translate.z; m_frames[i].vertices[j].y = (z * scale.z) + translate.z;
m_frames[i].vertices[j].z = -1.0f * ((y * scale.y) + translate.y); m_frames[i].vertices[j].z = -1.0f * ((y * scale.y) + translate.y);
fread(&c, 1, 1, fp); // Dummy command to increment file pointer (we don't care about the normal index) fread(&c, 1, 1, fp); // Dummy command to increment file pointer (we don't care about the normal index)
} }
//m_frameMap[m_frames[i].name] = i; //m_frameMap[m_frames[i].name] = i;
} }
fclose(fp); fclose(fp);
// Cleanup and finishing touches. // Cleanup and finishing touches.
// Vertex coordinates, as of now, are waaay out of range (most likely, unless the model is tiny). // Vertex coordinates, as of now, are waaay out of range (most likely, unless the model is tiny).
// We could've scaled them down above while reading them in, but I noticed issues calculating normals // We could've scaled them down above while reading them in, but I noticed issues calculating normals
// when that was done (probably due to lacking precision). So, we calculate the normals using the // when that was done (probably due to lacking precision). So, we calculate the normals using the
// un-touched coordinates (get the most accurate normal calc that way), then scale the vertex down. // un-touched coordinates (get the most accurate normal calc that way), then scale the vertex down.
for (int i = 0; i < header.numFrames; ++i) for (int i = 0; i < header.numFrames; ++i)
{ {
// Calculate vertex normals // Calculate vertex normals
Vector3 sumNormal; Vector3 sumNormal;
int sum; int sum;
for (int j = 0; j < header.numVertices; ++j) for (int j = 0; j < header.numVertices; ++j)
{ {
sum = 0; sum = 0;
sumNormal = Vector3(0, 0, 0); sumNormal = Vector3(0, 0, 0);
for (int k = 0; k < header.numPolys; ++k) for (int k = 0; k < header.numPolys; ++k)
{ {
if (m_polys[k].vertex[0] == j || m_polys[k].vertex[1] == j || m_polys[k].vertex[2] == j) if (m_polys[k].vertex[0] == j || m_polys[k].vertex[1] == j || m_polys[k].vertex[2] == j)
{ {
++sum; ++sum;
sumNormal += Vector3::SurfaceNormal(m_frames[i].vertices[m_polys[k].vertex[0]], sumNormal += Vector3::SurfaceNormal(m_frames[i].vertices[m_polys[k].vertex[0]],
m_frames[i].vertices[m_polys[k].vertex[1]], m_frames[i].vertices[m_polys[k].vertex[1]],
m_frames[i].vertices[m_polys[k].vertex[2]]); m_frames[i].vertices[m_polys[k].vertex[2]]);
} }
} }
m_frames[i].normals[j] = sumNormal / (float)sum; m_frames[i].normals[j] = sumNormal / (float)sum;
} }
//// Done, now scale the vertices down //// Done, now scale the vertices down
//for (int j = 0; j < header.numVertices; ++j) //for (int j = 0; j < header.numVertices; ++j)
//{ //{
// m_frames[i].vertices[j] /= (float)(MD2_SCALE_FACTOR); // m_frames[i].vertices[j] /= (float)(MD2_SCALE_FACTOR);
//} //}
} }
// check for an animation definition file // check for an animation definition file
std::string animationFile = file; std::string animationFile = file;
animationFile.erase(animationFile.find_last_of('.', std::string::npos)); animationFile.erase(animationFile.find_last_of('.', std::string::npos));
animationFile.append(".animations"); animationFile.append(".animations");
fp = fopen(animationFile.c_str(), "r"); fp = fopen(animationFile.c_str(), "r");
if (fp != NULL) if (fp != NULL)
{ {
char *buffer = new char[80]; char *buffer = new char[80];
std::string line; std::string line;
std::string name; std::string name;
std::string temp; std::string temp;
int start; int start;
int end; int end;
while (!feof(fp)) while (!feof(fp))
{ {
fgets(buffer, 80, fp); fgets(buffer, 80, fp);
line = buffer; line = buffer;
if (strlen(buffer) > 5) // minimum length for a viable frame definition if (strlen(buffer) > 5) // minimum length for a viable frame definition
{ {
// get animation name // get animation name
int nameEnd = line.find_first_of(','); int nameEnd = line.find_first_of(',');
if (nameEnd == std::string::npos) if (nameEnd == std::string::npos)
continue; continue;
name = line.substr(0, nameEnd); name = line.substr(0, nameEnd);
// get start frame index // get start frame index
int startEnd = line.find_first_of(',', nameEnd + 1); int startEnd = line.find_first_of(',', nameEnd + 1);
if (startEnd == std::string::npos) if (startEnd == std::string::npos)
continue; continue;
temp = line.substr(nameEnd + 1, startEnd); temp = line.substr(nameEnd + 1, startEnd);
start = atoi(temp.c_str()); start = atoi(temp.c_str());
// get end frame index // get end frame index
temp = line.substr(startEnd + 1, std::string::npos); temp = line.substr(startEnd + 1, std::string::npos);
end = atoi(temp.c_str()); end = atoi(temp.c_str());
Md2Animation *animation = new Md2Animation(); Md2Animation *animation = new Md2Animation();
animation->name = name; animation->name = name;
animation->startFrame = start; animation->startFrame = start;
animation->endFrame = end; animation->endFrame = end;
m_animations.push_back(*animation); m_animations.push_back(*animation);
} }
} }
delete[] buffer; delete[] buffer;
fclose(fp); fclose(fp);
} }
return true; return true;
} }
bool Md2::ConvertToMesh(const std::string &file) bool Md2::ConvertToMesh(const std::string &file)
{ {
FILE *fp = fopen(file.c_str(), "wb"); FILE *fp = fopen(file.c_str(), "wb");
if (fp == NULL) if (fp == NULL)
return false; return false;
WriteFileHeader(fp); WriteFileHeader(fp);
KeyFramesChunk *keyFramesChunk = new KeyFramesChunk(); KeyFramesChunk *keyFramesChunk = new KeyFramesChunk();
keyFramesChunk->numVertices = m_numVertices; keyFramesChunk->numVertices = m_numVertices;
for (long i = 0; i < m_numFrames; ++i) for (long i = 0; i < m_numFrames; ++i)
{ {
KeyFrame *frame = keyFramesChunk->AddFrame(); KeyFrame *frame = keyFramesChunk->AddFrame();
for (int j = 0; j < m_numVertices; ++j) for (int j = 0; j < m_numVertices; ++j)
frame->vertices[j] = m_frames[i].vertices[j]; frame->vertices[j] = m_frames[i].vertices[j];
for (int j = 0; j < m_numVertices; ++j) for (int j = 0; j < m_numVertices; ++j)
frame->normals[j] = m_frames[i].normals[j]; frame->normals[j] = m_frames[i].normals[j];
} }
WriteChunk(keyFramesChunk, fp); WriteChunk(keyFramesChunk, fp);
TexCoordsChunk *texCoordsChunk = new TexCoordsChunk(); TexCoordsChunk *texCoordsChunk = new TexCoordsChunk();
for (long i = 0; i < m_numTexCoords; ++i) for (long i = 0; i < m_numTexCoords; ++i)
texCoordsChunk->texCoords.push_back(m_texCoords[i]); texCoordsChunk->texCoords.push_back(m_texCoords[i]);
WriteChunk(texCoordsChunk, fp); WriteChunk(texCoordsChunk, fp);
KeyFrameTrianglesChunk *trianglesChunk = new KeyFrameTrianglesChunk(); KeyFrameTrianglesChunk *trianglesChunk = new KeyFrameTrianglesChunk();
for (long i = 0; i < m_numPolys; ++i) for (long i = 0; i < m_numPolys; ++i)
{ {
KeyFrameTriangle t; KeyFrameTriangle t;
t.vertices[0] = m_polys[i].vertex[0]; t.vertices[0] = m_polys[i].vertex[0];
t.vertices[1] = m_polys[i].vertex[1]; t.vertices[1] = m_polys[i].vertex[1];
t.vertices[2] = m_polys[i].vertex[2]; t.vertices[2] = m_polys[i].vertex[2];
t.texCoords[0] = m_polys[i].texCoord[0]; t.texCoords[0] = m_polys[i].texCoord[0];
t.texCoords[1] = m_polys[i].texCoord[1]; t.texCoords[1] = m_polys[i].texCoord[1];
t.texCoords[2] = m_polys[i].texCoord[2]; t.texCoords[2] = m_polys[i].texCoord[2];
trianglesChunk->triangles.push_back(t); trianglesChunk->triangles.push_back(t);
} }
WriteChunk(trianglesChunk, fp); WriteChunk(trianglesChunk, fp);
if (m_animations.size() > 0) if (m_animations.size() > 0)
{ {
AnimationsChunk *animationsChunk = new AnimationsChunk(); AnimationsChunk *animationsChunk = new AnimationsChunk();
for (long i = 0; i < m_animations.size(); ++i) for (long i = 0; i < m_animations.size(); ++i)
{ {
AnimationSequence a; AnimationSequence a;
a.name = m_animations[i].name; a.name = m_animations[i].name;
a.start = m_animations[i].startFrame; a.start = m_animations[i].startFrame;
a.end = m_animations[i].endFrame; a.end = m_animations[i].endFrame;
animationsChunk->animations.push_back(a); animationsChunk->animations.push_back(a);
} }
WriteChunk(animationsChunk, fp); WriteChunk(animationsChunk, fp);
} }
fclose(fp); fclose(fp);
return true; return true;
} }

View file

@ -1,100 +1,100 @@
#ifndef __MD2_H_INCLUDED__ #ifndef __MD2_H_INCLUDED__
#define __MD2_H_INCLUDED__ #define __MD2_H_INCLUDED__
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include "../geometry/vector2.h" #include "../geometry/vector2.h"
#include <string> #include <string>
#include <vector> #include <vector>
#define MD2_SKIN_NAME_LENGTH 64 #define MD2_SKIN_NAME_LENGTH 64
#define MD2_FRAME_NAME_LENGTH 16 #define MD2_FRAME_NAME_LENGTH 16
typedef struct typedef struct
{ {
char ident[4]; // Should be "IDP2" char ident[4]; // Should be "IDP2"
int version; // Should be 8 int version; // Should be 8
int skinWidth; // Texture dimensions int skinWidth; // Texture dimensions
int skinHeight; int skinHeight;
int frameSize; // Size of a single frame in bytes int frameSize; // Size of a single frame in bytes
int numSkins; int numSkins;
int numVertices; int numVertices;
int numTexCoords; int numTexCoords;
int numPolys; int numPolys;
int numGlCmds; int numGlCmds;
int numFrames; int numFrames;
int offsetSkins; int offsetSkins;
int offsetTexCoords; int offsetTexCoords;
int offsetPolys; int offsetPolys;
int offsetFrames; int offsetFrames;
int offsetGlCmds; int offsetGlCmds;
int offsetEnd; int offsetEnd;
} Md2Header; } Md2Header;
// Vertex and texcoord indices // Vertex and texcoord indices
typedef struct typedef struct
{ {
unsigned short vertex[3]; unsigned short vertex[3];
unsigned short texCoord[3]; unsigned short texCoord[3];
} Md2Polygon; } Md2Polygon;
// For each keyframe, stores the vertices, normals, and the string name // For each keyframe, stores the vertices, normals, and the string name
typedef struct Md2Frame typedef struct Md2Frame
{ {
std::string name; std::string name;
Vector3 *vertices; Vector3 *vertices;
Vector3 *normals; Vector3 *normals;
Md2Frame() Md2Frame()
{ {
vertices = NULL; vertices = NULL;
normals = NULL; normals = NULL;
} }
~Md2Frame() ~Md2Frame()
{ {
delete[] vertices; delete[] vertices;
delete[] normals; delete[] normals;
} }
} Md2Frame; } Md2Frame;
typedef struct typedef struct
{ {
std::string name; std::string name;
unsigned int startFrame; unsigned int startFrame;
unsigned int endFrame; unsigned int endFrame;
} Md2Animation; } Md2Animation;
class Md2 class Md2
{ {
public: public:
Md2(); Md2();
virtual ~Md2() { Release(); } virtual ~Md2() { Release(); }
void Release(); void Release();
bool Load(const std::string &file); bool Load(const std::string &file);
bool ConvertToMesh(const std::string &file); bool ConvertToMesh(const std::string &file);
int GetNumFrames() { return m_numFrames; } int GetNumFrames() { return m_numFrames; }
int GetNumVertices() { return m_numVertices; } int GetNumVertices() { return m_numVertices; }
int GetNumTexCoords() { return m_numTexCoords; } int GetNumTexCoords() { return m_numTexCoords; }
int GetNumPolys() { return m_numPolys; } int GetNumPolys() { return m_numPolys; }
int GetNumSkins() { return m_numSkins; } int GetNumSkins() { return m_numSkins; }
Md2Frame* GetFrames() { return m_frames; } Md2Frame* GetFrames() { return m_frames; }
Md2Polygon* GetPolygons() { return m_polys; } Md2Polygon* GetPolygons() { return m_polys; }
Vector2* GetTexCoords() { return m_texCoords; } Vector2* GetTexCoords() { return m_texCoords; }
private: private:
int m_numFrames; int m_numFrames;
int m_numVertices; int m_numVertices;
int m_numTexCoords; int m_numTexCoords;
int m_numPolys; int m_numPolys;
int m_numSkins; int m_numSkins;
Md2Frame *m_frames; Md2Frame *m_frames;
Md2Polygon *m_polys; Md2Polygon *m_polys;
Vector2 *m_texCoords; Vector2 *m_texCoords;
std::string *m_skins; std::string *m_skins;
std::vector<Md2Animation> m_animations; std::vector<Md2Animation> m_animations;
}; };
#endif #endif

View file

@ -1,435 +1,435 @@
#include "ms3d.h" #include "ms3d.h"
#include <stdio.h> #include <stdio.h>
#include "../util/files.h" #include "../util/files.h"
Ms3d::Ms3d() Ms3d::Ms3d()
{ {
m_numVertices = 0; m_numVertices = 0;
m_numTriangles = 0; m_numTriangles = 0;
m_numMeshes = 0; m_numMeshes = 0;
m_numMaterials = 0; m_numMaterials = 0;
m_numJoints = 0; m_numJoints = 0;
m_vertices = NULL; m_vertices = NULL;
m_triangles = NULL; m_triangles = NULL;
m_meshes = NULL; m_meshes = NULL;
m_materials = NULL; m_materials = NULL;
m_joints = NULL; m_joints = NULL;
} }
void Ms3d::Release() void Ms3d::Release()
{ {
delete[] m_vertices; delete[] m_vertices;
delete[] m_triangles; delete[] m_triangles;
delete[] m_meshes; delete[] m_meshes;
delete[] m_materials; delete[] m_materials;
delete[] m_joints; delete[] m_joints;
m_numVertices = 0; m_numVertices = 0;
m_numTriangles = 0; m_numTriangles = 0;
m_numMeshes = 0; m_numMeshes = 0;
m_numMaterials = 0; m_numMaterials = 0;
m_numJoints = 0; m_numJoints = 0;
} }
bool Ms3d::Load(const std::string &file) bool Ms3d::Load(const std::string &file)
{ {
FILE *fp; FILE *fp;
Ms3dHeader header; Ms3dHeader header;
fp = fopen(file.c_str(), "rb"); fp = fopen(file.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
// filetype verification // filetype verification
fread(&header.id, 10, 1, fp); fread(&header.id, 10, 1, fp);
if (strncmp(header.id, "MS3D000000", 10) != 0) if (strncmp(header.id, "MS3D000000", 10) != 0)
{ {
fclose(fp); fclose(fp);
return false; return false;
} }
fread(&header.version, 4, 1, fp); fread(&header.version, 4, 1, fp);
if (header.version != 4) if (header.version != 4)
{ {
fclose(fp); fclose(fp);
return false; return false;
} }
// read vertices // read vertices
fread(&m_numVertices, 2, 1, fp); fread(&m_numVertices, 2, 1, fp);
m_vertices = new Ms3dVertex[m_numVertices]; m_vertices = new Ms3dVertex[m_numVertices];
for (int i = 0; i < m_numVertices; ++i) for (int i = 0; i < m_numVertices; ++i)
{ {
Ms3dVertex *vertex = &m_vertices[i]; Ms3dVertex *vertex = &m_vertices[i];
fread(&vertex->editorFlags, 1, 1, fp); fread(&vertex->editorFlags, 1, 1, fp);
fread(&vertex->vertex.x, 4, 1, fp); fread(&vertex->vertex.x, 4, 1, fp);
fread(&vertex->vertex.y, 4, 1, fp); fread(&vertex->vertex.y, 4, 1, fp);
fread(&vertex->vertex.z, 4, 1, fp); fread(&vertex->vertex.z, 4, 1, fp);
fread(&vertex->jointIndex, 1, 1, fp); fread(&vertex->jointIndex, 1, 1, fp);
fread(&vertex->unused, 1, 1, fp); fread(&vertex->unused, 1, 1, fp);
} }
// read triangle definitions // read triangle definitions
fread(&m_numTriangles, 2, 1, fp); fread(&m_numTriangles, 2, 1, fp);
m_triangles = new Ms3dTriangle[m_numTriangles]; m_triangles = new Ms3dTriangle[m_numTriangles];
for (int i = 0; i < m_numTriangles; ++i) for (int i = 0; i < m_numTriangles; ++i)
{ {
Ms3dTriangle *triangle = &m_triangles[i]; Ms3dTriangle *triangle = &m_triangles[i];
fread(&triangle->editorFlags, 2, 1, fp); fread(&triangle->editorFlags, 2, 1, fp);
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
fread(&triangle->vertices[j], 2, 1, fp); fread(&triangle->vertices[j], 2, 1, fp);
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fread(&triangle->normals[j].x, 4, 1, fp); fread(&triangle->normals[j].x, 4, 1, fp);
fread(&triangle->normals[j].y, 4, 1, fp); fread(&triangle->normals[j].y, 4, 1, fp);
fread(&triangle->normals[j].z, 4, 1, fp); fread(&triangle->normals[j].z, 4, 1, fp);
} }
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
fread(&triangle->texCoords[j].x, 4, 1, fp); fread(&triangle->texCoords[j].x, 4, 1, fp);
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
fread(&triangle->texCoords[j].y, 4, 1, fp); fread(&triangle->texCoords[j].y, 4, 1, fp);
fread(&triangle->smoothingGroup, 1, 1, fp); fread(&triangle->smoothingGroup, 1, 1, fp);
fread(&triangle->meshIndex, 1, 1, fp); fread(&triangle->meshIndex, 1, 1, fp);
} }
// read mesh information // read mesh information
fread(&m_numMeshes, 2, 1, fp); fread(&m_numMeshes, 2, 1, fp);
m_meshes = new Ms3dMesh[m_numMeshes]; m_meshes = new Ms3dMesh[m_numMeshes];
for (int i = 0; i < m_numMeshes; ++i) for (int i = 0; i < m_numMeshes; ++i)
{ {
Ms3dMesh *mesh = &m_meshes[i]; Ms3dMesh *mesh = &m_meshes[i];
fread(&mesh->editorFlags, 1, 1, fp); fread(&mesh->editorFlags, 1, 1, fp);
ReadString(fp, mesh->name, 32); ReadString(fp, mesh->name, 32);
fread(&mesh->numTriangles, 2, 1, fp); fread(&mesh->numTriangles, 2, 1, fp);
mesh->triangles = new unsigned short[mesh->numTriangles]; mesh->triangles = new unsigned short[mesh->numTriangles];
for (int j = 0; j < mesh->numTriangles; ++j) for (int j = 0; j < mesh->numTriangles; ++j)
fread(&mesh->triangles[j], 2, 1, fp); fread(&mesh->triangles[j], 2, 1, fp);
fread(&mesh->materialIndex, 1, 1, fp); fread(&mesh->materialIndex, 1, 1, fp);
} }
// read material information // read material information
fread(&m_numMaterials, 2, 1, fp); fread(&m_numMaterials, 2, 1, fp);
if (m_numMaterials > 0) if (m_numMaterials > 0)
{ {
m_materials = new Ms3dMaterial[m_numMaterials]; m_materials = new Ms3dMaterial[m_numMaterials];
for (int i = 0; i < m_numMaterials; ++i) for (int i = 0; i < m_numMaterials; ++i)
{ {
Ms3dMaterial *material = &m_materials[i]; Ms3dMaterial *material = &m_materials[i];
ReadString(fp, material->name, 32); ReadString(fp, material->name, 32);
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
fread(&material->ambient[j], 4, 1, fp); fread(&material->ambient[j], 4, 1, fp);
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
fread(&material->diffuse[j], 4, 1, fp); fread(&material->diffuse[j], 4, 1, fp);
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
fread(&material->specular[j], 4, 1, fp); fread(&material->specular[j], 4, 1, fp);
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
fread(&material->emissive[j], 4, 1, fp); fread(&material->emissive[j], 4, 1, fp);
fread(&material->shininess, 4, 1, fp); fread(&material->shininess, 4, 1, fp);
fread(&material->transparency, 4, 1, fp); fread(&material->transparency, 4, 1, fp);
fread(&material->mode, 1, 1, fp); fread(&material->mode, 1, 1, fp);
ReadString(fp, material->texture, 128); ReadString(fp, material->texture, 128);
ReadString(fp, material->alpha, 128); ReadString(fp, material->alpha, 128);
} }
} }
// read joints // read joints
fread(&m_animationFps, 4, 1, fp); fread(&m_animationFps, 4, 1, fp);
fread(&m_editorAnimationTime, 4, 1, fp); fread(&m_editorAnimationTime, 4, 1, fp);
fread(&m_numFrames, 4, 1, fp); fread(&m_numFrames, 4, 1, fp);
fread(&m_numJoints, 2, 1, fp); fread(&m_numJoints, 2, 1, fp);
if (m_numJoints > 0) if (m_numJoints > 0)
{ {
m_joints = new Ms3dJoint[m_numJoints]; m_joints = new Ms3dJoint[m_numJoints];
for (int i = 0; i < m_numJoints; ++i) for (int i = 0; i < m_numJoints; ++i)
{ {
Ms3dJoint *joint = &m_joints[i]; Ms3dJoint *joint = &m_joints[i];
fread(&joint->editorFlags, 1, 1, fp); fread(&joint->editorFlags, 1, 1, fp);
ReadString(fp, joint->name, 32); ReadString(fp, joint->name, 32);
ReadString(fp, joint->parentName, 32); ReadString(fp, joint->parentName, 32);
fread(&joint->rotation.x, 4, 1, fp); fread(&joint->rotation.x, 4, 1, fp);
fread(&joint->rotation.y, 4, 1, fp); fread(&joint->rotation.y, 4, 1, fp);
fread(&joint->rotation.z, 4, 1, fp); fread(&joint->rotation.z, 4, 1, fp);
fread(&joint->position.x, 4, 1, fp); fread(&joint->position.x, 4, 1, fp);
fread(&joint->position.y, 4, 1, fp); fread(&joint->position.y, 4, 1, fp);
fread(&joint->position.z, 4, 1, fp); fread(&joint->position.z, 4, 1, fp);
fread(&joint->numRotationFrames, 2, 1, fp); fread(&joint->numRotationFrames, 2, 1, fp);
fread(&joint->numTranslationFrames, 2, 1, fp); fread(&joint->numTranslationFrames, 2, 1, fp);
joint->rotationFrames = new Ms3dKeyFrame[joint->numRotationFrames]; joint->rotationFrames = new Ms3dKeyFrame[joint->numRotationFrames];
for (int j = 0; j < joint->numRotationFrames; ++j) for (int j = 0; j < joint->numRotationFrames; ++j)
{ {
Ms3dKeyFrame *frame = &joint->rotationFrames[j]; Ms3dKeyFrame *frame = &joint->rotationFrames[j];
fread(&frame->time, 4, 1, fp); fread(&frame->time, 4, 1, fp);
fread(&frame->param.x, 4, 1, fp); fread(&frame->param.x, 4, 1, fp);
fread(&frame->param.y, 4, 1, fp); fread(&frame->param.y, 4, 1, fp);
fread(&frame->param.z, 4, 1, fp); fread(&frame->param.z, 4, 1, fp);
} }
joint->translationFrames = new Ms3dKeyFrame[joint->numTranslationFrames]; joint->translationFrames = new Ms3dKeyFrame[joint->numTranslationFrames];
for (int j = 0; j < joint->numTranslationFrames; ++j) for (int j = 0; j < joint->numTranslationFrames; ++j)
{ {
Ms3dKeyFrame *frame = &joint->translationFrames[j]; Ms3dKeyFrame *frame = &joint->translationFrames[j];
fread(&frame->time, 4, 1, fp); fread(&frame->time, 4, 1, fp);
fread(&frame->param.x, 4, 1, fp); fread(&frame->param.x, 4, 1, fp);
fread(&frame->param.y, 4, 1, fp); fread(&frame->param.y, 4, 1, fp);
fread(&frame->param.z, 4, 1, fp); fread(&frame->param.z, 4, 1, fp);
} }
} }
} }
fclose(fp); fclose(fp);
// check for an animation definition file // check for an animation definition file
std::string animationFile = file; std::string animationFile = file;
animationFile.erase(animationFile.find_last_of('.', std::string::npos)); animationFile.erase(animationFile.find_last_of('.', std::string::npos));
animationFile.append(".animations"); animationFile.append(".animations");
fp = fopen(animationFile.c_str(), "r"); fp = fopen(animationFile.c_str(), "r");
if (fp != NULL) if (fp != NULL)
{ {
char *buffer = new char[80]; char *buffer = new char[80];
std::string line; std::string line;
std::string name; std::string name;
std::string temp; std::string temp;
int start; int start;
int end; int end;
while (!feof(fp)) while (!feof(fp))
{ {
fgets(buffer, 80, fp); fgets(buffer, 80, fp);
line = buffer; line = buffer;
if (strlen(buffer) > 5) // minimum length for a viable frame definition if (strlen(buffer) > 5) // minimum length for a viable frame definition
{ {
// get animation name // get animation name
int nameEnd = line.find_first_of(','); int nameEnd = line.find_first_of(',');
if (nameEnd == std::string::npos) if (nameEnd == std::string::npos)
continue; continue;
name = line.substr(0, nameEnd); name = line.substr(0, nameEnd);
// get start frame index // get start frame index
int startEnd = line.find_first_of(',', nameEnd + 1); int startEnd = line.find_first_of(',', nameEnd + 1);
if (startEnd == std::string::npos) if (startEnd == std::string::npos)
continue; continue;
temp = line.substr(nameEnd + 1, startEnd); temp = line.substr(nameEnd + 1, startEnd);
start = atoi(temp.c_str()); start = atoi(temp.c_str());
// get end frame index // get end frame index
temp = line.substr(startEnd + 1, std::string::npos); temp = line.substr(startEnd + 1, std::string::npos);
end = atoi(temp.c_str()); end = atoi(temp.c_str());
Ms3dAnimation *animation = new Ms3dAnimation(); Ms3dAnimation *animation = new Ms3dAnimation();
animation->name = name; animation->name = name;
animation->startFrame = start; animation->startFrame = start;
animation->endFrame = end; animation->endFrame = end;
m_animations.push_back(*animation); m_animations.push_back(*animation);
} }
} }
delete[] buffer; delete[] buffer;
fclose(fp); fclose(fp);
} }
return true; return true;
} }
bool Ms3d::ConvertToMesh(const std::string &file) bool Ms3d::ConvertToMesh(const std::string &file)
{ {
FILE *fp = fopen(file.c_str(), "wb"); FILE *fp = fopen(file.c_str(), "wb");
if (fp == NULL) if (fp == NULL)
return false; return false;
fputs("MESH", fp); fputs("MESH", fp);
unsigned char version = 1; unsigned char version = 1;
fwrite(&version, 1, 1, fp); fwrite(&version, 1, 1, fp);
// vertices chunk // vertices chunk
fputs("VTX", fp); fputs("VTX", fp);
long numVertices = m_numVertices; long numVertices = m_numVertices;
long sizeOfVertices = ((sizeof(float) * 3)) * numVertices + sizeof(long); long sizeOfVertices = ((sizeof(float) * 3)) * numVertices + sizeof(long);
fwrite(&sizeOfVertices, sizeof(long), 1, fp); fwrite(&sizeOfVertices, sizeof(long), 1, fp);
fwrite(&numVertices, sizeof(long), 1, fp); fwrite(&numVertices, sizeof(long), 1, fp);
for (long i = 0; i < numVertices; ++i) for (long i = 0; i < numVertices; ++i)
{ {
Ms3dVertex *vertex = &m_vertices[i]; Ms3dVertex *vertex = &m_vertices[i];
fwrite(&vertex->vertex.x, sizeof(float), 1, fp); fwrite(&vertex->vertex.x, sizeof(float), 1, fp);
fwrite(&vertex->vertex.y, sizeof(float), 1, fp); fwrite(&vertex->vertex.y, sizeof(float), 1, fp);
fwrite(&vertex->vertex.z, sizeof(float), 1, fp); fwrite(&vertex->vertex.z, sizeof(float), 1, fp);
} }
// triangles chunk // triangles chunk
fputs("TRI", fp); fputs("TRI", fp);
long numTriangles = m_numTriangles; long numTriangles = m_numTriangles;
long sizeOfTriangles = (sizeof(int) * 4 + (sizeof(float) * 3) * 3 + (sizeof(float) * 2) * 3) * numTriangles + sizeof(long); long sizeOfTriangles = (sizeof(int) * 4 + (sizeof(float) * 3) * 3 + (sizeof(float) * 2) * 3) * numTriangles + sizeof(long);
fwrite(&sizeOfTriangles, sizeof(long), 1, fp); fwrite(&sizeOfTriangles, sizeof(long), 1, fp);
fwrite(&numTriangles, sizeof(long), 1, fp); fwrite(&numTriangles, sizeof(long), 1, fp);
for (long i = 0; i < numTriangles; ++i) for (long i = 0; i < numTriangles; ++i)
{ {
Ms3dTriangle *triangle = &m_triangles[i]; Ms3dTriangle *triangle = &m_triangles[i];
int index = triangle->vertices[0]; int index = triangle->vertices[0];
fwrite(&index, sizeof(int), 1, fp); fwrite(&index, sizeof(int), 1, fp);
index = triangle->vertices[1]; index = triangle->vertices[1];
fwrite(&index, sizeof(int), 1, fp); fwrite(&index, sizeof(int), 1, fp);
index = triangle->vertices[2]; index = triangle->vertices[2];
fwrite(&index, sizeof(int), 1, fp); fwrite(&index, sizeof(int), 1, fp);
index = triangle->meshIndex; index = triangle->meshIndex;
fwrite(&index, sizeof(int), 1, fp); fwrite(&index, sizeof(int), 1, fp);
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fwrite(&triangle->normals[j].x, sizeof(float), 1, fp); fwrite(&triangle->normals[j].x, sizeof(float), 1, fp);
fwrite(&triangle->normals[j].y, sizeof(float), 1, fp); fwrite(&triangle->normals[j].y, sizeof(float), 1, fp);
fwrite(&triangle->normals[j].z, sizeof(float), 1, fp); fwrite(&triangle->normals[j].z, sizeof(float), 1, fp);
} }
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fwrite(&triangle->texCoords[j].x, sizeof(float), 1, fp); fwrite(&triangle->texCoords[j].x, sizeof(float), 1, fp);
fwrite(&triangle->texCoords[j].y, sizeof(float), 1, fp); fwrite(&triangle->texCoords[j].y, sizeof(float), 1, fp);
} }
} }
// sub-meshes / groups chunk // sub-meshes / groups chunk
fputs("GRP", fp); fputs("GRP", fp);
long numGroups = m_numMeshes; long numGroups = m_numMeshes;
long sizeOfGroupNames = 0; long sizeOfGroupNames = 0;
for (long i = 0; i < numGroups; ++i) for (long i = 0; i < numGroups; ++i)
sizeOfGroupNames += (m_meshes[i].name.length() + 1); sizeOfGroupNames += (m_meshes[i].name.length() + 1);
long sizeOfGroups = sizeOfGroupNames + (sizeof(int)) * numGroups + sizeof(long); long sizeOfGroups = sizeOfGroupNames + (sizeof(int)) * numGroups + sizeof(long);
fwrite(&sizeOfGroups, sizeof(long), 1, fp); fwrite(&sizeOfGroups, sizeof(long), 1, fp);
fwrite(&numGroups, sizeof(long), 1, fp); fwrite(&numGroups, sizeof(long), 1, fp);
for (long i = 0; i < numGroups; ++i) for (long i = 0; i < numGroups; ++i)
{ {
Ms3dMesh *mesh = &m_meshes[i]; Ms3dMesh *mesh = &m_meshes[i];
fwrite(mesh->name.c_str(), mesh->name.length(), 1, fp); fwrite(mesh->name.c_str(), mesh->name.length(), 1, fp);
char c = '\0'; char c = '\0';
fwrite(&c, 1, 1, fp); fwrite(&c, 1, 1, fp);
int numTriangles = mesh->numTriangles; int numTriangles = mesh->numTriangles;
fwrite(&numTriangles, sizeof(int), 1, fp); fwrite(&numTriangles, sizeof(int), 1, fp);
} }
// joints chunk // joints chunk
fputs("JNT", fp); fputs("JNT", fp);
long numJoints = m_numJoints; long numJoints = m_numJoints;
long sizeOfJointNames = 0; long sizeOfJointNames = 0;
for (long i = 0; i < numJoints; ++i) for (long i = 0; i < numJoints; ++i)
sizeOfJointNames += (m_joints[i].name.length() + 1); sizeOfJointNames += (m_joints[i].name.length() + 1);
long sizeOfJoints = sizeOfJointNames + (sizeof(int) + sizeof(float) * 3 + sizeof(float) * 3) * numJoints + sizeof(long); long sizeOfJoints = sizeOfJointNames + (sizeof(int) + sizeof(float) * 3 + sizeof(float) * 3) * numJoints + sizeof(long);
fwrite(&sizeOfJoints, sizeof(long), 1, fp); fwrite(&sizeOfJoints, sizeof(long), 1, fp);
fwrite(&numJoints, sizeof(long), 1, fp); fwrite(&numJoints, sizeof(long), 1, fp);
for (long i = 0; i < numJoints; ++i) for (long i = 0; i < numJoints; ++i)
{ {
Ms3dJoint *joint = &m_joints[i]; Ms3dJoint *joint = &m_joints[i];
fwrite(joint->name.c_str(), joint->name.length(), 1, fp); fwrite(joint->name.c_str(), joint->name.length(), 1, fp);
char c = '\0'; char c = '\0';
fwrite(&c, 1, 1, fp); fwrite(&c, 1, 1, fp);
int parentIndex = FindIndexOfJoint(joint->parentName); int parentIndex = FindIndexOfJoint(joint->parentName);
fwrite(&parentIndex, sizeof(int), 1, fp); fwrite(&parentIndex, sizeof(int), 1, fp);
fwrite(&joint->position.x, sizeof(float), 1, fp); fwrite(&joint->position.x, sizeof(float), 1, fp);
fwrite(&joint->position.y, sizeof(float), 1, fp); fwrite(&joint->position.y, sizeof(float), 1, fp);
fwrite(&joint->position.z, sizeof(float), 1, fp); fwrite(&joint->position.z, sizeof(float), 1, fp);
fwrite(&joint->rotation.x, sizeof(float), 1, fp); fwrite(&joint->rotation.x, sizeof(float), 1, fp);
fwrite(&joint->rotation.y, sizeof(float), 1, fp); fwrite(&joint->rotation.y, sizeof(float), 1, fp);
fwrite(&joint->rotation.z, sizeof(float), 1, fp); fwrite(&joint->rotation.z, sizeof(float), 1, fp);
} }
// joints to vertices mapping chunk // joints to vertices mapping chunk
fputs("JTV", fp); fputs("JTV", fp);
long numMappings = numVertices; long numMappings = numVertices;
long sizeOfJointMappings = (sizeof(int) + sizeof(float)) * numMappings + sizeof(long); long sizeOfJointMappings = (sizeof(int) + sizeof(float)) * numMappings + sizeof(long);
fwrite(&sizeOfJointMappings, sizeof(long), 1, fp); fwrite(&sizeOfJointMappings, sizeof(long), 1, fp);
fwrite(&numMappings, sizeof(long), 1, fp); fwrite(&numMappings, sizeof(long), 1, fp);
for (long i = 0; i < numMappings; ++i) for (long i = 0; i < numMappings; ++i)
{ {
Ms3dVertex *vertex = &m_vertices[i]; Ms3dVertex *vertex = &m_vertices[i];
int jointIndex = vertex->jointIndex; int jointIndex = vertex->jointIndex;
fwrite(&jointIndex, sizeof(int), 1, fp); fwrite(&jointIndex, sizeof(int), 1, fp);
float weight = 1.0f; float weight = 1.0f;
fwrite(&weight, sizeof(float), 1, fp); fwrite(&weight, sizeof(float), 1, fp);
} }
// joint animation keyframes // joint animation keyframes
fputs("JKF", fp); fputs("JKF", fp);
long numFrames = m_numFrames; long numFrames = m_numFrames;
long sizeOfJointFrames = ((6 * sizeof(float)) * m_numJoints) * numFrames + sizeof(long); long sizeOfJointFrames = ((6 * sizeof(float)) * m_numJoints) * numFrames + sizeof(long);
fwrite(&sizeOfJointFrames, sizeof(long), 1, fp); fwrite(&sizeOfJointFrames, sizeof(long), 1, fp);
fwrite(&numFrames, sizeof(long), 1, fp); fwrite(&numFrames, sizeof(long), 1, fp);
for (long i = 0; i < numFrames; ++i) for (long i = 0; i < numFrames; ++i)
{ {
for (int j = 0; j < m_numJoints; ++j) for (int j = 0; j < m_numJoints; ++j)
{ {
Ms3dJoint *joint = &m_joints[j]; Ms3dJoint *joint = &m_joints[j];
Ms3dKeyFrame *position; Ms3dKeyFrame *position;
Ms3dKeyFrame *rotation; Ms3dKeyFrame *rotation;
if (i >= joint->numTranslationFrames) if (i >= joint->numTranslationFrames)
position = &joint->translationFrames[0]; position = &joint->translationFrames[0];
else else
position = &joint->translationFrames[i]; position = &joint->translationFrames[i];
if (i >= joint->numRotationFrames) if (i >= joint->numRotationFrames)
rotation = &joint->rotationFrames[0]; rotation = &joint->rotationFrames[0];
else else
rotation = &joint->rotationFrames[i]; rotation = &joint->rotationFrames[i];
fwrite(&position->param.x, sizeof(float), 1, fp); fwrite(&position->param.x, sizeof(float), 1, fp);
fwrite(&position->param.y, sizeof(float), 1, fp); fwrite(&position->param.y, sizeof(float), 1, fp);
fwrite(&position->param.z, sizeof(float), 1, fp); fwrite(&position->param.z, sizeof(float), 1, fp);
fwrite(&rotation->param.x, sizeof(float), 1, fp); fwrite(&rotation->param.x, sizeof(float), 1, fp);
fwrite(&rotation->param.y, sizeof(float), 1, fp); fwrite(&rotation->param.y, sizeof(float), 1, fp);
fwrite(&rotation->param.z, sizeof(float), 1, fp); fwrite(&rotation->param.z, sizeof(float), 1, fp);
} }
} }
if (m_animations.size() > 0) if (m_animations.size() > 0)
{ {
// figure out the size of all the animation name strings // figure out the size of all the animation name strings
long sizeofNames = 0; long sizeofNames = 0;
for (int i = 0; i < m_animations.size(); ++i) for (int i = 0; i < m_animations.size(); ++i)
sizeofNames += m_animations[i].name.length() + 1; sizeofNames += m_animations[i].name.length() + 1;
// animations chunk // animations chunk
fputs("ANI", fp); fputs("ANI", fp);
long numAnimations = m_animations.size(); long numAnimations = m_animations.size();
long sizeofAnimations = (sizeof(long) * 2) * numAnimations + sizeofNames + sizeof(long); long sizeofAnimations = (sizeof(long) * 2) * numAnimations + sizeofNames + sizeof(long);
fwrite(&sizeofAnimations, sizeof(long), 1, fp); fwrite(&sizeofAnimations, sizeof(long), 1, fp);
fwrite(&numAnimations, sizeof(long), 1, fp); fwrite(&numAnimations, sizeof(long), 1, fp);
for (long i = 0; i < numAnimations; ++i) for (long i = 0; i < numAnimations; ++i)
{ {
long data; long data;
const Ms3dAnimation *animation = &m_animations[i]; const Ms3dAnimation *animation = &m_animations[i];
//fputs(animation->name.c_str(), fp); //fputs(animation->name.c_str(), fp);
fputs(animation->name.c_str(), fp); fputs(animation->name.c_str(), fp);
fwrite("\0", 1, 1, fp); fwrite("\0", 1, 1, fp);
data = animation->startFrame; data = animation->startFrame;
fwrite(&data, sizeof(long), 1, fp); fwrite(&data, sizeof(long), 1, fp);
data = animation->endFrame; data = animation->endFrame;
fwrite(&data, sizeof(long), 1, fp); fwrite(&data, sizeof(long), 1, fp);
} }
} }
fclose(fp); fclose(fp);
return true; return true;
} }
int Ms3d::FindIndexOfJoint(const std::string &jointName) int Ms3d::FindIndexOfJoint(const std::string &jointName)
{ {
if (jointName.length() == 0) if (jointName.length() == 0)
return -1; return -1;
for (int i = 0; i < m_numJoints; ++i) for (int i = 0; i < m_numJoints; ++i)
{ {
Ms3dJoint *joint = &m_joints[i]; Ms3dJoint *joint = &m_joints[i];
if (joint->name == jointName) if (joint->name == jointName)
return i; return i;
} }
return -1; return -1;
} }

View file

@ -1,146 +1,146 @@
#ifndef __MS3D_H_INCLUDED__ #ifndef __MS3D_H_INCLUDED__
#define __MS3D_H_INCLUDED__ #define __MS3D_H_INCLUDED__
#include <string> #include <string>
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include "../geometry/vector2.h" #include "../geometry/vector2.h"
#include <vector> #include <vector>
struct Ms3dHeader struct Ms3dHeader
{ {
char id[10]; char id[10];
long version; long version;
}; };
struct Ms3dVertex struct Ms3dVertex
{ {
unsigned char editorFlags; unsigned char editorFlags;
Vector3 vertex; Vector3 vertex;
char jointIndex; char jointIndex;
unsigned char unused; unsigned char unused;
}; };
struct Ms3dTriangle struct Ms3dTriangle
{ {
unsigned short editorFlags; unsigned short editorFlags;
unsigned short vertices[3]; unsigned short vertices[3];
Vector3 normals[3]; Vector3 normals[3];
Vector2 texCoords[3]; Vector2 texCoords[3];
unsigned char smoothingGroup; unsigned char smoothingGroup;
unsigned char meshIndex; unsigned char meshIndex;
}; };
struct Ms3dMesh struct Ms3dMesh
{ {
unsigned char editorFlags; unsigned char editorFlags;
std::string name; std::string name;
unsigned short numTriangles; unsigned short numTriangles;
unsigned short *triangles; unsigned short *triangles;
char materialIndex; char materialIndex;
Ms3dMesh() Ms3dMesh()
{ {
triangles = NULL; triangles = NULL;
} }
~Ms3dMesh() ~Ms3dMesh()
{ {
delete[] triangles; delete[] triangles;
} }
}; };
struct Ms3dMaterial struct Ms3dMaterial
{ {
std::string name; std::string name;
float ambient[4]; float ambient[4];
float diffuse[4]; float diffuse[4];
float specular[4]; float specular[4];
float emissive[4]; float emissive[4];
float shininess; float shininess;
float transparency; float transparency;
char mode; char mode;
std::string texture; std::string texture;
std::string alpha; std::string alpha;
}; };
struct Ms3dKeyFrame struct Ms3dKeyFrame
{ {
float time; float time;
Vector3 param; Vector3 param;
}; };
struct Ms3dJoint struct Ms3dJoint
{ {
unsigned char editorFlags; unsigned char editorFlags;
std::string name; std::string name;
std::string parentName; std::string parentName;
Vector3 rotation; Vector3 rotation;
Vector3 position; Vector3 position;
unsigned short numRotationFrames; unsigned short numRotationFrames;
unsigned short numTranslationFrames; unsigned short numTranslationFrames;
Ms3dKeyFrame *rotationFrames; Ms3dKeyFrame *rotationFrames;
Ms3dKeyFrame *translationFrames; Ms3dKeyFrame *translationFrames;
Ms3dJoint() Ms3dJoint()
{ {
rotationFrames = NULL; rotationFrames = NULL;
translationFrames = NULL; translationFrames = NULL;
} }
~Ms3dJoint() ~Ms3dJoint()
{ {
delete[] rotationFrames; delete[] rotationFrames;
delete[] translationFrames; delete[] translationFrames;
} }
}; };
struct Ms3dAnimation struct Ms3dAnimation
{ {
std::string name; std::string name;
unsigned int startFrame; unsigned int startFrame;
unsigned int endFrame; unsigned int endFrame;
}; };
class Ms3d class Ms3d
{ {
public: public:
Ms3d(); Ms3d();
virtual ~Ms3d() { Release(); } virtual ~Ms3d() { Release(); }
void Release(); void Release();
bool Load(const std::string &file); bool Load(const std::string &file);
bool ConvertToMesh(const std::string &file); bool ConvertToMesh(const std::string &file);
unsigned short GetNumVertices() { return m_numVertices; } unsigned short GetNumVertices() { return m_numVertices; }
unsigned short GetNumTriangles() { return m_numTriangles; } unsigned short GetNumTriangles() { return m_numTriangles; }
unsigned short GetNumMeshes() { return m_numMeshes; } unsigned short GetNumMeshes() { return m_numMeshes; }
unsigned short GetNumMaterials() { return m_numMaterials; } unsigned short GetNumMaterials() { return m_numMaterials; }
unsigned short GetNumJoints() { return m_numJoints; } unsigned short GetNumJoints() { return m_numJoints; }
float GetAnimationFps() { return m_animationFps; } float GetAnimationFps() { return m_animationFps; }
int GetNumFrames() { return m_numFrames; } int GetNumFrames() { return m_numFrames; }
Ms3dVertex* GetVertices() { return m_vertices; } Ms3dVertex* GetVertices() { return m_vertices; }
Ms3dTriangle* GetTriangles() { return m_triangles; } Ms3dTriangle* GetTriangles() { return m_triangles; }
Ms3dMesh* GetMeshes() { return m_meshes; } Ms3dMesh* GetMeshes() { return m_meshes; }
Ms3dMaterial* GetMaterials() { return m_materials; } Ms3dMaterial* GetMaterials() { return m_materials; }
Ms3dJoint* GetJoints() { return m_joints; } Ms3dJoint* GetJoints() { return m_joints; }
private: private:
int FindIndexOfJoint(const std::string &jointName); int FindIndexOfJoint(const std::string &jointName);
unsigned short m_numVertices; unsigned short m_numVertices;
unsigned short m_numTriangles; unsigned short m_numTriangles;
unsigned short m_numMeshes; unsigned short m_numMeshes;
unsigned short m_numMaterials; unsigned short m_numMaterials;
unsigned short m_numJoints; unsigned short m_numJoints;
float m_animationFps; float m_animationFps;
float m_editorAnimationTime; float m_editorAnimationTime;
int m_numFrames; int m_numFrames;
Ms3dVertex *m_vertices; Ms3dVertex *m_vertices;
Ms3dTriangle *m_triangles; Ms3dTriangle *m_triangles;
Ms3dMesh *m_meshes; Ms3dMesh *m_meshes;
Ms3dMaterial *m_materials; Ms3dMaterial *m_materials;
Ms3dJoint *m_joints; Ms3dJoint *m_joints;
std::vector<Ms3dAnimation> m_animations; std::vector<Ms3dAnimation> m_animations;
}; };
#endif #endif

View file

@ -1,496 +1,496 @@
#include "obj.h" #include "obj.h"
#include <stdio.h> #include <stdio.h>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
Obj::Obj() Obj::Obj()
{ {
m_vertices = NULL; m_vertices = NULL;
m_normals = NULL; m_normals = NULL;
m_texCoords = NULL; m_texCoords = NULL;
m_materials = NULL; m_materials = NULL;
m_numVertices = 0; m_numVertices = 0;
m_numNormals = 0; m_numNormals = 0;
m_numTexCoords = 0; m_numTexCoords = 0;
m_numMaterials = 0; m_numMaterials = 0;
} }
void Obj::Release() void Obj::Release()
{ {
delete[] m_vertices; delete[] m_vertices;
delete[] m_normals; delete[] m_normals;
delete[] m_texCoords; delete[] m_texCoords;
delete[] m_materials; delete[] m_materials;
m_vertices = NULL; m_vertices = NULL;
m_normals = NULL; m_normals = NULL;
m_texCoords = NULL; m_texCoords = NULL;
m_materials = NULL; m_materials = NULL;
m_numVertices = 0; m_numVertices = 0;
m_numNormals = 0; m_numNormals = 0;
m_numTexCoords = 0; m_numTexCoords = 0;
m_numMaterials = 0; m_numMaterials = 0;
} }
bool Obj::Load(const std::string &file, const std::string &texturePath) bool Obj::Load(const std::string &file, const std::string &texturePath)
{ {
std::ifstream input; std::ifstream input;
std::string line; std::string line;
std::string op; std::string op;
std::string path; std::string path;
std::string tempName; std::string tempName;
Vector3 vertex; Vector3 vertex;
Vector3 normal; Vector3 normal;
ObjMaterial *currentMaterial = NULL; ObjMaterial *currentMaterial = NULL;
int currentVertex = 0; int currentVertex = 0;
int currentNormal = 0; int currentNormal = 0;
int currentTexCoord = 0; int currentTexCoord = 0;
int numGroups = 0; int numGroups = 0;
// Get pathname from filename given (if present) // 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 // 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) if (file.find_last_of('/') != std::string::npos)
path = file.substr(0, file.find_last_of('/') + 1); path = file.substr(0, file.find_last_of('/') + 1);
if (!FindAndLoadMaterials(path, texturePath, file)) if (!FindAndLoadMaterials(path, texturePath, file))
return false; return false;
if (!GetDataSizes(file)) if (!GetDataSizes(file))
return false; return false;
input.open(file.c_str()); input.open(file.c_str());
if (input.fail()) if (input.fail())
return false; return false;
// Extract name of model from the filename given (basically, chop off the extension and path) // Extract name of model from the filename given (basically, chop off the extension and path)
//if (file.find_last_of('.') != std::string::npos) //if (file.find_last_of('.') != std::string::npos)
// model->name = file.substr(path.length(), file.find_last_of('.') - path.length()); // model->name = file.substr(path.length(), file.find_last_of('.') - path.length());
// Begin reading in model data // Begin reading in model data
while (!input.eof()) while (!input.eof())
{ {
if (numGroups > 1) if (numGroups > 1)
break; break;
std::getline(input, line, '\n'); std::getline(input, line, '\n');
op = line.substr(0, line.find(' ')); op = line.substr(0, line.find(' '));
// Comments // Comments
if (op == "#") if (op == "#")
{ {
} }
// Vertex // Vertex
else if (op == "v") else if (op == "v")
{ {
sscanf(line.c_str(), "v %f %f %f", &m_vertices[currentVertex].x, &m_vertices[currentVertex].y, &m_vertices[currentVertex].z); sscanf(line.c_str(), "v %f %f %f", &m_vertices[currentVertex].x, &m_vertices[currentVertex].y, &m_vertices[currentVertex].z);
++currentVertex; ++currentVertex;
} }
// Texture coordinate // Texture coordinate
else if (op == "vt") else if (op == "vt")
{ {
sscanf(line.c_str(), "vt %f %f", &m_texCoords[currentTexCoord].x, &m_texCoords[currentTexCoord].y); sscanf(line.c_str(), "vt %f %f", &m_texCoords[currentTexCoord].x, &m_texCoords[currentTexCoord].y);
m_texCoords[currentTexCoord].x = -m_texCoords[currentTexCoord].y; m_texCoords[currentTexCoord].x = -m_texCoords[currentTexCoord].y;
++currentTexCoord; ++currentTexCoord;
} }
// Vertex normal // Vertex normal
else if (op == "vn") else if (op == "vn")
{ {
sscanf(line.c_str(), "vn %f %f %f", &m_normals[currentNormal].x, &m_normals[currentNormal].y, &m_normals[currentNormal].z); sscanf(line.c_str(), "vn %f %f %f", &m_normals[currentNormal].x, &m_normals[currentNormal].y, &m_normals[currentNormal].z);
++currentNormal; ++currentNormal;
} }
// Face definition // Face definition
else if (op == "f") else if (op == "f")
{ {
ParseFaceDefinition(line, currentMaterial); ParseFaceDefinition(line, currentMaterial);
} }
// Group name // Group name
else if (op == "g") else if (op == "g")
{ {
++numGroups; ++numGroups;
} }
// Object name // Object name
else if (op == "o") else if (op == "o")
{ {
} }
// Material // Material
else if (op == "usemtl") else if (op == "usemtl")
{ {
tempName = line.substr(line.find(' ') + 1); tempName = line.substr(line.find(' ') + 1);
currentMaterial = NULL; currentMaterial = NULL;
// Find the named material and set it as current // Find the named material and set it as current
for (unsigned int i = 0; i < m_numMaterials; ++i) for (unsigned int i = 0; i < m_numMaterials; ++i)
{ {
if (m_materials[i].name == tempName) if (m_materials[i].name == tempName)
{ {
currentMaterial = &m_materials[i]; currentMaterial = &m_materials[i];
break; break;
} }
} }
//ASSERT(currentMaterial != NULL); //ASSERT(currentMaterial != NULL);
} }
// Material file // Material file
else if (op == "mtllib") else if (op == "mtllib")
{ {
// Already would have been loaded // Already would have been loaded
} }
} }
input.close(); input.close();
return true; return true;
} }
void Obj::ParseFaceDefinition(const std::string &faceDefinition, ObjMaterial *currentMaterial) void Obj::ParseFaceDefinition(const std::string &faceDefinition, ObjMaterial *currentMaterial)
{ {
static int numFaceVertices = 0; static int numFaceVertices = 0;
static OBJ_FACE_VERTEX_TYPE vertexType; static OBJ_FACE_VERTEX_TYPE vertexType;
std::string def; std::string def;
int pos; int pos;
int n = 0; 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) // 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; pos = faceDefinition.find(' ') + 1;
def = faceDefinition.substr(pos); def = faceDefinition.substr(pos);
// Few different face formats, and variable amount of vertices per face possible // 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) // How many vertices are there in this face definition? (only calc this once)
// Also calc the vertex format // Also calc the vertex format
if (!numFaceVertices) if (!numFaceVertices)
{ {
pos = 0; pos = 0;
while (def.length() > 0 && def[def.length() - 1] == ' ') while (def.length() > 0 && def[def.length() - 1] == ' ')
def = def.substr(0, def.length() - 1); def = def.substr(0, def.length() - 1);
//ASSERT(def.length() > 0); //ASSERT(def.length() > 0);
while (pos != std::string::npos) while (pos != std::string::npos)
{ {
++pos; ++pos;
++numFaceVertices; ++numFaceVertices;
pos = def.find(' ', pos); pos = def.find(' ', pos);
} }
std::string tempVertex = def.substr(0, def.find(' ')); std::string tempVertex = def.substr(0, def.find(' '));
if (tempVertex.find("//") != std::string::npos) if (tempVertex.find("//") != std::string::npos)
vertexType = OBJ_VERTEX_NORMAL; vertexType = OBJ_VERTEX_NORMAL;
else else
{ {
pos = 0; pos = 0;
while (pos != std::string::npos) while (pos != std::string::npos)
{ {
++pos; ++pos;
++n; ++n;
pos = tempVertex.find('/', pos); pos = tempVertex.find('/', pos);
} }
if (n == 1) if (n == 1)
vertexType = OBJ_VERTEX_TEXCOORD; vertexType = OBJ_VERTEX_TEXCOORD;
else else
vertexType = OBJ_VERTEX_FULL; vertexType = OBJ_VERTEX_FULL;
} }
} }
// Parse out vertices in this face // Parse out vertices in this face
// We also store only triangles. Since OBJ file face definitions can have any number // 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 // of vertices per face, we need to split it up into triangles here for easy rendering
// This is done as follows: // This is done as follows:
// - first 3 vertices = first triangle for face // - first 3 vertices = first triangle for face
// - for each additional 1 vertex, take the first vertex read for this face + the previously // - 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 // read vertex for this face and combine to make a new triangle
std::istringstream parser; std::istringstream parser;
std::string currentVertex; std::string currentVertex;
int thisVertex[3]; int thisVertex[3];
int firstVertex[3]; int firstVertex[3];
int lastReadVertex[3]; int lastReadVertex[3];
int thisTriangle[3][3]; int thisTriangle[3][3];
ObjFace face; ObjFace face;
memset(&firstVertex, 0, sizeof(int) * 3); memset(&firstVertex, 0, sizeof(int) * 3);
memset(&lastReadVertex, 0, sizeof(int) * 3); memset(&lastReadVertex, 0, sizeof(int) * 3);
memset(&thisTriangle, 0, sizeof(int) * (3 * 3)); memset(&thisTriangle, 0, sizeof(int) * (3 * 3));
parser.clear(); parser.clear();
parser.str(def); parser.str(def);
for (int i = 0; i < numFaceVertices; ++i) for (int i = 0; i < numFaceVertices; ++i)
{ {
// Get current vertex for this face // Get current vertex for this face
parser >> currentVertex; parser >> currentVertex;
// Add vertex/texcoord/normal indexes to the data arrays // Add vertex/texcoord/normal indexes to the data arrays
// (OBJ file indexes are NOT zero based. We fix that here) // (OBJ file indexes are NOT zero based. We fix that here)
memset(&thisVertex, 0, sizeof(int) * 3); memset(&thisVertex, 0, sizeof(int) * 3);
switch (vertexType) switch (vertexType)
{ {
case OBJ_VERTEX_FULL: // v/vt/vn case OBJ_VERTEX_FULL: // v/vt/vn
sscanf(currentVertex.c_str(), "%d/%d/%d", &thisVertex[0], &thisVertex[1], &thisVertex[2]); sscanf(currentVertex.c_str(), "%d/%d/%d", &thisVertex[0], &thisVertex[1], &thisVertex[2]);
break; break;
case OBJ_VERTEX_NORMAL: // v//vn case OBJ_VERTEX_NORMAL: // v//vn
sscanf(currentVertex.c_str(), "%d//%d", &thisVertex[0], &thisVertex[2]); sscanf(currentVertex.c_str(), "%d//%d", &thisVertex[0], &thisVertex[2]);
break; break;
case OBJ_VERTEX_TEXCOORD: // v/vt case OBJ_VERTEX_TEXCOORD: // v/vt
sscanf(currentVertex.c_str(), "%d/%d", &thisVertex[0]); sscanf(currentVertex.c_str(), "%d/%d", &thisVertex[0]);
break; break;
} }
// Save the first vertex read for a face // Save the first vertex read for a face
if (i == 0) if (i == 0)
memcpy(&firstVertex, &thisVertex, sizeof(int) * 3); memcpy(&firstVertex, &thisVertex, sizeof(int) * 3);
// First 3 vertices simply form a triangle // First 3 vertices simply form a triangle
if (i <= 2) if (i <= 2)
{ {
face.vertices[i] = thisVertex[0] - 1; face.vertices[i] = thisVertex[0] - 1;
face.texcoords[i] = thisVertex[1] - 1; face.texcoords[i] = thisVertex[1] - 1;
face.normals[i] = thisVertex[2] - 1; face.normals[i] = thisVertex[2] - 1;
} }
// Store the first triangle // Store the first triangle
if (i == 2) if (i == 2)
{ {
//ASSERT(currentMaterial != NULL); //ASSERT(currentMaterial != NULL);
currentMaterial->faces[currentMaterial->lastFaceIndex] = face; currentMaterial->faces[currentMaterial->lastFaceIndex] = face;
++currentMaterial->lastFaceIndex; ++currentMaterial->lastFaceIndex;
} }
// Combine vertices to form additional triangles // Combine vertices to form additional triangles
if (i > 2) if (i > 2)
{ {
//ASSERT(currentMaterial != NULL); //ASSERT(currentMaterial != NULL);
face.vertices[0] = firstVertex[0] - 1; face.texcoords[0] = firstVertex[1] - 1; face.normals[0] = firstVertex[2] - 1; 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[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; face.vertices[2] = thisVertex[0] - 1; face.texcoords[2] = thisVertex[1] - 1; face.normals[2] = thisVertex[2] - 1;
currentMaterial->faces[currentMaterial->lastFaceIndex] = face; currentMaterial->faces[currentMaterial->lastFaceIndex] = face;
++currentMaterial->lastFaceIndex; ++currentMaterial->lastFaceIndex;
} }
// Save as "previously read vertex" // Save as "previously read vertex"
memcpy(&lastReadVertex, &thisVertex, sizeof(int) * 3); memcpy(&lastReadVertex, &thisVertex, sizeof(int) * 3);
} }
} }
bool Obj::GetDataSizes(const std::string &file) bool Obj::GetDataSizes(const std::string &file)
{ {
std::ifstream input; std::ifstream input;
std::string line; std::string line;
std::string op; std::string op;
int countVertices = 0; int countVertices = 0;
int countNormals = 0; int countNormals = 0;
int countTexCoords = 0; int countTexCoords = 0;
int numGroups = 0; int numGroups = 0;
std::string useMtlName; std::string useMtlName;
ObjMaterial *currentMaterial; ObjMaterial *currentMaterial;
input.open(file.c_str()); input.open(file.c_str());
if (input.fail()) if (input.fail())
return false; return false;
while (!input.eof()) while (!input.eof())
{ {
if (numGroups > 1) if (numGroups > 1)
break; break;
std::getline(input, line, '\n'); std::getline(input, line, '\n');
op = line.substr(0, line.find(' ')); op = line.substr(0, line.find(' '));
if (op == "g") if (op == "g")
++numGroups; ++numGroups;
else if (op == "v") else if (op == "v")
++countVertices; ++countVertices;
else if (op == "vt") else if (op == "vt")
++countTexCoords; ++countTexCoords;
else if (op == "vn") else if (op == "vn")
++countNormals; ++countNormals;
else if (op == "f") 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") // 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; ++currentMaterial->numFaces;
else if (op == "usemtl") else if (op == "usemtl")
{ {
std::string useMtlName = line.substr(line.find(' ') + 1); std::string useMtlName = line.substr(line.find(' ') + 1);
currentMaterial = NULL; currentMaterial = NULL;
// Find the named material and set it as current // Find the named material and set it as current
for (unsigned int i = 0; i < m_numMaterials; ++i) for (unsigned int i = 0; i < m_numMaterials; ++i)
{ {
if (m_materials[i].name == useMtlName) if (m_materials[i].name == useMtlName)
{ {
currentMaterial = &m_materials[i]; currentMaterial = &m_materials[i];
break; break;
} }
} }
//ASSERT(currentMaterial != NULL); //ASSERT(currentMaterial != NULL);
} }
} }
input.close(); input.close();
m_numVertices = countVertices; m_numVertices = countVertices;
m_numTexCoords = countTexCoords; m_numTexCoords = countTexCoords;
m_numNormals = countNormals; m_numNormals = countNormals;
m_vertices = new Vector3[m_numVertices]; m_vertices = new Vector3[m_numVertices];
m_texCoords = new Vector2[m_numTexCoords]; m_texCoords = new Vector2[m_numTexCoords];
m_normals = new Vector3[m_numNormals]; m_normals = new Vector3[m_numNormals];
for (unsigned int i = 0; i < m_numMaterials; ++i) for (unsigned int i = 0; i < m_numMaterials; ++i)
{ {
m_materials[i].faces = new ObjFace[m_materials[i].numFaces]; m_materials[i].faces = new ObjFace[m_materials[i].numFaces];
} }
return true; return true;
} }
bool Obj::LoadMaterialLibrary(const std::string &file, const std::string &texturePath) bool Obj::LoadMaterialLibrary(const std::string &file, const std::string &texturePath)
{ {
std::ifstream input; std::ifstream input;
std::string line; std::string line;
std::string op; std::string op;
int currentMaterial = -1; int currentMaterial = -1;
float r, g, b; float r, g, b;
if (!CountDefinedMaterials(file)) if (!CountDefinedMaterials(file))
return false; return false;
m_materials = new ObjMaterial[m_numMaterials]; m_materials = new ObjMaterial[m_numMaterials];
input.open(file.c_str()); input.open(file.c_str());
if (input.fail()) if (input.fail())
return false; return false;
while (!input.eof()) while (!input.eof())
{ {
std::getline(input, line, '\n'); std::getline(input, line, '\n');
op = line.substr(0, line.find(' ')); op = line.substr(0, line.find(' '));
// New material definition (possibility of multiple per .mtl file) // New material definition (possibility of multiple per .mtl file)
if (op == "newmtl") if (op == "newmtl")
{ {
++currentMaterial; ++currentMaterial;
m_materials[currentMaterial].name = line.substr(op.length() + 1); m_materials[currentMaterial].name = line.substr(op.length() + 1);
} }
// Ambient color // Ambient color
else if (op == "Ka") else if (op == "Ka")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
sscanf(line.c_str(), "Ka %f %f %f", &r, &g, &b); sscanf(line.c_str(), "Ka %f %f %f", &r, &g, &b);
m_materials[currentMaterial].material->SetAmbient(RGB_24_f(r, g, b)); m_materials[currentMaterial].material->SetAmbient(RGB_24_f(r, g, b));
} }
// Diffuse color // Diffuse color
else if (op == "Kd") else if (op == "Kd")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
sscanf(line.c_str(), "Kd %f %f %f", &r, &g, &b); sscanf(line.c_str(), "Kd %f %f %f", &r, &g, &b);
m_materials[currentMaterial].material->SetDiffuse(RGB_24_f(r, g, b)); m_materials[currentMaterial].material->SetDiffuse(RGB_24_f(r, g, b));
} }
// Specular color // Specular color
else if (op == "Ks") else if (op == "Ks")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
sscanf(line.c_str(), "Ks %f %f %f", &r, &g, &b); sscanf(line.c_str(), "Ks %f %f %f", &r, &g, &b);
m_materials[currentMaterial].material->SetSpecular(RGB_24_f(r, g, b)); m_materials[currentMaterial].material->SetSpecular(RGB_24_f(r, g, b));
} }
// Alpha value // Alpha value
else if (op == "d" || op == "Tr") else if (op == "d" || op == "Tr")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
} }
// Shininess // Shininess
else if (op == "Ns") else if (op == "Ns")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
} }
// Illumination model // Illumination model
else if (op == "illum") else if (op == "illum")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
} }
// Texture // Texture
else if (op == "map_Ka" || op == "map_Kd") else if (op == "map_Ka" || op == "map_Kd")
{ {
//ASSERT(currentMaterial >= 0); //ASSERT(currentMaterial >= 0);
m_materials[currentMaterial].material->SetTexture(texturePath + line.substr(op.length() + 1)); m_materials[currentMaterial].material->SetTexture(texturePath + line.substr(op.length() + 1));
} }
} }
input.close(); input.close();
return true; return true;
} }
bool Obj::CountDefinedMaterials(const std::string &file) bool Obj::CountDefinedMaterials(const std::string &file)
{ {
std::ifstream input; std::ifstream input;
std::string line; std::string line;
std::string op; std::string op;
int count = 0; int count = 0;
input.open(file.c_str()); input.open(file.c_str());
if (input.fail()) if (input.fail())
return false; return false;
while (!input.eof()) while (!input.eof())
{ {
std::getline(input, line, '\n'); std::getline(input, line, '\n');
op = line.substr(0, line.find(' ')); op = line.substr(0, line.find(' '));
if (op == "newmtl") if (op == "newmtl")
++m_numMaterials; ++m_numMaterials;
} }
input.close(); input.close();
return true; return true;
} }
bool Obj::FindAndLoadMaterials(const std::string &materialPath, const std::string &texturePath, const std::string &file) bool Obj::FindAndLoadMaterials(const std::string &materialPath, const std::string &texturePath, const std::string &file)
{ {
std::ifstream input; std::ifstream input;
std::string line; std::string line;
std::string op; std::string op;
input.open(file.c_str()); input.open(file.c_str());
if (input.fail()) if (input.fail())
return false; return false;
while (!input.eof()) while (!input.eof())
{ {
std::getline(input, line, '\n'); std::getline(input, line, '\n');
op = line.substr(0, line.find(' ')); op = line.substr(0, line.find(' '));
if (op == "mtllib") if (op == "mtllib")
{ {
LoadMaterialLibrary(materialPath + line.substr(line.find(' ') + 1), texturePath); LoadMaterialLibrary(materialPath + line.substr(line.find(' ') + 1), texturePath);
break; break;
} }
} }
input.close(); input.close();
return true; return true;
} }
bool Obj::ConvertToMesh(const std::string &file) bool Obj::ConvertToMesh(const std::string &file)
{ {
return false; return false;
} }

View file

@ -1,84 +1,84 @@
#ifndef __OBJ_H_INCLUDED__ #ifndef __OBJ_H_INCLUDED__
#define __OBJ_H_INCLUDED__ #define __OBJ_H_INCLUDED__
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include "../geometry/vector2.h" #include "../geometry/vector2.h"
#include "../assets/material.h" #include "../assets/material.h"
#include <string> #include <string>
typedef enum OBJ_FACE_VERTEX_TYPE typedef enum OBJ_FACE_VERTEX_TYPE
{ {
OBJ_VERTEX_TEXCOORD, OBJ_VERTEX_TEXCOORD,
OBJ_VERTEX_NORMAL, OBJ_VERTEX_NORMAL,
OBJ_VERTEX_FULL OBJ_VERTEX_FULL
}; };
typedef struct typedef struct
{ {
unsigned int vertices[3]; unsigned int vertices[3];
unsigned int texcoords[3]; unsigned int texcoords[3];
unsigned int normals[3]; unsigned int normals[3];
} ObjFace; } ObjFace;
typedef struct ObjMaterial typedef struct ObjMaterial
{ {
std::string name; std::string name;
Material *material; Material *material;
ObjFace *faces; ObjFace *faces;
unsigned int numFaces; unsigned int numFaces;
unsigned int lastFaceIndex; unsigned int lastFaceIndex;
ObjMaterial() ObjMaterial()
{ {
material = new Material(); material = new Material();
faces = NULL; faces = NULL;
numFaces = 0; numFaces = 0;
lastFaceIndex = 0; lastFaceIndex = 0;
} }
~ObjMaterial() ~ObjMaterial()
{ {
delete material; delete material;
delete[] faces; delete[] faces;
} }
} ObjMaterial; } ObjMaterial;
class Obj class Obj
{ {
public: public:
Obj(); Obj();
virtual ~Obj() { Release(); } virtual ~Obj() { Release(); }
void Release(); void Release();
bool Load(const std::string &file, const std::string &texturePath); bool Load(const std::string &file, const std::string &texturePath);
bool ConvertToMesh(const std::string &file); bool ConvertToMesh(const std::string &file);
int GetNumVertices() { return m_numVertices; } int GetNumVertices() { return m_numVertices; }
int GetNumNormals() { return m_numNormals; } int GetNumNormals() { return m_numNormals; }
int GetNumTexCoords() { return m_numTexCoords; } int GetNumTexCoords() { return m_numTexCoords; }
int GetNumMaterials() { return m_numMaterials; } int GetNumMaterials() { return m_numMaterials; }
Vector3* GetVertices() { return m_vertices; } Vector3* GetVertices() { return m_vertices; }
Vector3* GetNormals() { return m_normals; } Vector3* GetNormals() { return m_normals; }
Vector2* GetTexCoords() { return m_texCoords; } Vector2* GetTexCoords() { return m_texCoords; }
ObjMaterial* GetMaterials() { return m_materials; } ObjMaterial* GetMaterials() { return m_materials; }
private: private:
bool GetDataSizes(const std::string &file); bool GetDataSizes(const std::string &file);
bool LoadMaterialLibrary(const std::string &file, const std::string &texturePath); bool LoadMaterialLibrary(const std::string &file, const std::string &texturePath);
bool CountDefinedMaterials(const std::string &file); bool CountDefinedMaterials(const std::string &file);
bool FindAndLoadMaterials(const std::string &materialPath, const std::string &texturePath, 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); void ParseFaceDefinition(const std::string &faceDefinition, ObjMaterial *currentMaterial);
Vector3 *m_vertices; Vector3 *m_vertices;
Vector3 *m_normals; Vector3 *m_normals;
Vector2 *m_texCoords; Vector2 *m_texCoords;
ObjMaterial *m_materials; ObjMaterial *m_materials;
unsigned int m_numVertices; unsigned int m_numVertices;
unsigned int m_numNormals; unsigned int m_numNormals;
unsigned int m_numTexCoords; unsigned int m_numTexCoords;
unsigned int m_numMaterials; unsigned int m_numMaterials;
}; };
#endif #endif

View file

@ -1,261 +1,261 @@
#include "sm.h" #include "sm.h"
#include <stdio.h> #include <stdio.h>
#include "../util/files.h" #include "../util/files.h"
#include "../chunks/chunks.h" #include "../chunks/chunks.h"
StaticModel::StaticModel() StaticModel::StaticModel()
{ {
m_numMaterials = 0; m_numMaterials = 0;
m_numPolygons = 0; m_numPolygons = 0;
m_numVertices = 0; m_numVertices = 0;
m_numNormals = 0; m_numNormals = 0;
m_numTexCoords = 0; m_numTexCoords = 0;
m_hasNormals = false; m_hasNormals = false;
m_hasTexCoords = false; m_hasTexCoords = false;
m_hasColors = false; m_hasColors = false;
m_materials = NULL; m_materials = NULL;
m_polygons = NULL; m_polygons = NULL;
m_texCoords = NULL; m_texCoords = NULL;
m_vertices = NULL; m_vertices = NULL;
m_normals = NULL; m_normals = NULL;
} }
void StaticModel::Release() void StaticModel::Release()
{ {
delete[] m_materials; delete[] m_materials;
delete[] m_polygons; delete[] m_polygons;
delete[] m_texCoords; delete[] m_texCoords;
delete[] m_vertices; delete[] m_vertices;
delete[] m_normals; delete[] m_normals;
} }
bool StaticModel::Load(const std::string &file) bool StaticModel::Load(const std::string &file)
{ {
FILE *fp; FILE *fp;
unsigned short numMaterials; unsigned short numMaterials;
unsigned int numPolys, numVertices, numNormals, numTexCoords; unsigned int numPolys, numVertices, numNormals, numTexCoords;
unsigned int ambient, diffuse, specular, emission; unsigned int ambient, diffuse, specular, emission;
unsigned int n; unsigned int n;
int currentMaterial; int currentMaterial;
int count; int count;
float x, y, z; float x, y, z;
unsigned char header[2]; unsigned char header[2];
unsigned char c; unsigned char c;
std::string texture; std::string texture;
fp = fopen(file.c_str(), "rb"); fp = fopen(file.c_str(), "rb");
if (!fp) if (!fp)
return false; return false;
// Simple file type validation // Simple file type validation
fread(&header[0], 2, 1, fp); fread(&header[0], 2, 1, fp);
if (header[0] != 'S' || header[1] != 'M') if (header[0] != 'S' || header[1] != 'M')
return false; return false;
fread(&numMaterials, 2, 1, fp); fread(&numMaterials, 2, 1, fp);
fread(&numPolys, 4, 1, fp); fread(&numPolys, 4, 1, fp);
fread(&numVertices, 4, 1, fp); fread(&numVertices, 4, 1, fp);
fread(&numNormals, 4, 1, fp); fread(&numNormals, 4, 1, fp);
fread(&numTexCoords, 4, 1, fp); fread(&numTexCoords, 4, 1, fp);
m_materials = new SmMaterial[numMaterials]; m_materials = new SmMaterial[numMaterials];
m_polygons = new SmPolygon[numPolys]; m_polygons = new SmPolygon[numPolys];
m_texCoords = new Vector2[numTexCoords]; m_texCoords = new Vector2[numTexCoords];
m_vertices = new Vector3[numVertices]; m_vertices = new Vector3[numVertices];
m_normals = new Vector3[numNormals]; m_normals = new Vector3[numNormals];
//ASSERT(m_materials != NULL); //ASSERT(m_materials != NULL);
//ASSERT(m_polygons != NULL); //ASSERT(m_polygons != NULL);
//ASSERT(m_texCoords != NULL); //ASSERT(m_texCoords != NULL);
//ASSERT(m_vertices != NULL); //ASSERT(m_vertices != NULL);
//ASSERT(m_normals != NULL); //ASSERT(m_normals != NULL);
m_numMaterials = numMaterials; m_numMaterials = numMaterials;
m_numPolygons = numPolys; m_numPolygons = numPolys;
m_numVertices = numVertices; m_numVertices = numVertices;
m_numNormals = numNormals; m_numNormals = numNormals;
m_numTexCoords = numTexCoords; m_numTexCoords = numTexCoords;
// Read in material definitions // Read in material definitions
for (int i = 0; i < m_numMaterials; ++i) for (int i = 0; i < m_numMaterials; ++i)
{ {
fread(&ambient, 4, 1, fp); fread(&ambient, 4, 1, fp);
fread(&diffuse, 4, 1, fp); fread(&diffuse, 4, 1, fp);
fread(&specular, 4, 1, fp); fread(&specular, 4, 1, fp);
fread(&emission, 4, 1, fp); fread(&emission, 4, 1, fp);
m_materials[i].material->ambient = Color::FromInt(ambient); m_materials[i].material->ambient = Color::FromInt(ambient);
m_materials[i].material->diffuse = Color::FromInt(diffuse); m_materials[i].material->diffuse = Color::FromInt(diffuse);
m_materials[i].material->specular = Color::FromInt(specular); m_materials[i].material->specular = Color::FromInt(specular);
m_materials[i].material->emissive = Color::FromInt(emission); m_materials[i].material->emissive = Color::FromInt(emission);
m_materials[i].material->shininess = 0.0f; m_materials[i].material->shininess = 0.0f;
m_materials[i].material->opacity = COLOR_ALPHA_OPAQUE; m_materials[i].material->opacity = COLOR_ALPHA_OPAQUE;
ReadString(fp, m_materials[i].material->name); ReadString(fp, m_materials[i].material->name);
} }
// Read in triangle definitions (all are indexes into raw data following) // Read in triangle definitions (all are indexes into raw data following)
currentMaterial = NO_MATERIAL; currentMaterial = NO_MATERIAL;
for (unsigned int i = 0; i < m_numPolygons; ++i) for (unsigned int i = 0; i < m_numPolygons; ++i)
{ {
// Vertices // Vertices
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fread(&n, 4, 1, fp); fread(&n, 4, 1, fp);
m_polygons[i].vertices[j] = n; m_polygons[i].vertices[j] = n;
} }
// Normals // Normals
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fread(&n, 4, 1, fp); fread(&n, 4, 1, fp);
m_polygons[i].normals[j] = n; m_polygons[i].normals[j] = n;
} }
// TexCoords // TexCoords
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fread(&n, 4, 1, fp); fread(&n, 4, 1, fp);
m_polygons[i].texcoords[j] = n; m_polygons[i].texcoords[j] = n;
} }
// Vertex colors // Vertex colors
for (int j = 0; j < 3; ++j) for (int j = 0; j < 3; ++j)
{ {
fread(&n, 2, 1, fp); fread(&n, 2, 1, fp);
m_polygons[i].colors[j] = n; m_polygons[i].colors[j] = n;
} }
// Material index // Material index
fread(&m_polygons[i].material, 2, 1, fp); fread(&m_polygons[i].material, 2, 1, fp);
// Record start/end indices for the different materials // Record start/end indices for the different materials
// This way rendering can be done per material while still only looping // This way rendering can be done per material while still only looping
// over all of this model's polygons once per frame // over all of this model's polygons once per frame
if (m_polygons[i].material != currentMaterial) if (m_polygons[i].material != currentMaterial)
{ {
if (currentMaterial > NO_MATERIAL) if (currentMaterial > NO_MATERIAL)
m_materials[currentMaterial].polyEnd = i; m_materials[currentMaterial].polyEnd = i;
currentMaterial = m_polygons[i].material; currentMaterial = m_polygons[i].material;
m_materials[currentMaterial].polyStart = i; m_materials[currentMaterial].polyStart = i;
} }
// If any of the normals, texcoords, or colors are non-zero, we need to flag that such // If any of the normals, texcoords, or colors are non-zero, we need to flag that such
// information exists in this model // information exists in this model
if (m_polygons[i].colors[0] != 0 || m_polygons[i].colors[1] != 0 || m_polygons[i].colors[2] != 0) if (m_polygons[i].colors[0] != 0 || m_polygons[i].colors[1] != 0 || m_polygons[i].colors[2] != 0)
m_hasColors = true; m_hasColors = true;
} }
// Will always include the last polygon due to the way the .SM exporter sorts // Will always include the last polygon due to the way the .SM exporter sorts
m_materials[currentMaterial].polyEnd = numPolys; m_materials[currentMaterial].polyEnd = numPolys;
// Vertices // Vertices
for (unsigned int i = 0; i < m_numVertices; ++i) for (unsigned int i = 0; i < m_numVertices; ++i)
{ {
fread(&x, 4, 1, fp); fread(&x, 4, 1, fp);
fread(&y, 4, 1, fp); fread(&y, 4, 1, fp);
fread(&z, 4, 1, fp); fread(&z, 4, 1, fp);
m_vertices[i].x = x / 2; m_vertices[i].x = x / 2;
m_vertices[i].y = y / 2; m_vertices[i].y = y / 2;
m_vertices[i].z = z / 2; m_vertices[i].z = z / 2;
} }
// Normals // Normals
for (unsigned int i = 0; i < m_numNormals; ++i) for (unsigned int i = 0; i < m_numNormals; ++i)
{ {
fread(&x, 4, 1, fp); fread(&x, 4, 1, fp);
fread(&y, 4, 1, fp); fread(&y, 4, 1, fp);
fread(&z, 4, 1, fp); fread(&z, 4, 1, fp);
//ASSERT(!((x >= 1.0f || x <= -1.0f) || //ASSERT(!((x >= 1.0f || x <= -1.0f) ||
// (y >= 1.0f || y <= -1.0f) || // (y >= 1.0f || y <= -1.0f) ||
// (z >= 1.0f || z <= -1.0f))); // (z >= 1.0f || z <= -1.0f)));
m_normals[i].x = x; m_normals[i].x = x;
m_normals[i].y = y; m_normals[i].y = y;
m_normals[i].z = z; m_normals[i].z = z;
if (m_normals[i].x != 0 || m_normals[i].y != 0 || m_normals[i].z != 0) if (m_normals[i].x != 0 || m_normals[i].y != 0 || m_normals[i].z != 0)
m_hasNormals = true; m_hasNormals = true;
} }
// Texture coordinates // Texture coordinates
for (unsigned int i = 0; i < m_numTexCoords; ++i) for (unsigned int i = 0; i < m_numTexCoords; ++i)
{ {
fread(&x, 4, 1, fp); fread(&x, 4, 1, fp);
fread(&y, 4, 1, fp); fread(&y, 4, 1, fp);
//ASSERT(!((x >= 2048.0f || x <= -2048.0f) || //ASSERT(!((x >= 2048.0f || x <= -2048.0f) ||
// (y >= 2048.0f || y <= -2048.0f))); // (y >= 2048.0f || y <= -2048.0f)));
// TODO: revisit this, seems a bit hack-ish and probably only correct // TODO: revisit this, seems a bit hack-ish and probably only correct
// for the shitty models I made // for the shitty models I made
m_texCoords[i].x = x; m_texCoords[i].x = x;
m_texCoords[i].y = -y; m_texCoords[i].y = -y;
if (m_texCoords[i].x != 0 || m_texCoords[i].y != 0) if (m_texCoords[i].x != 0 || m_texCoords[i].y != 0)
m_hasTexCoords = true; m_hasTexCoords = true;
} }
fclose(fp); fclose(fp);
return true; return true;
} }
bool StaticModel::ConvertToMesh(const std::string &file) bool StaticModel::ConvertToMesh(const std::string &file)
{ {
FILE *fp = fopen(file.c_str(), "wb"); FILE *fp = fopen(file.c_str(), "wb");
if (fp == NULL) if (fp == NULL)
return false; return false;
WriteFileHeader(fp); WriteFileHeader(fp);
VerticesChunk *verticesChunk = new VerticesChunk(); VerticesChunk *verticesChunk = new VerticesChunk();
for (long i = 0; i < m_numVertices; ++i) for (long i = 0; i < m_numVertices; ++i)
verticesChunk->vertices.push_back(m_vertices[i]); verticesChunk->vertices.push_back(m_vertices[i]);
WriteChunk(verticesChunk, fp); WriteChunk(verticesChunk, fp);
SAFE_DELETE(verticesChunk); SAFE_DELETE(verticesChunk);
NormalsChunk *normalsChunk = new NormalsChunk(); NormalsChunk *normalsChunk = new NormalsChunk();
for (long i = 0; i < m_numNormals; ++i) for (long i = 0; i < m_numNormals; ++i)
normalsChunk->normals.push_back(m_normals[i]); normalsChunk->normals.push_back(m_normals[i]);
WriteChunk(normalsChunk, fp); WriteChunk(normalsChunk, fp);
SAFE_DELETE(normalsChunk); SAFE_DELETE(normalsChunk);
TexCoordsChunk *texCoordsChunk = new TexCoordsChunk(); TexCoordsChunk *texCoordsChunk = new TexCoordsChunk();
for (long i = 0; i < m_numTexCoords; ++i) for (long i = 0; i < m_numTexCoords; ++i)
texCoordsChunk->texCoords.push_back(m_texCoords[i]); texCoordsChunk->texCoords.push_back(m_texCoords[i]);
WriteChunk(texCoordsChunk, fp); WriteChunk(texCoordsChunk, fp);
SAFE_DELETE(texCoordsChunk); SAFE_DELETE(texCoordsChunk);
MaterialsChunk *materialsChunk = new MaterialsChunk(); MaterialsChunk *materialsChunk = new MaterialsChunk();
for (long i = 0; i < m_numMaterials; ++i) for (long i = 0; i < m_numMaterials; ++i)
materialsChunk->materials.push_back(*m_materials[i].material); materialsChunk->materials.push_back(*m_materials[i].material);
WriteChunk(materialsChunk, fp); WriteChunk(materialsChunk, fp);
SAFE_DELETE(materialsChunk); SAFE_DELETE(materialsChunk);
TrianglesChunk *trianglesChunk = new TrianglesChunk(); TrianglesChunk *trianglesChunk = new TrianglesChunk();
for (long i = 0; i < m_numPolygons; ++i) for (long i = 0; i < m_numPolygons; ++i)
{ {
Triangle t; Triangle t;
t.vertices[0] = m_polygons[i].vertices[0]; t.vertices[0] = m_polygons[i].vertices[0];
t.vertices[1] = m_polygons[i].vertices[1]; t.vertices[1] = m_polygons[i].vertices[1];
t.vertices[2] = m_polygons[i].vertices[2]; t.vertices[2] = m_polygons[i].vertices[2];
t.normals[0] = m_polygons[i].normals[0]; t.normals[0] = m_polygons[i].normals[0];
t.normals[1] = m_polygons[i].normals[1]; t.normals[1] = m_polygons[i].normals[1];
t.normals[2] = m_polygons[i].normals[2]; t.normals[2] = m_polygons[i].normals[2];
t.texCoords[0] = m_polygons[i].texcoords[0]; t.texCoords[0] = m_polygons[i].texcoords[0];
t.texCoords[1] = m_polygons[i].texcoords[1]; t.texCoords[1] = m_polygons[i].texcoords[1];
t.texCoords[2] = m_polygons[i].texcoords[2]; t.texCoords[2] = m_polygons[i].texcoords[2];
t.materialIndex = m_polygons[i].material; t.materialIndex = m_polygons[i].material;
trianglesChunk->triangles.push_back(t); trianglesChunk->triangles.push_back(t);
} }
WriteChunk(trianglesChunk, fp); WriteChunk(trianglesChunk, fp);
fclose(fp); fclose(fp);
return true; return true;
} }

View file

@ -1,73 +1,73 @@
#ifndef __SM_H_INCLUDED__ #ifndef __SM_H_INCLUDED__
#define __SM_H_INCLUDED__ #define __SM_H_INCLUDED__
#include "../assets/material.h" #include "../assets/material.h"
#include "../geometry/vector3.h" #include "../geometry/vector3.h"
#include "../geometry/vector2.h" #include "../geometry/vector2.h"
#include <string> #include <string>
typedef struct typedef struct
{ {
unsigned int vertices[3]; unsigned int vertices[3];
unsigned int normals[3]; unsigned int normals[3];
unsigned int texcoords[3]; unsigned int texcoords[3];
unsigned short colors[3]; unsigned short colors[3];
short material; short material;
} SmPolygon; } SmPolygon;
typedef struct SmMaterial typedef struct SmMaterial
{ {
Material *material; Material *material;
unsigned int polyStart; unsigned int polyStart;
unsigned int polyEnd; unsigned int polyEnd;
SmMaterial() SmMaterial()
{ {
material = new Material(); material = new Material();
polyStart = 0; polyStart = 0;
polyEnd = 0; polyEnd = 0;
}; };
~SmMaterial() ~SmMaterial()
{ {
delete material; delete material;
} }
} SmMaterial; } SmMaterial;
#define NO_MATERIAL -1 #define NO_MATERIAL -1
class StaticModel class StaticModel
{ {
public: public:
StaticModel(); StaticModel();
virtual ~StaticModel() { Release(); } virtual ~StaticModel() { Release(); }
void Release(); void Release();
bool Load(const std::string &file); bool Load(const std::string &file);
bool ConvertToMesh(const std::string &file); bool ConvertToMesh(const std::string &file);
SmMaterial* GetMaterial(unsigned short index) { return &m_materials[index]; } SmMaterial* GetMaterial(unsigned short index) { return &m_materials[index]; }
SmPolygon* GetPolygon(unsigned int index) { return &m_polygons[index]; } SmPolygon* GetPolygon(unsigned int index) { return &m_polygons[index]; }
Vector3* GetVertex(unsigned int index) { return &m_vertices[index]; } Vector3* GetVertex(unsigned int index) { return &m_vertices[index]; }
unsigned int GetNumMaterials() { return (unsigned int)m_numMaterials; } unsigned int GetNumMaterials() { return (unsigned int)m_numMaterials; }
unsigned int GetNumPolygons() { return m_numPolygons; } unsigned int GetNumPolygons() { return m_numPolygons; }
unsigned int GetNumVertices() { return m_numVertices; } unsigned int GetNumVertices() { return m_numVertices; }
private: private:
SmMaterial *m_materials; SmMaterial *m_materials;
SmPolygon *m_polygons; SmPolygon *m_polygons;
Vector3 *m_vertices; Vector3 *m_vertices;
Vector3 *m_normals; Vector3 *m_normals;
Vector2 *m_texCoords; Vector2 *m_texCoords;
int m_numMaterials; int m_numMaterials;
unsigned int m_numPolygons; unsigned int m_numPolygons;
unsigned int m_numVertices; unsigned int m_numVertices;
unsigned int m_numNormals; unsigned int m_numNormals;
unsigned int m_numTexCoords; unsigned int m_numTexCoords;
bool m_hasNormals; bool m_hasNormals;
bool m_hasTexCoords; bool m_hasTexCoords;
bool m_hasColors; bool m_hasColors;
}; };
#endif #endif

View file

@ -1,25 +1,25 @@
#include "files.h" #include "files.h"
void ReadString(FILE *fp, std::string &buffer, int fixedLength) void ReadString(FILE *fp, std::string &buffer, int fixedLength)
{ {
char c; char c;
if (fixedLength > 0) if (fixedLength > 0)
{ {
for (int i = 0; i < fixedLength; ++i) for (int i = 0; i < fixedLength; ++i)
{ {
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
if (c != '\0') if (c != '\0')
buffer += c; buffer += c;
} }
} }
else else
{ {
do do
{ {
fread(&c, 1, 1, fp); fread(&c, 1, 1, fp);
if (c != '\0') if (c != '\0')
buffer += c; buffer += c;
} while (c != '\0'); } while (c != '\0');
} }
} }

View file

@ -1,9 +1,9 @@
#ifndef __UTIL_FILES_H_INCLUDED__ #ifndef __UTIL_FILES_H_INCLUDED__
#define __UTIL_FILES_H_INCLUDED__ #define __UTIL_FILES_H_INCLUDED__
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
void ReadString(FILE *fp, std::string &buffer, int fixedLength = 0); void ReadString(FILE *fp, std::string &buffer, int fixedLength = 0);
#endif #endif