Fix CRLF
This commit is contained in:
parent
978f2aa08e
commit
87a60137f1
18
.gitignore
vendored
18
.gitignore
vendored
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
*.sdf
|
*.sdf
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.user
|
*.user
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
ipch/
|
ipch/
|
||||||
|
|
||||||
*.suo
|
*.suo
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in a new issue