Browse Source

Normalize line endings

seanpaultaylor 12 years ago
parent
commit
eb7026d191
53 changed files with 9435 additions and 9435 deletions
  1. 357 357
      samples/racer/sample-racer.vcxproj
  2. 128 128
      samples/racer/sample-racer.vcxproj.filters
  3. 26 26
      samples/racer/sample-racer.vcxproj.user
  4. 651 651
      samples/racer/src/RacerGame.cpp
  5. 138 138
      samples/racer/src/RacerGame.h
  6. 305 305
      samples/spaceship/.cproject
  7. 78 78
      samples/spaceship/.project
  8. 101 101
      samples/spaceship/android/build.xml
  9. 44 44
      samples/spaceship/bar-descriptor.xml
  10. 7 7
      samples/spaceship/game.config
  11. 364 364
      samples/spaceship/sample-spaceship.vcxproj
  12. 103 103
      samples/spaceship/sample-spaceship.vcxproj.filters
  13. 26 26
      samples/spaceship/sample-spaceship.vcxproj.user
  14. 547 547
      samples/spaceship/src/SpaceshipGame.cpp
  15. 152 152
      samples/spaceship/src/SpaceshipGame.h
  16. 95 95
      template/android/template.build.xml
  17. 6 6
      template/game.config
  18. 84 84
      template/template.bar-descriptor.xml
  19. 87 87
      template/template.project
  20. 342 342
      template/template.vcxproj
  21. 26 26
      template/template.vcxproj.user
  22. 44 44
      tools/encoder/README.md
  23. 233 233
      tools/encoder/gameplay-bundle.txt
  24. 20 20
      tools/encoder/gameplay-encoder.sln
  25. 305 305
      tools/encoder/gameplay-encoder.vcxproj.filters
  26. 18 18
      tools/encoder/gameplay-encoder.vcxproj.user
  27. 74 74
      tools/encoder/src/Animation.cpp
  28. 66 66
      tools/encoder/src/Animation.h
  29. 248 248
      tools/encoder/src/AnimationChannel.cpp
  30. 102 102
      tools/encoder/src/AnimationChannel.h
  31. 70 70
      tools/encoder/src/Animations.cpp
  32. 44 44
      tools/encoder/src/Animations.h
  33. 25 25
      tools/encoder/src/Base.cpp
  34. 146 146
      tools/encoder/src/BoundingVolume.cpp
  35. 57 57
      tools/encoder/src/BoundingVolume.h
  36. 126 126
      tools/encoder/src/Camera.cpp
  37. 59 59
      tools/encoder/src/Camera.h
  38. 31 31
      tools/encoder/src/Constants.cpp
  39. 33 33
      tools/encoder/src/Constants.h
  40. 1346 1346
      tools/encoder/src/Curve.cpp
  41. 483 483
      tools/encoder/src/Curve.h
  42. 40 40
      tools/encoder/src/Effect.cpp
  43. 39 39
      tools/encoder/src/Effect.h
  44. 225 225
      tools/encoder/src/EncoderArguments.h
  45. 295 295
      tools/encoder/src/FBXSceneEncoder.h
  46. 805 805
      tools/encoder/src/FBXUtil.cpp
  47. 203 203
      tools/encoder/src/FBXUtil.h
  48. 208 208
      tools/encoder/src/FileIO.cpp
  49. 155 155
      tools/encoder/src/FileIO.h
  50. 52 52
      tools/encoder/src/Font.cpp
  51. 56 56
      tools/encoder/src/Font.h
  52. 118 118
      tools/encoder/src/GPBDecoder.cpp
  53. 42 42
      tools/encoder/src/GPBDecoder.h

+ 357 - 357
samples/racer/sample-racer.vcxproj

@@ -1,358 +1,358 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugMem|Win32">
-      <Configuration>DebugMem</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugMem|x64">
-      <Configuration>DebugMem</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{82522888-E09A-ED48-AD7D-247237B37B3A}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>sample-racer</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <CustomBuildBeforeTargets />
-    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-copy ..\..\gameplay\res\logo_powered_white.png res
-copy .\game.dxt.config .\game.config</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <ShowIncludes>false</ShowIncludes>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-copy ..\..\gameplay\res\logo_powered_white.png res
-copy .\game.dxt.config .\game.config</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <ShowIncludes>false</ShowIncludes>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-copy ..\..\gameplay\res\logo_powered_white.png res
-copy .\game.dxt.config .\game.config</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
-      <Message>Copying game.config...</Message>
-      <Outputs>game.config.dummy</Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <None Include="bar-descriptor.xml">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="icon.png" />
-    <None Include="res\common\background_track.ogg" />
-    <None Include="res\common\engine_loop.ogg" />
-    <None Include="res\common\gamepad.form" />
-    <None Include="res\common\gamepad.theme" />
-    <None Include="res\common\menu.form" />
-    <None Include="res\common\menu.theme" />
-    <None Include="res\common\overlay.form" />
-    <None Include="res\common\racer.gpb" />
-    <None Include="res\common\racer.lua" />
-    <None Include="res\common\racer.material" />
-    <None Include="res\common\racer.physics" />
-    <None Include="res\common\racer.scene" />
-    <None Include="res\shaders\colored.frag" />
-    <None Include="res\shaders\colored.vert" />
-    <None Include="res\shaders\font.frag" />
-    <None Include="res\shaders\font.vert" />
-    <None Include="res\shaders\form.frag" />
-    <None Include="res\shaders\form.vert" />
-    <None Include="res\shaders\lighting.frag" />
-    <None Include="res\shaders\lighting.vert" />
-    <None Include="res\shaders\skinning-none.vert" />
-    <None Include="res\shaders\skinning.vert" />
-    <None Include="res\shaders\sprite.frag" />
-    <None Include="res\shaders\sprite.vert" />
-    <None Include="res\shaders\terrain.frag" />
-    <None Include="res\shaders\terrain.vert" />
-    <None Include="res\shaders\textured.frag" />
-    <None Include="res\shaders\textured.vert" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\RacerGame.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\RacerGame.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <Image Include="res\common\heightmap-combinedmap_0.png" />
-    <Image Include="res\common\menu.png" />
-    <Image Include="res\logo_powered_white.png" />
-  </ItemGroup>
-  <ItemGroup>
-    <Media Include="res\common\braking.wav" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugMem|Win32">
+      <Configuration>DebugMem</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|x64">
+      <Configuration>DebugMem</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{82522888-E09A-ED48-AD7D-247237B37B3A}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>sample-racer</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <CustomBuildBeforeTargets />
+    <CustomBuildAfterTargets>Build</CustomBuildAfterTargets>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+copy ..\..\gameplay\res\logo_powered_white.png res
+copy .\game.dxt.config .\game.config</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;XInput.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ShowIncludes>false</ShowIncludes>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+copy ..\..\gameplay\res\logo_powered_white.png res
+copy .\game.dxt.config .\game.config</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ShowIncludes>false</ShowIncludes>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+copy ..\..\gameplay\res\logo_powered_white.png res
+copy .\game.dxt.config .\game.config</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy /Y "$(ProjectDir)game.dxt.config" "$(ProjectDir)game.config"</Command>
+      <Message>Copying game.config...</Message>
+      <Outputs>game.config.dummy</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="bar-descriptor.xml">
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="icon.png" />
+    <None Include="res\common\background_track.ogg" />
+    <None Include="res\common\engine_loop.ogg" />
+    <None Include="res\common\gamepad.form" />
+    <None Include="res\common\gamepad.theme" />
+    <None Include="res\common\menu.form" />
+    <None Include="res\common\menu.theme" />
+    <None Include="res\common\overlay.form" />
+    <None Include="res\common\racer.gpb" />
+    <None Include="res\common\racer.lua" />
+    <None Include="res\common\racer.material" />
+    <None Include="res\common\racer.physics" />
+    <None Include="res\common\racer.scene" />
+    <None Include="res\shaders\colored.frag" />
+    <None Include="res\shaders\colored.vert" />
+    <None Include="res\shaders\font.frag" />
+    <None Include="res\shaders\font.vert" />
+    <None Include="res\shaders\form.frag" />
+    <None Include="res\shaders\form.vert" />
+    <None Include="res\shaders\lighting.frag" />
+    <None Include="res\shaders\lighting.vert" />
+    <None Include="res\shaders\skinning-none.vert" />
+    <None Include="res\shaders\skinning.vert" />
+    <None Include="res\shaders\sprite.frag" />
+    <None Include="res\shaders\sprite.vert" />
+    <None Include="res\shaders\terrain.frag" />
+    <None Include="res\shaders\terrain.vert" />
+    <None Include="res\shaders\textured.frag" />
+    <None Include="res\shaders\textured.vert" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\RacerGame.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\RacerGame.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\common\heightmap-combinedmap_0.png" />
+    <Image Include="res\common\menu.png" />
+    <Image Include="res\logo_powered_white.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Media Include="res\common\braking.wav" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
 </Project>

+ 128 - 128
samples/racer/sample-racer.vcxproj.filters

@@ -1,129 +1,129 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="res">
-    </Filter>
-    <Filter Include="src">
-    </Filter>
-    <Filter Include="res\common">
-      <UniqueIdentifier>{175385aa-76bd-4390-961c-c7634597f147}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="res\shaders">
-      <UniqueIdentifier>{d2844a62-7159-4fa4-8401-95732ac8307a}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="icon.png" />
-    <None Include="bar-descriptor.xml" />
-    <None Include="res\shaders\colored.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\colored.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\font.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\font.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\form.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\form.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\lighting.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\lighting.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\skinning.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\skinning-none.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\sprite.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\sprite.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\terrain.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\terrain.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\textured.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\textured.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\common\background_track.ogg">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\engine_loop.ogg">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\gamepad.form">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\gamepad.theme">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\menu.form">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\menu.theme">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\overlay.form">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\racer.gpb">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\racer.lua">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\racer.material">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\racer.physics">
-      <Filter>res\common</Filter>
-    </None>
-    <None Include="res\common\racer.scene">
-      <Filter>res\common</Filter>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\RacerGame.h">
-      <Filter>src</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\RacerGame.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <Image Include="res\logo_powered_white.png">
-      <Filter>res</Filter>
-    </Image>
-    <Image Include="res\common\heightmap-combinedmap_0.png">
-      <Filter>res\common</Filter>
-    </Image>
-    <Image Include="res\common\menu.png">
-      <Filter>res\common</Filter>
-    </Image>
-  </ItemGroup>
-  <ItemGroup>
-    <Media Include="res\common\braking.wav">
-      <Filter>res\common</Filter>
-    </Media>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="res">
+    </Filter>
+    <Filter Include="src">
+    </Filter>
+    <Filter Include="res\common">
+      <UniqueIdentifier>{175385aa-76bd-4390-961c-c7634597f147}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="res\shaders">
+      <UniqueIdentifier>{d2844a62-7159-4fa4-8401-95732ac8307a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="icon.png" />
+    <None Include="bar-descriptor.xml" />
+    <None Include="res\shaders\colored.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\colored.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\font.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\font.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\form.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\form.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\lighting.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\lighting.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\skinning.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\skinning-none.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\sprite.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\sprite.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\terrain.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\terrain.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\textured.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\textured.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\common\background_track.ogg">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\engine_loop.ogg">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\gamepad.form">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\gamepad.theme">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\menu.form">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\menu.theme">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\overlay.form">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\racer.gpb">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\racer.lua">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\racer.material">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\racer.physics">
+      <Filter>res\common</Filter>
+    </None>
+    <None Include="res\common\racer.scene">
+      <Filter>res\common</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\RacerGame.h">
+      <Filter>src</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\RacerGame.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\logo_powered_white.png">
+      <Filter>res</Filter>
+    </Image>
+    <Image Include="res\common\heightmap-combinedmap_0.png">
+      <Filter>res\common</Filter>
+    </Image>
+    <Image Include="res\common\menu.png">
+      <Filter>res\common</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <Media Include="res\common\braking.wav">
+      <Filter>res\common</Filter>
+    </Media>
+  </ItemGroup>
 </Project>

+ 26 - 26
samples/racer/sample-racer.vcxproj.user

@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>

+ 651 - 651
samples/racer/src/RacerGame.cpp

@@ -1,651 +1,651 @@
-#include "RacerGame.h"
-
-// Render queue indexes (in order of drawing).
-enum RenderQueue
-{
-    QUEUE_OPAQUE = 0,
-    QUEUE_TRANSPARENT,
-    QUEUE_COUNT
-};
-
-bool __viewFrustumCulling = true;
-bool __flythruCamera = false;
-bool __drawDebug = false;
-bool __useAccelerometer = false;
-bool __showMenu = false;
-bool __menuFlag = false;
-
-// Declare our game instance
-RacerGame game;
-
-// Input bit-flags (powers of 2)
-#define ACCELERATOR (1 << 0)
-#define BRAKE (1 << 1)
-#define REVERSE (1 << 2)
-#define UPRIGHT (1 << 3)
-#define STEER_LEFT (1 << 4)
-#define STEER_RIGHT (1 << 5)
-#define ACCELERATOR_MOUSE (1 << 6)
-#define BRAKE_MOUSE (1 << 7)
-
-#define STEERING_RESPONSE (7.0f)
-
-RacerGame::RacerGame()
-    : _scene(NULL), _keyFlags(0), _mouseFlags(0), _steering(0), _gamepad(NULL), _carVehicle(NULL), _upsetTimer(0),
-      _backgroundSound(NULL), _engineSound(NULL), _brakingSound(NULL)
-{
-}
-
-void RacerGame::initialize()
-{
-    setMultiTouch(true);
-
-    _font = Font::create("res/ui/arial.gpb");
-
-    // Display the gameplay splash screen during loading, for at least 1 second.
-    displayScreen(this, &RacerGame::drawSplash, NULL, 1000L);
-
-    // Create the menu and start listening to its controls.
-    _menu = Form::create("res/common/menu.form");
-    _menu->setEnabled(false);
-    static_cast<Button*>(_menu->getControl("newGameButton"))->addListener(this, Listener::CLICK);
-    static_cast<Button*>(_menu->getControl("quitGameButton"))->addListener(this, Listener::CLICK);
-    static_cast<RadioButton*>(_menu->getControl("useGamepad"))->addListener(this, Listener::VALUE_CHANGED);
-    static_cast<RadioButton*>(_menu->getControl("useTilt"))->addListener(this, Listener::VALUE_CHANGED);
-    if (!canExit())
-    {
-        // Prevent a programmatic exit on platforms that don't allow it.
-        _menu->removeControl("quitGameButton");
-    }
-
-    // Create a pause button to display the menu
-    _overlay = Form::create("res/common/overlay.form");
-    static_cast<Button*>(_overlay->getControl("menuButton"))->addListener(this, Listener::CLICK);
-
-    // Load the scene
-    _scene = Scene::load("res/common/racer.scene");
-
-    // Set the aspect ratio for the scene's camera to match the current resolution
-    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
-
-    // Initialize scene
-    _scene->visit(this, &RacerGame::initializeScene);
-
-    // Load and initialize game script
-    getScriptController()->loadScript("res/common/racer.lua");
-    getScriptController()->executeFunction<void>("setScene", "<Scene>", _scene);
-
-    Node* carNode = _scene->findNode("carbody");
-    if (carNode && carNode->getCollisionObject()->getType() == PhysicsCollisionObject::VEHICLE)
-    {
-        _carVehicle = static_cast<PhysicsVehicle*>(carNode->getCollisionObject());
-        resetToStart();
-    }
-
-    // Create audio tracks
-    _backgroundSound = AudioSource::create("res/common/background_track.ogg");
-    if (_backgroundSound)
-    {
-        _backgroundSound->setLooped(true);
-        _backgroundSound->play();
-        _backgroundSound->setGain(0.3f);
-    }
-
-    _engineSound = AudioSource::create("res/common/engine_loop.ogg");
-    if (_engineSound)
-    {
-        _engineSound->setLooped(true);
-        _engineSound->play();
-        _engineSound->setGain(0.7f);
-    }
-
-    _brakingSound = AudioSource::create("res/common/braking.wav");
-    _brakingSound->setLooped(false);
-    _brakingSound->setGain(0.5f);
-
-    _gamepad = getGamepad(0);
-}
-
-bool RacerGame::initializeScene(Node* node)
-{
-    static Node* lightNode = _scene->findNode("directionalLight1");
-
-    Model* model = node->getModel();
-    if (model)
-    {
-        Material* material = model->getMaterial();
-
-        if (material && material->getTechnique()->getPassByIndex(0)->getEffect()->getUniform("u_directionalLightDirection"))
-        {
-            material->getParameter("u_ambientColor")->setValue(_scene->getAmbientColor());
-            material->getParameter("u_directionalLightColor[0]")->setValue(lightNode->getLight()->getColor());
-            material->getParameter("u_directionalLightDirection[0]")->setValue(lightNode->getForwardVectorView());
-        }
-    }
-
-    return true;
-}
-
-void RacerGame::finalize()
-{
-    SAFE_RELEASE(_backgroundSound);
-    SAFE_RELEASE(_engineSound);
-    SAFE_RELEASE(_brakingSound);
-    SAFE_RELEASE(_scene);
-    SAFE_RELEASE(_font);
-    SAFE_RELEASE(_menu);
-    SAFE_RELEASE(_overlay);
-}
-
-void RacerGame::update(float elapsedTime)
-{   
-    // The "Start" button is mapped to MENU2.
-    if (!__showMenu && !__menuFlag && _gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
-    {
-        __menuFlag = true;
-        menuEvent();
-    }
-
-    if (__menuFlag && !_gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
-    {
-        __menuFlag = false;
-    }
-
-    if (__showMenu && !__menuFlag && _gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
-    {
-        __menuFlag = true;
-        menuEvent();
-    }
-
-    Node* cameraNode;
-    if (_scene->getActiveCamera() && (cameraNode = _scene->getActiveCamera()->getNode()))
-    {
-        float dt = elapsedTime / 1000.0f;
-        float braking = 0;
-        float driving = 0;
-
-        if (_carVehicle)
-        {
-            float v = _carVehicle->getSpeedKph();
-            bool isVirt = _gamepad->isVirtual();
-
-            if (!__flythruCamera)
-            {
-                // Vehicle Control (Normal Mode)
-                Vector2 direction;
-                if (_gamepad->getJoystickCount())
-                {
-                    _gamepad->getJoystickValues(0, &direction);
-                }
-                
-                if (_gamepad->isButtonDown(Gamepad::BUTTON_LEFT))
-                {
-                    direction.set(-1.0f, 0.0f);
-                }
-                else if (_gamepad->isButtonDown(Gamepad::BUTTON_RIGHT))
-                {
-                    direction.set(1.0f, 0.0f);
-                }
-
-                // Allow keys to control steering
-                if (_keyFlags & STEER_LEFT)
-                {
-                    _steering += STEERING_RESPONSE * dt;
-                }
-                else if (_keyFlags & STEER_RIGHT)
-                {
-                    _steering -= STEERING_RESPONSE * dt;
-                }
-                else if (__useAccelerometer)
-                {
-                    float pitch, roll;
-                    Game::getAccelerometerValues(&pitch, &roll);
-
-                    _steering = -0.16 * roll;
-                }
-                else
-                {
-                    _steering = -direction.x;
-                }
-                _steering = max(-1.0f, min(_steering, 1.0f));
-
-                if (_gamepad->getTriggerCount() > 1)
-                {
-                    driving = _gamepad->getTriggerValue(1);
-                    _engineSound->setGain(0.8f + (driving * 0.2f));
-                }
-                
-                if (!driving && (_keyFlags & ACCELERATOR || _keyFlags & ACCELERATOR_MOUSE || _gamepad->isButtonDown(Gamepad::BUTTON_A)))
-                {
-                    driving = 1;
-                    _engineSound->setGain(1.0f);
-                }
-                else
-                {
-                    _engineSound->setGain(0.8f);
-                }
-                float s = _carVehicle->getSpeedSmoothKph() / 100.0f;
-                _engineSound->setPitch(max(0.2f, min(s, 2.0f)));
-
-                // Reverse only below a reasonable speed
-                bool isReverseCommanded = (_keyFlags & REVERSE) ||
-                                          (!isVirt && _gamepad->isButtonDown(Gamepad::BUTTON_X)) ||
-                                          (direction.y < -0.1 && _gamepad->isButtonDown(Gamepad::BUTTON_A));
-                if (isReverseCommanded && v < 30.0f)
-                {
-                    driving = -0.6f;
-                }
-
-                if ( (_keyFlags & BRAKE) || (_keyFlags & BRAKE_MOUSE) || _gamepad->isButtonDown(Gamepad::BUTTON_B))
-                {
-                    braking = 1;
-                    if (_brakingSound && (_brakingSound->getState() != AudioSource::PLAYING) && (v > 30.0f))
-                        _brakingSound->play();
-                }
-                else
-                {
-                    _brakingSound->stop();
-                }
-
-                // Make the camera follow the car
-                Node* carNode = _carVehicle->getNode();
-                Vector3 carPosition(carNode->getTranslation());
-                Vector3 commandedPosition(carPosition + Vector3::unitY()*4.0f - carNode->getBackVector()*10.0f);
-                cameraNode->translateSmooth(commandedPosition, dt, 0.2f);
-                Matrix m;
-                Matrix::createLookAt(cameraNode->getTranslation(), carPosition, Vector3::unitY(), &m);
-                m.transpose();
-                Quaternion q;
-                m.getRotation(&q);
-                cameraNode->setRotation(q);
-            }
-
-            // Slightly different steering gain based on gamepad type.
-            _carVehicle->setSteerdown( (isVirt ? 94.0f : 87.0f), (isVirt ? 0.15f : 0.22f) );
-            _carVehicle->update(elapsedTime, _steering, braking, driving);
-
-            // Auto-detect an upset car
-            if (fabs(v) < 10.0f && isUpset())
-            {
-                _upsetTimer += dt;
-            }
-            else
-            {
-                _upsetTimer = 0;
-            }
-
-            if (_upsetTimer > 3.0f)
-            {
-                _upsetTimer = 0;
-                resetInPlace();
-            }
-            else if ( (_keyFlags & UPRIGHT) ||
-                 (!isVirt && _gamepad->isButtonDown(Gamepad::BUTTON_Y)) ||
-                 (_carVehicle->getNode()->getTranslationY() < -300.0f) )
-            {
-                resetToStart();
-            }
-        }
-    }
-}
-
-bool RacerGame::isUpset() const
-{
-    GP_ASSERT(_carVehicle);
-
-    return _carVehicle->getNode()->getUpVector().y < 0.4f;
-}
-
-void RacerGame::render(float elapsedTime)
-{
-    // Clear the color and depth buffers
-    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
-
-    // Visit all the nodes in the scene to build our render queues
-    for (unsigned int i = 0; i < QUEUE_COUNT; ++i)
-        _renderQueues[i].clear();
-    _scene->visit(this, &RacerGame::buildRenderQueues);
-
-    // Draw the scene from our render queues
-    drawScene();
-
-    if (__drawDebug)
-    {
-        Game::getInstance()->getPhysicsController()->drawDebug(_scene->getActiveCamera()->getViewProjectionMatrix());
-    }
-
-    // Draw the gamepad
-    if (_gamepad && _gamepad->isVirtual())
-    	_gamepad->draw();
-
-    // Draw the menu
-    if (__showMenu)
-    {
-        _menu->draw();
-    }
-    
-    _overlay->draw();
-        
-    // Draw FPS and speed
-    int carSpeed = _carVehicle ? (int)_carVehicle->getSpeedKph() : 0;
-    _font->start();
-    char fps[32];
-    sprintf(fps, "%d", getFrameRate());
-    _font->drawText(fps, 5, 5, Vector4(0,0.5f,1,1), 20);
-    char kph[32];
-    sprintf(kph, "%d [km/h]", carSpeed);
-    _font->drawText(kph, getWidth() / 2 - 50, getHeight() - 60, Vector4(1,1,1,1), 40);
-    _font->finish();
-}
-
-bool RacerGame::buildRenderQueues(Node* node)
-{
-    Model* model = node->getModel(); 
-    if (model)
-    {
-        // Perform view-frustum culling for this node
-        if (__viewFrustumCulling && !node->getBoundingSphere().intersects(_scene->getActiveCamera()->getFrustum()))
-            return true;
-
-        // Determine which render queue to insert the node into
-        std::vector<Node*>* queue;
-        if (node->hasTag("transparent"))
-            queue = &_renderQueues[QUEUE_TRANSPARENT];
-        else
-            queue = &_renderQueues[QUEUE_OPAQUE];
-
-        queue->push_back(node);
-    }
-    return true;
-}
-
-void RacerGame::drawScene()
-{
-    // Iterate through each render queue and draw the nodes in them
-    for (unsigned int i = 0; i < QUEUE_COUNT; ++i)
-    {
-        std::vector<Node*>& queue = _renderQueues[i];
-
-        for (size_t j = 0, ncount = queue.size(); j < ncount; ++j)
-        {
-            queue[j]->getModel()->draw();
-        }
-    }
-}
-
-void RacerGame::drawSplash(void* param)
-{
-    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
-
-    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
-    batch->start();
-    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
-    batch->finish();
-    SAFE_DELETE(batch);
-}
-
-void RacerGame::keyEvent(Keyboard::KeyEvent evt, int key)
-{
-    if (evt == Keyboard::KEY_PRESS)
-    {
-        switch (key)
-        {
-        case Keyboard::KEY_ESCAPE:
-            menuEvent();
-            break;
-        case Keyboard::KEY_A:
-        case Keyboard::KEY_CAPITAL_A:
-        case Keyboard::KEY_LEFT_ARROW:
-            _keyFlags |= STEER_LEFT;
-            break;
-        case Keyboard::KEY_D:
-        case Keyboard::KEY_CAPITAL_D:
-        case Keyboard::KEY_RIGHT_ARROW:
-            _keyFlags |= STEER_RIGHT;
-            break;
-        case Keyboard::KEY_W:
-        case Keyboard::KEY_CAPITAL_W:
-        case Keyboard::KEY_UP_ARROW:
-            _keyFlags |= ACCELERATOR;
-            break;
-        case Keyboard::KEY_S:
-        case Keyboard::KEY_CAPITAL_S:
-        case Keyboard::KEY_DOWN_ARROW:
-            _keyFlags |= REVERSE;
-            break;
-        case Keyboard::KEY_SPACE:
-            _keyFlags |= BRAKE;
-            break;
-        case Keyboard::KEY_Y:
-        case Keyboard::KEY_CAPITAL_Y:
-            _keyFlags |= UPRIGHT;
-            break;
-        case Keyboard::KEY_V:
-            __viewFrustumCulling = !__viewFrustumCulling;
-            break;
-        case Keyboard::KEY_F:
-            __flythruCamera = !__flythruCamera;
-            getScriptController()->executeFunction<void>("toggleCamera");
-            break;
-        case Keyboard::KEY_B:
-            __drawDebug = !__drawDebug;
-            break;
-        case Keyboard::KEY_J:
-            __useAccelerometer = !__useAccelerometer;
-            break;
-        }
-    }
-    else if (evt == Keyboard::KEY_RELEASE)
-    {
-        switch (key)
-        {
-        case Keyboard::KEY_A:
-        case Keyboard::KEY_CAPITAL_A:
-        case Keyboard::KEY_LEFT_ARROW:
-            _keyFlags &= ~STEER_LEFT;
-            break;
-        case Keyboard::KEY_D:
-        case Keyboard::KEY_CAPITAL_D:
-        case Keyboard::KEY_RIGHT_ARROW:
-            _keyFlags &= ~STEER_RIGHT;
-            break;
-        case Keyboard::KEY_W:
-        case Keyboard::KEY_CAPITAL_W:
-        case Keyboard::KEY_UP_ARROW:
-            _keyFlags &= ~ACCELERATOR;
-            break;
-        case Keyboard::KEY_S:
-        case Keyboard::KEY_CAPITAL_S:
-        case Keyboard::KEY_DOWN_ARROW:
-            _keyFlags &= ~REVERSE;
-            break;
-        case Keyboard::KEY_SPACE:
-            _keyFlags &= ~BRAKE;
-            break;
-        case Keyboard::KEY_Y:
-        case Keyboard::KEY_CAPITAL_Y:
-            _keyFlags &= ~UPRIGHT;
-            break;
-        }
-    }
-}
-
-void RacerGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
-{
-    switch (evt)
-    {
-    case Touch::TOUCH_PRESS:
-        break;
-    case Touch::TOUCH_RELEASE:
-        break;
-    case Touch::TOUCH_MOVE:
-        break;
-    };
-}
-
-bool RacerGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
-{
-    bool consumed = false;
-
-    switch (evt)
-    {
-    case Mouse::MOUSE_PRESS_LEFT_BUTTON:
-        _keyFlags |= ACCELERATOR_MOUSE;
-        break;
-    case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
-        _keyFlags |= BRAKE_MOUSE;
-        break;
-    case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
-        _keyFlags &= ~ACCELERATOR_MOUSE;
-        break;
-    case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
-        _keyFlags &= ~BRAKE_MOUSE;
-        break;
-    }
-
-    return consumed;
-}
-
-void RacerGame::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
-{
-    // Prioritise physical gamepads over the virtual one.
-    switch(evt)
-    {
-    case Gamepad::CONNECTED_EVENT:
-        if (gamepad->isVirtual())
-        {
-            float from = 0.0f;
-            float to = getHeight();
-            Animation* virtualGamepadAnimation = gamepad->getForm()->createAnimationFromTo("gamepad_transition", Form::ANIMATE_POSITION_Y, &from, &to, Curve::LINEAR, 2000L);
-            _virtualGamepadClip = virtualGamepadAnimation->getClip();
-
-            _virtualGamepad = gamepad;
-        }
-        else
-        {
-            if (!_physicalGamepad)
-                _physicalGamepad = gamepad;
-        }
-
-        if (_physicalGamepad)
-        {
-        	if (_virtualGamepadClip && _gamepad == _virtualGamepad)
-            {
-        		_virtualGamepadClip->setSpeed(1.0f);
-                _virtualGamepadClip->play();
-            }
-            _gamepad = _physicalGamepad;
-			if (_virtualGamepad)
-			{
-				_virtualGamepad->getForm()->setEnabled(false);
-			}
-        }
-        else if (_virtualGamepad)
-        {
-            if (_gamepad == _physicalGamepad)
-            {
-        	    _virtualGamepadClip->setSpeed(-1.0f);
-                _virtualGamepadClip->play();
-            }
-            _gamepad = _virtualGamepad;
-            _virtualGamepad->getForm()->setEnabled(true);
-        }
-
-        break;
-    case Gamepad::DISCONNECTED_EVENT:
-        if (gamepad == _physicalGamepad)
-        {
-            _gamepad = _virtualGamepad;
-            _physicalGamepad = NULL;
-
-            _virtualGamepadClip->setSpeed(-1.0f);
-            _virtualGamepadClip->play();
-            _virtualGamepad->getForm()->setEnabled(true);
-        }
-        break;
-    }
-}
-
-void RacerGame::menuEvent()
-{
-    __showMenu = !__showMenu;
-
-    if (__showMenu)
-    {
-        static_cast<Button*>(_overlay->getControl("menuButton"))->setText("Resume");
-        pause();
-        _menu->setEnabled(true);
-        //_menu->setState(Control::FOCUS);
-    }
-    else
-    {
-        static_cast<Button*>(_overlay->getControl("menuButton"))->setText("Menu");
-        resume();
-        _menu->setEnabled(false);
-    }
-}
-
-void RacerGame::resetToStart()
-{
-    Vector3 pos(-258, 1, 278);
-    Quaternion rot(Vector3::unitY(), MATH_DEG_TO_RAD(143.201f));
-
-    reset(pos, rot);
-}
-
-void RacerGame::resetInPlace()
-{
-    Node* carNode = _carVehicle->getNode();
-
-    Vector3 pos;
-    carNode->getTranslation(&pos);
-    pos.y += 3.0f;
-
-    float angle = 0;
-    Vector3 v;
-    carNode->getForwardVector(&v);
-    if (v.x*v.x + v.z*v.z > 0)
-    {
-        angle += atan2(-v.x, -v.z);
-    }
-    Quaternion rot(Vector3::unitY(), angle);
-
-    reset(pos, rot);
-}
-
-void RacerGame::reset(const Vector3& pos, const Quaternion& rot)
-{
-    Node* carNode = _carVehicle->getNode();
-
-    _carVehicle->setEnabled(false);
-    carNode->setTranslation(pos);
-    carNode->setRotation(rot);
-    _carVehicle->reset();
-    _carVehicle->setEnabled(true);
-}
-
-void RacerGame::controlEvent(Control* control, EventType evt)
-{
-    if (strcmp(control->getId(), "newGameButton") == 0)
-    {
-        resetToStart();
-        // Close the menu and resume the game.
-        menuEvent();
-    }
-    else if (strcmp(control->getId(), "quitGameButton") == 0)
-    {
-        exit();
-    }
-    else if (strcmp(control->getId(), "useGamepad") == 0)
-    {
-        __useAccelerometer = false;
-    }
-    else if (strcmp(control->getId(), "useTilt") == 0)
-    {
-        __useAccelerometer = true;
-    }
-    else if (strcmp(control->getId(), "menuButton") == 0)
-    {
-        menuEvent();
-    }
-}
+#include "RacerGame.h"
+
+// Render queue indexes (in order of drawing).
+enum RenderQueue
+{
+    QUEUE_OPAQUE = 0,
+    QUEUE_TRANSPARENT,
+    QUEUE_COUNT
+};
+
+bool __viewFrustumCulling = true;
+bool __flythruCamera = false;
+bool __drawDebug = false;
+bool __useAccelerometer = false;
+bool __showMenu = false;
+bool __menuFlag = false;
+
+// Declare our game instance
+RacerGame game;
+
+// Input bit-flags (powers of 2)
+#define ACCELERATOR (1 << 0)
+#define BRAKE (1 << 1)
+#define REVERSE (1 << 2)
+#define UPRIGHT (1 << 3)
+#define STEER_LEFT (1 << 4)
+#define STEER_RIGHT (1 << 5)
+#define ACCELERATOR_MOUSE (1 << 6)
+#define BRAKE_MOUSE (1 << 7)
+
+#define STEERING_RESPONSE (7.0f)
+
+RacerGame::RacerGame()
+    : _scene(NULL), _keyFlags(0), _mouseFlags(0), _steering(0), _gamepad(NULL), _carVehicle(NULL), _upsetTimer(0),
+      _backgroundSound(NULL), _engineSound(NULL), _brakingSound(NULL)
+{
+}
+
+void RacerGame::initialize()
+{
+    setMultiTouch(true);
+
+    _font = Font::create("res/ui/arial.gpb");
+
+    // Display the gameplay splash screen during loading, for at least 1 second.
+    displayScreen(this, &RacerGame::drawSplash, NULL, 1000L);
+
+    // Create the menu and start listening to its controls.
+    _menu = Form::create("res/common/menu.form");
+    _menu->setEnabled(false);
+    static_cast<Button*>(_menu->getControl("newGameButton"))->addListener(this, Listener::CLICK);
+    static_cast<Button*>(_menu->getControl("quitGameButton"))->addListener(this, Listener::CLICK);
+    static_cast<RadioButton*>(_menu->getControl("useGamepad"))->addListener(this, Listener::VALUE_CHANGED);
+    static_cast<RadioButton*>(_menu->getControl("useTilt"))->addListener(this, Listener::VALUE_CHANGED);
+    if (!canExit())
+    {
+        // Prevent a programmatic exit on platforms that don't allow it.
+        _menu->removeControl("quitGameButton");
+    }
+
+    // Create a pause button to display the menu
+    _overlay = Form::create("res/common/overlay.form");
+    static_cast<Button*>(_overlay->getControl("menuButton"))->addListener(this, Listener::CLICK);
+
+    // Load the scene
+    _scene = Scene::load("res/common/racer.scene");
+
+    // Set the aspect ratio for the scene's camera to match the current resolution
+    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
+
+    // Initialize scene
+    _scene->visit(this, &RacerGame::initializeScene);
+
+    // Load and initialize game script
+    getScriptController()->loadScript("res/common/racer.lua");
+    getScriptController()->executeFunction<void>("setScene", "<Scene>", _scene);
+
+    Node* carNode = _scene->findNode("carbody");
+    if (carNode && carNode->getCollisionObject()->getType() == PhysicsCollisionObject::VEHICLE)
+    {
+        _carVehicle = static_cast<PhysicsVehicle*>(carNode->getCollisionObject());
+        resetToStart();
+    }
+
+    // Create audio tracks
+    _backgroundSound = AudioSource::create("res/common/background_track.ogg");
+    if (_backgroundSound)
+    {
+        _backgroundSound->setLooped(true);
+        _backgroundSound->play();
+        _backgroundSound->setGain(0.3f);
+    }
+
+    _engineSound = AudioSource::create("res/common/engine_loop.ogg");
+    if (_engineSound)
+    {
+        _engineSound->setLooped(true);
+        _engineSound->play();
+        _engineSound->setGain(0.7f);
+    }
+
+    _brakingSound = AudioSource::create("res/common/braking.wav");
+    _brakingSound->setLooped(false);
+    _brakingSound->setGain(0.5f);
+
+    _gamepad = getGamepad(0);
+}
+
+bool RacerGame::initializeScene(Node* node)
+{
+    static Node* lightNode = _scene->findNode("directionalLight1");
+
+    Model* model = node->getModel();
+    if (model)
+    {
+        Material* material = model->getMaterial();
+
+        if (material && material->getTechnique()->getPassByIndex(0)->getEffect()->getUniform("u_directionalLightDirection"))
+        {
+            material->getParameter("u_ambientColor")->setValue(_scene->getAmbientColor());
+            material->getParameter("u_directionalLightColor[0]")->setValue(lightNode->getLight()->getColor());
+            material->getParameter("u_directionalLightDirection[0]")->setValue(lightNode->getForwardVectorView());
+        }
+    }
+
+    return true;
+}
+
+void RacerGame::finalize()
+{
+    SAFE_RELEASE(_backgroundSound);
+    SAFE_RELEASE(_engineSound);
+    SAFE_RELEASE(_brakingSound);
+    SAFE_RELEASE(_scene);
+    SAFE_RELEASE(_font);
+    SAFE_RELEASE(_menu);
+    SAFE_RELEASE(_overlay);
+}
+
+void RacerGame::update(float elapsedTime)
+{   
+    // The "Start" button is mapped to MENU2.
+    if (!__showMenu && !__menuFlag && _gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
+    {
+        __menuFlag = true;
+        menuEvent();
+    }
+
+    if (__menuFlag && !_gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
+    {
+        __menuFlag = false;
+    }
+
+    if (__showMenu && !__menuFlag && _gamepad->isButtonDown(Gamepad::BUTTON_MENU2))
+    {
+        __menuFlag = true;
+        menuEvent();
+    }
+
+    Node* cameraNode;
+    if (_scene->getActiveCamera() && (cameraNode = _scene->getActiveCamera()->getNode()))
+    {
+        float dt = elapsedTime / 1000.0f;
+        float braking = 0;
+        float driving = 0;
+
+        if (_carVehicle)
+        {
+            float v = _carVehicle->getSpeedKph();
+            bool isVirt = _gamepad->isVirtual();
+
+            if (!__flythruCamera)
+            {
+                // Vehicle Control (Normal Mode)
+                Vector2 direction;
+                if (_gamepad->getJoystickCount())
+                {
+                    _gamepad->getJoystickValues(0, &direction);
+                }
+                
+                if (_gamepad->isButtonDown(Gamepad::BUTTON_LEFT))
+                {
+                    direction.set(-1.0f, 0.0f);
+                }
+                else if (_gamepad->isButtonDown(Gamepad::BUTTON_RIGHT))
+                {
+                    direction.set(1.0f, 0.0f);
+                }
+
+                // Allow keys to control steering
+                if (_keyFlags & STEER_LEFT)
+                {
+                    _steering += STEERING_RESPONSE * dt;
+                }
+                else if (_keyFlags & STEER_RIGHT)
+                {
+                    _steering -= STEERING_RESPONSE * dt;
+                }
+                else if (__useAccelerometer)
+                {
+                    float pitch, roll;
+                    Game::getAccelerometerValues(&pitch, &roll);
+
+                    _steering = -0.16 * roll;
+                }
+                else
+                {
+                    _steering = -direction.x;
+                }
+                _steering = max(-1.0f, min(_steering, 1.0f));
+
+                if (_gamepad->getTriggerCount() > 1)
+                {
+                    driving = _gamepad->getTriggerValue(1);
+                    _engineSound->setGain(0.8f + (driving * 0.2f));
+                }
+                
+                if (!driving && (_keyFlags & ACCELERATOR || _keyFlags & ACCELERATOR_MOUSE || _gamepad->isButtonDown(Gamepad::BUTTON_A)))
+                {
+                    driving = 1;
+                    _engineSound->setGain(1.0f);
+                }
+                else
+                {
+                    _engineSound->setGain(0.8f);
+                }
+                float s = _carVehicle->getSpeedSmoothKph() / 100.0f;
+                _engineSound->setPitch(max(0.2f, min(s, 2.0f)));
+
+                // Reverse only below a reasonable speed
+                bool isReverseCommanded = (_keyFlags & REVERSE) ||
+                                          (!isVirt && _gamepad->isButtonDown(Gamepad::BUTTON_X)) ||
+                                          (direction.y < -0.1 && _gamepad->isButtonDown(Gamepad::BUTTON_A));
+                if (isReverseCommanded && v < 30.0f)
+                {
+                    driving = -0.6f;
+                }
+
+                if ( (_keyFlags & BRAKE) || (_keyFlags & BRAKE_MOUSE) || _gamepad->isButtonDown(Gamepad::BUTTON_B))
+                {
+                    braking = 1;
+                    if (_brakingSound && (_brakingSound->getState() != AudioSource::PLAYING) && (v > 30.0f))
+                        _brakingSound->play();
+                }
+                else
+                {
+                    _brakingSound->stop();
+                }
+
+                // Make the camera follow the car
+                Node* carNode = _carVehicle->getNode();
+                Vector3 carPosition(carNode->getTranslation());
+                Vector3 commandedPosition(carPosition + Vector3::unitY()*4.0f - carNode->getBackVector()*10.0f);
+                cameraNode->translateSmooth(commandedPosition, dt, 0.2f);
+                Matrix m;
+                Matrix::createLookAt(cameraNode->getTranslation(), carPosition, Vector3::unitY(), &m);
+                m.transpose();
+                Quaternion q;
+                m.getRotation(&q);
+                cameraNode->setRotation(q);
+            }
+
+            // Slightly different steering gain based on gamepad type.
+            _carVehicle->setSteerdown( (isVirt ? 94.0f : 87.0f), (isVirt ? 0.15f : 0.22f) );
+            _carVehicle->update(elapsedTime, _steering, braking, driving);
+
+            // Auto-detect an upset car
+            if (fabs(v) < 10.0f && isUpset())
+            {
+                _upsetTimer += dt;
+            }
+            else
+            {
+                _upsetTimer = 0;
+            }
+
+            if (_upsetTimer > 3.0f)
+            {
+                _upsetTimer = 0;
+                resetInPlace();
+            }
+            else if ( (_keyFlags & UPRIGHT) ||
+                 (!isVirt && _gamepad->isButtonDown(Gamepad::BUTTON_Y)) ||
+                 (_carVehicle->getNode()->getTranslationY() < -300.0f) )
+            {
+                resetToStart();
+            }
+        }
+    }
+}
+
+bool RacerGame::isUpset() const
+{
+    GP_ASSERT(_carVehicle);
+
+    return _carVehicle->getNode()->getUpVector().y < 0.4f;
+}
+
+void RacerGame::render(float elapsedTime)
+{
+    // Clear the color and depth buffers
+    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
+
+    // Visit all the nodes in the scene to build our render queues
+    for (unsigned int i = 0; i < QUEUE_COUNT; ++i)
+        _renderQueues[i].clear();
+    _scene->visit(this, &RacerGame::buildRenderQueues);
+
+    // Draw the scene from our render queues
+    drawScene();
+
+    if (__drawDebug)
+    {
+        Game::getInstance()->getPhysicsController()->drawDebug(_scene->getActiveCamera()->getViewProjectionMatrix());
+    }
+
+    // Draw the gamepad
+    if (_gamepad && _gamepad->isVirtual())
+    	_gamepad->draw();
+
+    // Draw the menu
+    if (__showMenu)
+    {
+        _menu->draw();
+    }
+    
+    _overlay->draw();
+        
+    // Draw FPS and speed
+    int carSpeed = _carVehicle ? (int)_carVehicle->getSpeedKph() : 0;
+    _font->start();
+    char fps[32];
+    sprintf(fps, "%d", getFrameRate());
+    _font->drawText(fps, 5, 5, Vector4(0,0.5f,1,1), 20);
+    char kph[32];
+    sprintf(kph, "%d [km/h]", carSpeed);
+    _font->drawText(kph, getWidth() / 2 - 50, getHeight() - 60, Vector4(1,1,1,1), 40);
+    _font->finish();
+}
+
+bool RacerGame::buildRenderQueues(Node* node)
+{
+    Model* model = node->getModel(); 
+    if (model)
+    {
+        // Perform view-frustum culling for this node
+        if (__viewFrustumCulling && !node->getBoundingSphere().intersects(_scene->getActiveCamera()->getFrustum()))
+            return true;
+
+        // Determine which render queue to insert the node into
+        std::vector<Node*>* queue;
+        if (node->hasTag("transparent"))
+            queue = &_renderQueues[QUEUE_TRANSPARENT];
+        else
+            queue = &_renderQueues[QUEUE_OPAQUE];
+
+        queue->push_back(node);
+    }
+    return true;
+}
+
+void RacerGame::drawScene()
+{
+    // Iterate through each render queue and draw the nodes in them
+    for (unsigned int i = 0; i < QUEUE_COUNT; ++i)
+    {
+        std::vector<Node*>& queue = _renderQueues[i];
+
+        for (size_t j = 0, ncount = queue.size(); j < ncount; ++j)
+        {
+            queue[j]->getModel()->draw();
+        }
+    }
+}
+
+void RacerGame::drawSplash(void* param)
+{
+    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
+
+    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
+    batch->start();
+    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
+    batch->finish();
+    SAFE_DELETE(batch);
+}
+
+void RacerGame::keyEvent(Keyboard::KeyEvent evt, int key)
+{
+    if (evt == Keyboard::KEY_PRESS)
+    {
+        switch (key)
+        {
+        case Keyboard::KEY_ESCAPE:
+            menuEvent();
+            break;
+        case Keyboard::KEY_A:
+        case Keyboard::KEY_CAPITAL_A:
+        case Keyboard::KEY_LEFT_ARROW:
+            _keyFlags |= STEER_LEFT;
+            break;
+        case Keyboard::KEY_D:
+        case Keyboard::KEY_CAPITAL_D:
+        case Keyboard::KEY_RIGHT_ARROW:
+            _keyFlags |= STEER_RIGHT;
+            break;
+        case Keyboard::KEY_W:
+        case Keyboard::KEY_CAPITAL_W:
+        case Keyboard::KEY_UP_ARROW:
+            _keyFlags |= ACCELERATOR;
+            break;
+        case Keyboard::KEY_S:
+        case Keyboard::KEY_CAPITAL_S:
+        case Keyboard::KEY_DOWN_ARROW:
+            _keyFlags |= REVERSE;
+            break;
+        case Keyboard::KEY_SPACE:
+            _keyFlags |= BRAKE;
+            break;
+        case Keyboard::KEY_Y:
+        case Keyboard::KEY_CAPITAL_Y:
+            _keyFlags |= UPRIGHT;
+            break;
+        case Keyboard::KEY_V:
+            __viewFrustumCulling = !__viewFrustumCulling;
+            break;
+        case Keyboard::KEY_F:
+            __flythruCamera = !__flythruCamera;
+            getScriptController()->executeFunction<void>("toggleCamera");
+            break;
+        case Keyboard::KEY_B:
+            __drawDebug = !__drawDebug;
+            break;
+        case Keyboard::KEY_J:
+            __useAccelerometer = !__useAccelerometer;
+            break;
+        }
+    }
+    else if (evt == Keyboard::KEY_RELEASE)
+    {
+        switch (key)
+        {
+        case Keyboard::KEY_A:
+        case Keyboard::KEY_CAPITAL_A:
+        case Keyboard::KEY_LEFT_ARROW:
+            _keyFlags &= ~STEER_LEFT;
+            break;
+        case Keyboard::KEY_D:
+        case Keyboard::KEY_CAPITAL_D:
+        case Keyboard::KEY_RIGHT_ARROW:
+            _keyFlags &= ~STEER_RIGHT;
+            break;
+        case Keyboard::KEY_W:
+        case Keyboard::KEY_CAPITAL_W:
+        case Keyboard::KEY_UP_ARROW:
+            _keyFlags &= ~ACCELERATOR;
+            break;
+        case Keyboard::KEY_S:
+        case Keyboard::KEY_CAPITAL_S:
+        case Keyboard::KEY_DOWN_ARROW:
+            _keyFlags &= ~REVERSE;
+            break;
+        case Keyboard::KEY_SPACE:
+            _keyFlags &= ~BRAKE;
+            break;
+        case Keyboard::KEY_Y:
+        case Keyboard::KEY_CAPITAL_Y:
+            _keyFlags &= ~UPRIGHT;
+            break;
+        }
+    }
+}
+
+void RacerGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+{
+    switch (evt)
+    {
+    case Touch::TOUCH_PRESS:
+        break;
+    case Touch::TOUCH_RELEASE:
+        break;
+    case Touch::TOUCH_MOVE:
+        break;
+    };
+}
+
+bool RacerGame::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
+{
+    bool consumed = false;
+
+    switch (evt)
+    {
+    case Mouse::MOUSE_PRESS_LEFT_BUTTON:
+        _keyFlags |= ACCELERATOR_MOUSE;
+        break;
+    case Mouse::MOUSE_PRESS_RIGHT_BUTTON:
+        _keyFlags |= BRAKE_MOUSE;
+        break;
+    case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
+        _keyFlags &= ~ACCELERATOR_MOUSE;
+        break;
+    case Mouse::MOUSE_RELEASE_RIGHT_BUTTON:
+        _keyFlags &= ~BRAKE_MOUSE;
+        break;
+    }
+
+    return consumed;
+}
+
+void RacerGame::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
+{
+    // Prioritise physical gamepads over the virtual one.
+    switch(evt)
+    {
+    case Gamepad::CONNECTED_EVENT:
+        if (gamepad->isVirtual())
+        {
+            float from = 0.0f;
+            float to = getHeight();
+            Animation* virtualGamepadAnimation = gamepad->getForm()->createAnimationFromTo("gamepad_transition", Form::ANIMATE_POSITION_Y, &from, &to, Curve::LINEAR, 2000L);
+            _virtualGamepadClip = virtualGamepadAnimation->getClip();
+
+            _virtualGamepad = gamepad;
+        }
+        else
+        {
+            if (!_physicalGamepad)
+                _physicalGamepad = gamepad;
+        }
+
+        if (_physicalGamepad)
+        {
+        	if (_virtualGamepadClip && _gamepad == _virtualGamepad)
+            {
+        		_virtualGamepadClip->setSpeed(1.0f);
+                _virtualGamepadClip->play();
+            }
+            _gamepad = _physicalGamepad;
+			if (_virtualGamepad)
+			{
+				_virtualGamepad->getForm()->setEnabled(false);
+			}
+        }
+        else if (_virtualGamepad)
+        {
+            if (_gamepad == _physicalGamepad)
+            {
+        	    _virtualGamepadClip->setSpeed(-1.0f);
+                _virtualGamepadClip->play();
+            }
+            _gamepad = _virtualGamepad;
+            _virtualGamepad->getForm()->setEnabled(true);
+        }
+
+        break;
+    case Gamepad::DISCONNECTED_EVENT:
+        if (gamepad == _physicalGamepad)
+        {
+            _gamepad = _virtualGamepad;
+            _physicalGamepad = NULL;
+
+            _virtualGamepadClip->setSpeed(-1.0f);
+            _virtualGamepadClip->play();
+            _virtualGamepad->getForm()->setEnabled(true);
+        }
+        break;
+    }
+}
+
+void RacerGame::menuEvent()
+{
+    __showMenu = !__showMenu;
+
+    if (__showMenu)
+    {
+        static_cast<Button*>(_overlay->getControl("menuButton"))->setText("Resume");
+        pause();
+        _menu->setEnabled(true);
+        //_menu->setState(Control::FOCUS);
+    }
+    else
+    {
+        static_cast<Button*>(_overlay->getControl("menuButton"))->setText("Menu");
+        resume();
+        _menu->setEnabled(false);
+    }
+}
+
+void RacerGame::resetToStart()
+{
+    Vector3 pos(-258, 1, 278);
+    Quaternion rot(Vector3::unitY(), MATH_DEG_TO_RAD(143.201f));
+
+    reset(pos, rot);
+}
+
+void RacerGame::resetInPlace()
+{
+    Node* carNode = _carVehicle->getNode();
+
+    Vector3 pos;
+    carNode->getTranslation(&pos);
+    pos.y += 3.0f;
+
+    float angle = 0;
+    Vector3 v;
+    carNode->getForwardVector(&v);
+    if (v.x*v.x + v.z*v.z > 0)
+    {
+        angle += atan2(-v.x, -v.z);
+    }
+    Quaternion rot(Vector3::unitY(), angle);
+
+    reset(pos, rot);
+}
+
+void RacerGame::reset(const Vector3& pos, const Quaternion& rot)
+{
+    Node* carNode = _carVehicle->getNode();
+
+    _carVehicle->setEnabled(false);
+    carNode->setTranslation(pos);
+    carNode->setRotation(rot);
+    _carVehicle->reset();
+    _carVehicle->setEnabled(true);
+}
+
+void RacerGame::controlEvent(Control* control, EventType evt)
+{
+    if (strcmp(control->getId(), "newGameButton") == 0)
+    {
+        resetToStart();
+        // Close the menu and resume the game.
+        menuEvent();
+    }
+    else if (strcmp(control->getId(), "quitGameButton") == 0)
+    {
+        exit();
+    }
+    else if (strcmp(control->getId(), "useGamepad") == 0)
+    {
+        __useAccelerometer = false;
+    }
+    else if (strcmp(control->getId(), "useTilt") == 0)
+    {
+        __useAccelerometer = true;
+    }
+    else if (strcmp(control->getId(), "menuButton") == 0)
+    {
+        menuEvent();
+    }
+}

+ 138 - 138
samples/racer/src/RacerGame.h

@@ -1,138 +1,138 @@
-#ifndef TEMPLATEGAME_H_
-#define TEMPLATEGAME_H_
-
-#include "gameplay.h"
-
-using namespace gameplay;
-
-/**
- * Main game class.
- */
-class RacerGame: public Game, Control::Listener
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    RacerGame();
-
-    /**
-     * @see Game::keyEvent
-     */
-    void keyEvent(Keyboard::KeyEvent evt, int key);
-
-    /**
-     * @see Game::touchEvent
-     */
-    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
-
-    /**
-     * @see Game::mouseEvent
-     */
-    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
-
-    /** 
-     * @see Game::gamepadEvent
-     */
-    void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
-
-    /**
-     * @see Game::menuEvent
-     */
-    void menuEvent();
-
-    /**
-     * @see Control::controlEvent
-     */
-    void controlEvent(Control* control, EventType evt);
-    
-protected:
-
-    /**
-     * @see Game::initialize
-     */
-    void initialize();
-
-    /**
-     * @see Game::finalize
-     */
-    void finalize();
-
-    /**
-     * @see Game::update
-     */
-    void update(float elapsedTime);
-
-    /**
-     * @see Game::render
-     */
-    void render(float elapsedTime);
-
-private:
-
-    /**
-     * Initializes the scene.
-     */
-    bool initializeScene(Node* node);
-
-    /**
-     * Visits the scene to build render queues for a single frame.
-     */
-    bool buildRenderQueues(Node* node);
-
-    /**
-     * Draws the scene.
-     */
-    void drawScene();
-
-    /**
-     * Draws the splash screen.
-     */
-    void drawSplash(void* param);
-
-    /**
-     * Reset vehicle to its initial state.
-     */
-    void resetToStart();
-
-    /**
-     * Upright vehicle at its current location.
-     */
-    void resetInPlace();
-
-    /**
-     * Generic helper function for resets.
-     *
-     * @param pos desired position.
-     * @param rot desired rotation.
-     */
-    void reset(const Vector3& pos, const Quaternion& rot);
-
-    /**
-     * Indicates that the vehicle may be over-turned.
-     */
-    bool isUpset() const;
-
-    Scene* _scene;
-    Font* _font;
-    Form* _menu;
-    Form* _overlay;
-    std::vector<Node*> _renderQueues[2];
-    unsigned int _keyFlags;
-    unsigned int _mouseFlags;
-    float _steering;
-    Gamepad* _gamepad;
-    Gamepad* _physicalGamepad;
-    Gamepad* _virtualGamepad;
-    AnimationClip* _virtualGamepadClip;
-    PhysicsVehicle* _carVehicle;
-    float _upsetTimer;
-
-    // Sounds
-    AudioSource* _backgroundSound;
-    AudioSource* _engineSound;
-    AudioSource* _brakingSound;
-};
-
-#endif
+#ifndef TEMPLATEGAME_H_
+#define TEMPLATEGAME_H_
+
+#include "gameplay.h"
+
+using namespace gameplay;
+
+/**
+ * Main game class.
+ */
+class RacerGame: public Game, Control::Listener
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    RacerGame();
+
+    /**
+     * @see Game::keyEvent
+     */
+    void keyEvent(Keyboard::KeyEvent evt, int key);
+
+    /**
+     * @see Game::touchEvent
+     */
+    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+
+    /**
+     * @see Game::mouseEvent
+     */
+    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
+
+    /** 
+     * @see Game::gamepadEvent
+     */
+    void gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad);
+
+    /**
+     * @see Game::menuEvent
+     */
+    void menuEvent();
+
+    /**
+     * @see Control::controlEvent
+     */
+    void controlEvent(Control* control, EventType evt);
+    
+protected:
+
+    /**
+     * @see Game::initialize
+     */
+    void initialize();
+
+    /**
+     * @see Game::finalize
+     */
+    void finalize();
+
+    /**
+     * @see Game::update
+     */
+    void update(float elapsedTime);
+
+    /**
+     * @see Game::render
+     */
+    void render(float elapsedTime);
+
+private:
+
+    /**
+     * Initializes the scene.
+     */
+    bool initializeScene(Node* node);
+
+    /**
+     * Visits the scene to build render queues for a single frame.
+     */
+    bool buildRenderQueues(Node* node);
+
+    /**
+     * Draws the scene.
+     */
+    void drawScene();
+
+    /**
+     * Draws the splash screen.
+     */
+    void drawSplash(void* param);
+
+    /**
+     * Reset vehicle to its initial state.
+     */
+    void resetToStart();
+
+    /**
+     * Upright vehicle at its current location.
+     */
+    void resetInPlace();
+
+    /**
+     * Generic helper function for resets.
+     *
+     * @param pos desired position.
+     * @param rot desired rotation.
+     */
+    void reset(const Vector3& pos, const Quaternion& rot);
+
+    /**
+     * Indicates that the vehicle may be over-turned.
+     */
+    bool isUpset() const;
+
+    Scene* _scene;
+    Font* _font;
+    Form* _menu;
+    Form* _overlay;
+    std::vector<Node*> _renderQueues[2];
+    unsigned int _keyFlags;
+    unsigned int _mouseFlags;
+    float _steering;
+    Gamepad* _gamepad;
+    Gamepad* _physicalGamepad;
+    Gamepad* _virtualGamepad;
+    AnimationClip* _virtualGamepadClip;
+    PhysicsVehicle* _carVehicle;
+    float _upsetTimer;
+
+    // Sounds
+    AudioSource* _backgroundSound;
+    AudioSource* _engineSound;
+    AudioSource* _brakingSound;
+};
+
+#endif

+ 305 - 305
samples/spaceship/.cproject

@@ -1,305 +1,305 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?>
-
-<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.1898582830">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.1898582830" moduleId="org.eclipse.cdt.core.settings" name="Device-Debug">
-				<externalSettings/>
-				<extensions>
-					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.1898582830" name="Device-Debug" parent="com.qnx.qcc.configuration.exe.debug">
-					<folderInfo id="com.qnx.qcc.configuration.exe.debug.1898582830." name="/" resourcePath="">
-						<toolChain id="com.qnx.qcc.toolChain.exe.debug.2096919997" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
-							<option id="com.qnx.qcc.option.cpu.1283176032" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
-							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1406837167" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
-							<builder buildPath="${workspace_loc:/samples/spaceship/Device-Debug}" id="org.eclipse.cdt.build.core.internal.builder.1609644263" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
-							<tool id="com.qnx.qcc.tool.compiler.1158303109" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
-								<option id="com.qnx.qcc.option.compile.debug.1544186943" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.2012394098" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.defines.1031425461" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.includePath.1786077513" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1477606922" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
-									<listOptionValue builtIn="false" value="-Wno-psabi"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.compiler.981211207" superClass="com.qnx.qcc.inputType.compiler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.assembler.254047236" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
-								<option id="com.qnx.qcc.option.assembler.debug.1535948819" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.assembler.includePath.1703969047" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.assembler.689583433" superClass="com.qnx.qcc.inputType.assembler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.linker.852178446" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
-								<option id="com.qnx.qcc.option.linker.debug.153962189" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.langcpp.2142014141" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.security.2067622227" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.libraryPaths.1331874760" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/arm&quot;"/>
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.linker.libraries.570734469" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
-									<listOptionValue builtIn="false" value="GLESv2"/>
-									<listOptionValue builtIn="false" value="EGL"/>
-									<listOptionValue builtIn="false" value="screen"/>
-									<listOptionValue builtIn="false" value="m"/>
-									<listOptionValue builtIn="false" value="png"/>
-									<listOptionValue builtIn="false" value="pps"/>
-									<listOptionValue builtIn="false" value="bps"/>
-									<listOptionValue builtIn="false" value="gestures"/>
-									<listOptionValue builtIn="false" value="OpenAL"/>
-									<listOptionValue builtIn="false" value="asound"/>
-									<listOptionValue builtIn="false" value="gameplay"/>
-									<listOptionValue builtIn="false" value="lua"/>
-									<listOptionValue builtIn="false" value="bullet"/>
-									<listOptionValue builtIn="false" value="vorbis"/>
-									<listOptionValue builtIn="false" value="scoreloopcore"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.linker.1645280653" superClass="com.qnx.qcc.inputType.linker">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
-								</inputType>
-							</tool>
-							<tool id="com.qnx.qcc.tool.archiver.1784000328" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
-				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
-			</storageModule>
-		</cconfiguration>
-		<cconfiguration id="com.qnx.qcc.configuration.exe.release.791928190">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.release.791928190" moduleId="org.eclipse.cdt.core.settings" name="Device-Release">
-				<externalSettings/>
-				<extensions>
-					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.release.791928190" name="Device-Release" parent="com.qnx.qcc.configuration.exe.release">
-					<folderInfo id="com.qnx.qcc.configuration.exe.release.791928190." name="/" resourcePath="">
-						<toolChain id="com.qnx.qcc.toolChain.exe.release.1572330033" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
-							<option id="com.qnx.qcc.option.cpu.78317338" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
-							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1102881265" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
-							<builder buildPath="${workspace_loc:/sample-spaceship/Device-Release}" id="org.eclipse.cdt.build.core.internal.builder.1401321898" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
-							<tool id="com.qnx.qcc.tool.compiler.167195532" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
-								<option id="com.qnx.qcc.option.compiler.optlevel.1128281721" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
-								<option id="com.qnx.qcc.option.compiler.security.1305913768" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.defines.1393479764" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.includePath.1846473564" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1778753947" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
-									<listOptionValue builtIn="false" value="-Wno-psabi"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.compiler.763591924" superClass="com.qnx.qcc.inputType.compiler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.assembler.127627187" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
-								<option id="com.qnx.qcc.option.assembler.includePath.1753648943" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.assembler.2061094267" superClass="com.qnx.qcc.inputType.assembler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.linker.1416386099" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
-								<option id="com.qnx.qcc.option.linker.langcpp.825789136" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.security.701819676" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.libraryPaths.1540049128" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/arm&quot;"/>
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.linker.libraries.1996548068" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
-									<listOptionValue builtIn="false" value="GLESv2"/>
-									<listOptionValue builtIn="false" value="EGL"/>
-									<listOptionValue builtIn="false" value="screen"/>
-									<listOptionValue builtIn="false" value="m"/>
-									<listOptionValue builtIn="false" value="png"/>
-									<listOptionValue builtIn="false" value="pps"/>
-									<listOptionValue builtIn="false" value="bps"/>
-									<listOptionValue builtIn="false" value="gestures"/>
-									<listOptionValue builtIn="false" value="OpenAL"/>
-									<listOptionValue builtIn="false" value="asound"/>
-									<listOptionValue builtIn="false" value="gameplay"/>
-									<listOptionValue builtIn="false" value="lua"/>
-									<listOptionValue builtIn="false" value="bullet"/>
-									<listOptionValue builtIn="false" value="vorbis"/>
-									<listOptionValue builtIn="false" value="scoreloopcore"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.linker.534133606" superClass="com.qnx.qcc.inputType.linker">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
-								</inputType>
-							</tool>
-							<tool id="com.qnx.qcc.tool.archiver.1386344814" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
-				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
-			</storageModule>
-		</cconfiguration>
-		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.1233004640">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.1233004640" moduleId="org.eclipse.cdt.core.settings" name="Simulator">
-				<externalSettings/>
-				<extensions>
-					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.1233004640" name="Simulator" parent="com.qnx.qcc.configuration.exe.debug">
-					<folderInfo id="com.qnx.qcc.configuration.exe.debug.1233004640." name="/" resourcePath="">
-						<toolChain id="com.qnx.qcc.toolChain.exe.debug.775222128" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
-							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.32198076" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
-							<builder buildPath="${workspace_loc:/sample-spaceship/Simulator}" id="org.eclipse.cdt.build.core.internal.builder.2125250125" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
-							<tool id="com.qnx.qcc.tool.compiler.572962635" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
-								<option id="com.qnx.qcc.option.compile.debug.836165207" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1801893474" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.defines.1406768557" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.includePath.2118333103" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1980634690" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
-									<listOptionValue builtIn="false" value="-Wno-psabi"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.compiler.346604454" superClass="com.qnx.qcc.inputType.compiler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.assembler.405466690" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
-								<option id="com.qnx.qcc.option.assembler.debug.939069468" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.assembler.includePath.74539899" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.assembler.439279576" superClass="com.qnx.qcc.inputType.assembler"/>
-							</tool>
-							<tool id="com.qnx.qcc.tool.linker.1280619646" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
-								<option id="com.qnx.qcc.option.linker.debug.1060455453" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.langcpp.868409140" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.security.1156565203" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.linker.libraryPaths.1716299782" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/x86&quot;"/>
-									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/x86&quot;"/>
-								</option>
-								<option id="com.qnx.qcc.option.linker.libraries.790894544" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
-									<listOptionValue builtIn="false" value="GLESv2"/>
-									<listOptionValue builtIn="false" value="EGL"/>
-									<listOptionValue builtIn="false" value="screen"/>
-									<listOptionValue builtIn="false" value="m"/>
-									<listOptionValue builtIn="false" value="png"/>
-									<listOptionValue builtIn="false" value="pps"/>
-									<listOptionValue builtIn="false" value="bps"/>
-									<listOptionValue builtIn="false" value="gestures"/>
-									<listOptionValue builtIn="false" value="OpenAL"/>
-									<listOptionValue builtIn="false" value="asound"/>
-									<listOptionValue builtIn="false" value="gameplay"/>
-									<listOptionValue builtIn="false" value="lua"/>
-									<listOptionValue builtIn="false" value="bullet"/>
-									<listOptionValue builtIn="false" value="vorbis"/>
-									<listOptionValue builtIn="false" value="scoreloopcore"/>
-								</option>
-								<inputType id="com.qnx.qcc.inputType.linker.1805822171" superClass="com.qnx.qcc.inputType.linker">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
-								</inputType>
-							</tool>
-							<tool id="com.qnx.qcc.tool.archiver.788532836" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
-				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
-			</storageModule>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="sample02-spaceship.null.298926908" name="sample02-spaceship"/>
-	</storageModule>
-	<storageModule moduleId="scannerConfiguration">
-		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.134475205">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.1388065949">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.1481263776">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.release.791928190">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.1233004640">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.1047868168">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.1898582830">
-			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
-		</scannerConfigBuildInfo>
-	</storageModule>
-	<storageModule moduleId="refreshScope"/>
-	<storageModule moduleId="com.qnx.tools.ide.qde.core.QNXProjectProperties"/>
-	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-</cproject>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.1898582830">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.1898582830" moduleId="org.eclipse.cdt.core.settings" name="Device-Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.1898582830" name="Device-Debug" parent="com.qnx.qcc.configuration.exe.debug">
+					<folderInfo id="com.qnx.qcc.configuration.exe.debug.1898582830." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.debug.2096919997" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.1283176032" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1406837167" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/samples/spaceship/Device-Debug}" id="org.eclipse.cdt.build.core.internal.builder.1609644263" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.1158303109" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compile.debug.1544186943" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.2012394098" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1031425461" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.includePath.1786077513" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1477606922" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Wno-psabi"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.981211207" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.254047236" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.1535948819" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.assembler.includePath.1703969047" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.assembler.689583433" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.852178446" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.153962189" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.langcpp.2142014141" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.security.2067622227" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1331874760" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraries.570734469" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="m"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="pps"/>
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
+									<listOptionValue builtIn="false" value="OpenAL"/>
+									<listOptionValue builtIn="false" value="asound"/>
+									<listOptionValue builtIn="false" value="gameplay"/>
+									<listOptionValue builtIn="false" value="lua"/>
+									<listOptionValue builtIn="false" value="bullet"/>
+									<listOptionValue builtIn="false" value="vorbis"/>
+									<listOptionValue builtIn="false" value="scoreloopcore"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.linker.1645280653" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.1784000328" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
+				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
+			</storageModule>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.release.791928190">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.release.791928190" moduleId="org.eclipse.cdt.core.settings" name="Device-Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.release.791928190" name="Device-Release" parent="com.qnx.qcc.configuration.exe.release">
+					<folderInfo id="com.qnx.qcc.configuration.exe.release.791928190." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.release.1572330033" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<option id="com.qnx.qcc.option.cpu.78317338" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/>
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1102881265" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/sample-spaceship/Device-Release}" id="org.eclipse.cdt.build.core.internal.builder.1401321898" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.167195532" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compiler.optlevel.1128281721" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compiler.security.1305913768" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1393479764" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.includePath.1846473564" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1778753947" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Wno-psabi"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.763591924" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.127627187" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.includePath.1753648943" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.assembler.2061094267" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1416386099" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.langcpp.825789136" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.security.701819676" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1540049128" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraries.1996548068" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="m"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="pps"/>
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
+									<listOptionValue builtIn="false" value="OpenAL"/>
+									<listOptionValue builtIn="false" value="asound"/>
+									<listOptionValue builtIn="false" value="gameplay"/>
+									<listOptionValue builtIn="false" value="lua"/>
+									<listOptionValue builtIn="false" value="bullet"/>
+									<listOptionValue builtIn="false" value="vorbis"/>
+									<listOptionValue builtIn="false" value="scoreloopcore"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.linker.534133606" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.1386344814" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
+				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
+			</storageModule>
+		</cconfiguration>
+		<cconfiguration id="com.qnx.qcc.configuration.exe.debug.1233004640">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.exe.debug.1233004640" moduleId="org.eclipse.cdt.core.settings" name="Simulator">
+				<externalSettings/>
+				<extensions>
+					<extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.qnx.qcc.configuration.exe.debug.1233004640" name="Simulator" parent="com.qnx.qcc.configuration.exe.debug">
+					<folderInfo id="com.qnx.qcc.configuration.exe.debug.1233004640." name="/" resourcePath="">
+						<toolChain id="com.qnx.qcc.toolChain.exe.debug.775222128" name="QNX QCC" superClass="com.qnx.qcc.toolChain">
+							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.32198076" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/sample-spaceship/Simulator}" id="org.eclipse.cdt.build.core.internal.builder.2125250125" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
+							<tool id="com.qnx.qcc.tool.compiler.572962635" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
+								<option id="com.qnx.qcc.option.compile.debug.836165207" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1801893474" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.defines.1406768557" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.includePath.2118333103" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/lua/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../external-deps/oggvorbis/include&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1980634690" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-Wno-psabi"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.compiler.346604454" superClass="com.qnx.qcc.inputType.compiler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.assembler.405466690" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
+								<option id="com.qnx.qcc.option.assembler.debug.939069468" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.assembler.includePath.74539899" name="Include Directories (-I)" superClass="com.qnx.qcc.option.assembler.includePath" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay/src}&quot;"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.assembler.439279576" superClass="com.qnx.qcc.inputType.assembler"/>
+							</tool>
+							<tool id="com.qnx.qcc.tool.linker.1280619646" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
+								<option id="com.qnx.qcc.option.linker.debug.1060455453" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.langcpp.868409140" name="C++ (-lang-c++)" superClass="com.qnx.qcc.option.linker.langcpp" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.security.1156565203" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.linker.libraryPaths.1716299782" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths">
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/lua/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/${ConfigName}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/bullet/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/gameplay}/../external-deps/oggvorbis/lib/blackberry/x86&quot;"/>
+								</option>
+								<option id="com.qnx.qcc.option.linker.libraries.790894544" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
+									<listOptionValue builtIn="false" value="GLESv2"/>
+									<listOptionValue builtIn="false" value="EGL"/>
+									<listOptionValue builtIn="false" value="screen"/>
+									<listOptionValue builtIn="false" value="m"/>
+									<listOptionValue builtIn="false" value="png"/>
+									<listOptionValue builtIn="false" value="pps"/>
+									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
+									<listOptionValue builtIn="false" value="OpenAL"/>
+									<listOptionValue builtIn="false" value="asound"/>
+									<listOptionValue builtIn="false" value="gameplay"/>
+									<listOptionValue builtIn="false" value="lua"/>
+									<listOptionValue builtIn="false" value="bullet"/>
+									<listOptionValue builtIn="false" value="vorbis"/>
+									<listOptionValue builtIn="false" value="scoreloopcore"/>
+								</option>
+								<inputType id="com.qnx.qcc.inputType.linker.1805822171" superClass="com.qnx.qcc.inputType.linker">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+									<additionalInput kind="additionaldependency" paths="$(LIB_DEPS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.qnx.qcc.tool.archiver.788532836" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings">
+				<externalSettings containerId="gameplay;" factoryId="org.eclipse.cdt.core.cfg.export.settings.sipplier"/>
+			</storageModule>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="sample02-spaceship.null.298926908" name="sample02-spaceship"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.134475205">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.coverage.1388065949">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.1481263776">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.release.791928190">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.1233004640">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.profile.1047868168">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.exe.debug.1898582830">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="refreshScope"/>
+	<storageModule moduleId="com.qnx.tools.ide.qde.core.QNXProjectProperties"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>

+ 78 - 78
samples/spaceship/.project

@@ -1,78 +1,78 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>sample-spaceship</name>
-	<comment></comment>
-	<projects>
-		<project>gameplay</project>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-				<dictionary>
-					<key>?name?</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.append_environment</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildCommand</key>
-					<value>make</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildLocation</key>
-					<value>${workspace_loc:/samples/spaceship/Device-Debug}</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.contents</key>
-					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
-					<value>false</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.stopOnError</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
-					<value>true</value>
-				</dictionary>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-		<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
-		<nature>org.eclipse.cdt.core.ccnature</nature>
-	</natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>sample-spaceship</name>
+	<comment></comment>
+	<projects>
+		<project>gameplay</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>make</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildLocation</key>
+					<value>${workspace_loc:/samples/spaceship/Device-Debug}</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>true</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+		<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+	</natures>
+</projectDescription>

+ 101 - 101
samples/spaceship/android/build.xml

@@ -1,101 +1,101 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="sample-spaceship" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked into
-         Version Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The ant.properties file can be created by you. It is only edited by the
-         'android' tool to add properties to it.
-         This is the place to change some Ant specific build properties.
-         Here are some properties you may want to change/update:
-
-         source.dir
-             The name of the source directory. Default is 'src'.
-         out.dir
-             The name of the output directory. Default is 'bin'.
-
-         For other overridable properties, look at the beginning of the rules
-         files in the SDK, at tools/ant/build.xml
-
-         Properties related to the SDK location or the project target should
-         be updated using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems.
-
-         -->
-    <property file="ant.properties" />
-
-    <!-- The project.properties file is created and updated by the 'android'
-         tool, as well as ADT.
-
-         This contains project specific properties such as project target, and library
-         dependencies. Lower level build properties are stored in ant.properties
-         (or in .classpath for Eclipse projects).
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems. -->
-    <loadproperties srcFile="project.properties" />
-
-    <!-- quick check on sdk.dir -->
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
-          unless="sdk.dir" />
-
-
-<!-- extension targets. Uncomment the ones where you want to do custom work
-     in between standard targets -->
-
-    <target name="-pre-build">
-		<mkdir dir="src"/>
-    </target>
-	
-<!--
-    <target name="-pre-compile">
-    </target>
-
-    /* This is typically used for code obfuscation.
-       Compiled code location: ${out.classes.absolute.dir}
-       If this is not done in place, override ${out.dex.input.absolute.dir} */
-       -->
-    <target name="-post-compile">
-        <copy file="../res/airstrip.gpb" tofile="assets/res/airstrip.gpb"/>
-        <copy file="../res/background.ogg" tofile="assets/res/background.ogg"/>
-        <copy file="../res/background.png" tofile="assets/res/background.png"/>
-		<copy file="../res/challenge.form" tofile="assets/res/challenge.form"/>
-        <copy file="../res/menu.form" tofile="assets/res/menu.form"/>
-		<copy file="../res/menu.theme" tofile="assets/res/menu.theme"/>
-		<copy file="../res/menuAtlas.png" tofile="assets/res/menuAtlas.png"/>
-        <copy file="../res/propulsion_glow.png" tofile="assets/res/propulsion_glow.png"/>
-        <copy file="../res/spaceship.gpb" tofile="assets/res/spaceship.gpb"/>
-        <copy file="../res/spaceship.wav" tofile="assets/res/spaceship.wav"/>
-        <copy todir="assets/res/shaders">
-            <fileset dir="../../../gameplay/res/shaders"/>
-        </copy>
-        <copy file="../../../gameplay/res/logo_powered_white.png" tofile="assets/res/logo_powered_white.png"/>
-    </target>
-
-
-    <!-- Import the actual build file.
-
-         To customize existing targets, there are two options:
-         - Customize only one target:
-             - copy/paste the target into this file, *before* the
-               <import> task.
-             - customize it to your needs.
-         - Customize the whole content of build.xml
-             - copy/paste the content of the rules files (minus the top node)
-               into this file, replacing the <import> task.
-             - customize to your needs.
-
-         ***********************
-         ****** IMPORTANT ******
-         ***********************
-         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
-         in order to avoid having your file be overridden by tools such as "android update project"
-    -->
-    <!-- version-tag: 1 -->
-    <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="sample-spaceship" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+          unless="sdk.dir" />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+     in between standard targets -->
+
+    <target name="-pre-build">
+		<mkdir dir="src"/>
+    </target>
+	
+<!--
+    <target name="-pre-compile">
+    </target>
+
+    /* This is typically used for code obfuscation.
+       Compiled code location: ${out.classes.absolute.dir}
+       If this is not done in place, override ${out.dex.input.absolute.dir} */
+       -->
+    <target name="-post-compile">
+        <copy file="../res/airstrip.gpb" tofile="assets/res/airstrip.gpb"/>
+        <copy file="../res/background.ogg" tofile="assets/res/background.ogg"/>
+        <copy file="../res/background.png" tofile="assets/res/background.png"/>
+		<copy file="../res/challenge.form" tofile="assets/res/challenge.form"/>
+        <copy file="../res/menu.form" tofile="assets/res/menu.form"/>
+		<copy file="../res/menu.theme" tofile="assets/res/menu.theme"/>
+		<copy file="../res/menuAtlas.png" tofile="assets/res/menuAtlas.png"/>
+        <copy file="../res/propulsion_glow.png" tofile="assets/res/propulsion_glow.png"/>
+        <copy file="../res/spaceship.gpb" tofile="assets/res/spaceship.gpb"/>
+        <copy file="../res/spaceship.wav" tofile="assets/res/spaceship.wav"/>
+        <copy todir="assets/res/shaders">
+            <fileset dir="../../../gameplay/res/shaders"/>
+        </copy>
+        <copy file="../../../gameplay/res/logo_powered_white.png" tofile="assets/res/logo_powered_white.png"/>
+    </target>
+
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>

+ 44 - 44
samples/spaceship/bar-descriptor.xml

@@ -1,44 +1,44 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.qnx.com/schemas/application/1.0">
-  <id>org.gameplay3d.sample_spaceship</id>
-  <name>Spaceship</name>
-  <versionNumber>2.0.0</versionNumber>
-  <buildId>1</buildId>
-  <description>Spaceship</description>
-  <author>RIM Canada</author>
-  <category>core.games</category>
-  <initialWindow>
-    <autoOrients>false</autoOrients>
-    <aspectRatio>landscape</aspectRatio>
-    <systemChrome>none</systemChrome>
-    <transparent>false</transparent>
-  </initialWindow>
-  <asset path="icon.png">icon.png</asset>
-  <asset path="res/airstrip.gpb">res/airstrip.gpb</asset>
-  <asset path="res/spaceship.gpb">res/spaceship.gpb</asset>
-  <asset path="res/spaceship.wav">res/spaceship.wav</asset>
-  <asset path="res//background.ogg">res/background.ogg</asset>
-  <asset path="res/background.png">res/background.png</asset>
-  <asset path="res/propulsion_glow.png">res/propulsion_glow.png</asset>
-  <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-  <asset path="../../gameplay/res/shaders">res/shaders</asset>
-  <asset path="../../gameplay/res/ui">res/ui</asset>
-  <asset path="game.config">game.config</asset>
-  <configuration name="Device-Debug">
-    <platformArchitecture>armle-v7</platformArchitecture>
-    <asset path="Device-Debug/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
-  </configuration>
-  <configuration name="Device-Release">
-    <platformArchitecture>armle-v7</platformArchitecture>
-    <asset path="Device-Release/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
-  </configuration>
-  <configuration name="Simulator">
-    <platformArchitecture>x86</platformArchitecture>
-    <asset path="Simulator/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
-  </configuration>
-  <permission>read_device_identifying_information</permission>
-  <icon>
-    <image>icon.png</image>
-  </icon>
-  <env var="LD_LIBRARY_PATH" value="app/native/lib" />
-</qnx>
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<qnx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.qnx.com/schemas/application/1.0">
+  <id>org.gameplay3d.sample_spaceship</id>
+  <name>Spaceship</name>
+  <versionNumber>2.0.0</versionNumber>
+  <buildId>1</buildId>
+  <description>Spaceship</description>
+  <author>RIM Canada</author>
+  <category>core.games</category>
+  <initialWindow>
+    <autoOrients>false</autoOrients>
+    <aspectRatio>landscape</aspectRatio>
+    <systemChrome>none</systemChrome>
+    <transparent>false</transparent>
+  </initialWindow>
+  <asset path="icon.png">icon.png</asset>
+  <asset path="res/airstrip.gpb">res/airstrip.gpb</asset>
+  <asset path="res/spaceship.gpb">res/spaceship.gpb</asset>
+  <asset path="res/spaceship.wav">res/spaceship.wav</asset>
+  <asset path="res//background.ogg">res/background.ogg</asset>
+  <asset path="res/background.png">res/background.png</asset>
+  <asset path="res/propulsion_glow.png">res/propulsion_glow.png</asset>
+  <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
+  <asset path="../../gameplay/res/shaders">res/shaders</asset>
+  <asset path="../../gameplay/res/ui">res/ui</asset>
+  <asset path="game.config">game.config</asset>
+  <configuration name="Device-Debug">
+    <platformArchitecture>armle-v7</platformArchitecture>
+    <asset path="Device-Debug/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
+  </configuration>
+  <configuration name="Device-Release">
+    <platformArchitecture>armle-v7</platformArchitecture>
+    <asset path="Device-Release/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
+  </configuration>
+  <configuration name="Simulator">
+    <platformArchitecture>x86</platformArchitecture>
+    <asset path="Simulator/sample-spaceship" entry="true" type="Qnx/Elf">sample-spaceship</asset>
+  </configuration>
+  <permission>read_device_identifying_information</permission>
+  <icon>
+    <image>icon.png</image>
+  </icon>
+  <env var="LD_LIBRARY_PATH" value="app/native/lib" />
+</qnx>

+ 7 - 7
samples/spaceship/game.config

@@ -1,7 +1,7 @@
-window
-{
-    title = Spaceship
-    width = 1280
-    height = 720
-    fullscreen = false
-}
+window
+{
+    title = Spaceship
+    width = 1280
+    height = 720
+    fullscreen = false
+}

+ 364 - 364
samples/spaceship/sample-spaceship.vcxproj

@@ -1,365 +1,365 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugMem|Win32">
-      <Configuration>DebugMem</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugMem|x64">
-      <Configuration>DebugMem</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{CC37B8E9-6402-4841-8D6A-5D908A5909B3}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>sample-spaceship</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <IntDir>$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-copy ..\..\gameplay\res\logo_powered_white.png res</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-      copy ..\..\gameplay\res\logo_powered_white.png res</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
-      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
-      copy ..\..\gameplay\res\logo_powered_white.png res</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Message>
-      </Message>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <None Include="bar-descriptor.xml" />
-    <None Include="game.config" />
-    <None Include="icon.png" />
-    <None Include="res\airstrip.gpb" />
-    <None Include="res\background.ogg" />
-    <None Include="res\shaders\colored.frag" />
-    <None Include="res\shaders\colored.vert" />
-    <None Include="res\shaders\font.frag" />
-    <None Include="res\shaders\font.vert" />
-    <None Include="res\shaders\form.frag" />
-    <None Include="res\shaders\form.vert" />
-    <None Include="res\shaders\lighting.frag" />
-    <None Include="res\shaders\lighting.vert" />
-    <None Include="res\shaders\skinning-none.vert" />
-    <None Include="res\shaders\skinning.vert" />
-    <None Include="res\shaders\sprite.frag" />
-    <None Include="res\shaders\sprite.vert" />
-    <None Include="res\shaders\terrain.frag" />
-    <None Include="res\shaders\terrain.vert" />
-    <None Include="res\shaders\textured.frag" />
-    <None Include="res\shaders\textured.vert" />
-    <None Include="res\spaceship.gpb" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\SpaceshipGame.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\SpaceshipGame.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <Font Include="res\airstrip.ttf" />
-  </ItemGroup>
-  <ItemGroup>
-    <Image Include="res\background.png" />
-    <Image Include="res\propulsion_glow.png" />
-  </ItemGroup>
-  <ItemGroup>
-    <Media Include="res\spaceship.wav" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugMem|Win32">
+      <Configuration>DebugMem</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|x64">
+      <Configuration>DebugMem</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{CC37B8E9-6402-4841-8D6A-5D908A5909B3}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>sample-spaceship</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+copy ..\..\gameplay\res\logo_powered_white.png res</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+      copy ..\..\gameplay\res\logo_powered_white.png res</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x86;..\..\external-deps\bullet\lib\windows\x86;..\..\external-deps\openal\lib\windows\x86;..\..\external-deps\oggvorbis\lib\windows\x86;..\..\external-deps\glew\lib\windows\x86;..\..\external-deps\png\lib\windows\x86;..\..\external-deps\zlib\lib\windows\x86;..\..\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy ..\..\gameplay\res\shaders res\shaders\* /s /y /d
+      xcopy ..\..\gameplay\res\ui res\ui\* /s /y /d
+      copy ..\..\gameplay\res\logo_powered_white.png res</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\gameplay\src;..\..\external-deps\bullet\include;..\..\external-deps\lua\include;..\..\external-deps\openal\include\AL;..\..\external-deps\oggvorbis\include;..\..\external-deps\png\include;..\..\external-deps\zlib\include;..\..\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>..\..\external-deps\lua\lib\windows\x64;..\..\external-deps\bullet\lib\windows\x64;..\..\external-deps\openal\lib\windows\x64;..\..\external-deps\oggvorbis\lib\windows\x64;..\..\external-deps\glew\lib\windows\x64;..\..\external-deps\png\lib\windows\x64;..\..\external-deps\zlib\lib\windows\x64;..\..\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="bar-descriptor.xml" />
+    <None Include="game.config" />
+    <None Include="icon.png" />
+    <None Include="res\airstrip.gpb" />
+    <None Include="res\background.ogg" />
+    <None Include="res\shaders\colored.frag" />
+    <None Include="res\shaders\colored.vert" />
+    <None Include="res\shaders\font.frag" />
+    <None Include="res\shaders\font.vert" />
+    <None Include="res\shaders\form.frag" />
+    <None Include="res\shaders\form.vert" />
+    <None Include="res\shaders\lighting.frag" />
+    <None Include="res\shaders\lighting.vert" />
+    <None Include="res\shaders\skinning-none.vert" />
+    <None Include="res\shaders\skinning.vert" />
+    <None Include="res\shaders\sprite.frag" />
+    <None Include="res\shaders\sprite.vert" />
+    <None Include="res\shaders\terrain.frag" />
+    <None Include="res\shaders\terrain.vert" />
+    <None Include="res\shaders\textured.frag" />
+    <None Include="res\shaders\textured.vert" />
+    <None Include="res\spaceship.gpb" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\SpaceshipGame.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\SpaceshipGame.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <Font Include="res\airstrip.ttf" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\background.png" />
+    <Image Include="res\propulsion_glow.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Media Include="res\spaceship.wav" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
 </Project>

+ 103 - 103
samples/spaceship/sample-spaceship.vcxproj.filters

@@ -1,104 +1,104 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="res">
-      <UniqueIdentifier>{174b782f-abfa-4a6e-99f3-ef7c67fb4798}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src">
-      <UniqueIdentifier>{03dcd1a4-e2c1-4dc6-ac81-3e6538d8e747}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="res\shaders">
-      <UniqueIdentifier>{bb48b4a6-578b-4029-a7ef-8860bc4c16cb}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="bar-descriptor.xml" />
-    <None Include="icon.png" />
-    <None Include="game.config" />
-    <None Include="res\airstrip.gpb">
-      <Filter>res</Filter>
-    </None>
-    <None Include="res\background.ogg">
-      <Filter>res</Filter>
-    </None>
-    <None Include="res\spaceship.gpb">
-      <Filter>res</Filter>
-    </None>
-    <None Include="res\shaders\colored.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\colored.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\font.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\font.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\form.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\form.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\lighting.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\lighting.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\skinning.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\skinning-none.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\sprite.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\sprite.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\terrain.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\terrain.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\textured.frag">
-      <Filter>res\shaders</Filter>
-    </None>
-    <None Include="res\shaders\textured.vert">
-      <Filter>res\shaders</Filter>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\SpaceshipGame.h">
-      <Filter>src</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\SpaceshipGame.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <Font Include="res\airstrip.ttf">
-      <Filter>res</Filter>
-    </Font>
-  </ItemGroup>
-  <ItemGroup>
-    <Image Include="res\background.png">
-      <Filter>res</Filter>
-    </Image>
-    <Image Include="res\propulsion_glow.png">
-      <Filter>res</Filter>
-    </Image>
-  </ItemGroup>
-  <ItemGroup>
-    <Media Include="res\spaceship.wav">
-      <Filter>res</Filter>
-    </Media>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="res">
+      <UniqueIdentifier>{174b782f-abfa-4a6e-99f3-ef7c67fb4798}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{03dcd1a4-e2c1-4dc6-ac81-3e6538d8e747}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="res\shaders">
+      <UniqueIdentifier>{bb48b4a6-578b-4029-a7ef-8860bc4c16cb}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="bar-descriptor.xml" />
+    <None Include="icon.png" />
+    <None Include="game.config" />
+    <None Include="res\airstrip.gpb">
+      <Filter>res</Filter>
+    </None>
+    <None Include="res\background.ogg">
+      <Filter>res</Filter>
+    </None>
+    <None Include="res\spaceship.gpb">
+      <Filter>res</Filter>
+    </None>
+    <None Include="res\shaders\colored.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\colored.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\font.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\font.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\form.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\form.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\lighting.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\lighting.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\skinning.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\skinning-none.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\sprite.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\sprite.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\terrain.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\terrain.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\textured.frag">
+      <Filter>res\shaders</Filter>
+    </None>
+    <None Include="res\shaders\textured.vert">
+      <Filter>res\shaders</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\SpaceshipGame.h">
+      <Filter>src</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\SpaceshipGame.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Font Include="res\airstrip.ttf">
+      <Filter>res</Filter>
+    </Font>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\background.png">
+      <Filter>res</Filter>
+    </Image>
+    <Image Include="res\propulsion_glow.png">
+      <Filter>res</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <Media Include="res\spaceship.wav">
+      <Filter>res</Filter>
+    </Media>
+  </ItemGroup>
 </Project>

+ 26 - 26
samples/spaceship/sample-spaceship.vcxproj.user

@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;../../bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>

+ 547 - 547
samples/spaceship/src/SpaceshipGame.cpp

@@ -1,547 +1,547 @@
-#include "SpaceshipGame.h"
-
-// Declare our game instance
-SpaceshipGame game;
-
-// Collision constants
-#define ROOF_HEIGHT 11.6f
-#define FLOOR_HEIGHT 0.6f
-#define MAP_LENGTH 1000.0f
-#define CAMERA_RANGE_FRONT -1
-#define CAMERA_RANGE_BACK 8
-
-// Mass of the space ship
-#define MASS 50.0f
-
-// Gravity constant (earth's gravity is ~9.8m/s/s)
-#define GRAVITY 9.8f
-
-// Force applied due to gravity (F = mg)
-#define GRAVITATIONAL_FORCE (MASS * GRAVITY)
-
-// Normal force used in friction computations (Fn = -mg)
-#define FORCE_NORMAL (-GRAVITATIONAL_FORCE)
-
-// Friction between floor and spaceship (Ff = u * Fn)
-#define FLOOR_FRICTION (0.4f * FORCE_NORMAL)
-
-// Friction between roof and spaceship (Ff = u * Fn)
-#define ROOF_FRICTION (0.035f * FORCE_NORMAL)
-
-// Distance from space ship (screen-space) after which force is no longer applied to the ship
-#define TOUCH_DISTANCE_MAX 400.0f
-
-// Amount to scale screen-space push/force vector by
-#define FORCE_SCALE 4.0f
-
-// Constant for the maximum force that can be applied to the ship
-#define FORCE_MAX (TOUCH_DISTANCE_MAX * FORCE_SCALE)
-
-// Maximum velocity (+/-)
-#define VELOCITY_MAX 75.0f
-
-// Maximum ship tilt (degrees)
-#define SHIP_TILT_MAX 45.0f
-
-// Maximum ship rotation (degrees) at full throttle
-#define SHIP_ROTATE_SPEED_MAX 500.0f
-
-// Multiplier for engine glow effect (based on throttle)
-#define ENGINE_POWER 2.5f
-
-// Multiplier for sound pitch (based on throttle)
-#define SOUND_PITCH_SCALE 2.0f
-
-// Lighting constants
-#define AMBIENT_LIGHT_COLOR Vector3(0.2f, 0.2f, 0.2f)
-#define SPECULAR 20.0f
-
-// Clamp function
-#define CLAMP(x, min, max) (x < min ? min : (x > max ? max : x))
-
-SpaceshipGame::SpaceshipGame()
-    : _scene(NULL), _cameraNode(NULL), _shipGroupNode(NULL), _shipNode(NULL), _propulsionNode(NULL), _glowNode(NULL),
-      _stateBlock(NULL), _font(NULL), _throttle(0), _shipTilt(0), _finished(true), _finishedTime(0), _pushing(false), _time(0),
-       _glowDiffuseParameter(NULL), _shipSpecularParameter(NULL), _spaceshipSound(NULL)
-{
-}
-
-SpaceshipGame::~SpaceshipGame()
-{
-}
-
-void SpaceshipGame::initialize()
-{
-    // TODO: Not working on iOS
-    // Display the gameplay splash screen for at least 1 second.
-    displayScreen(this, &SpaceshipGame::drawSplash, NULL, 1000L);
-
-    // Create our render state block that will be reused across all materials
-    _stateBlock = RenderState::StateBlock::create();
-    _stateBlock->setDepthTest(true);
-    _stateBlock->setCullFace(true);
-    _stateBlock->setBlend(true);
-    _stateBlock->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
-    _stateBlock->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
-
-    // Load our scene from file
-    _scene = Scene::load("res/spaceship.gpb");
-
-    // Update the aspect ratio for our scene's camera to match the current device resolution
-    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
-
-    // Initialize scene data
-    initializeSpaceship();
-    initializeEnvironment();
-
-    // Create a background audio track
-    _backgroundSound = AudioSource::create("res/background.ogg");
-    if (_backgroundSound)
-        _backgroundSound->setLooped(true);
-
-    // Create font
-    _font = Font::create("res/airstrip.gpb");
-
-    // Store camera node
-    _cameraNode = _scene->findNode("camera1");
-
-    // Store initial ship and camera positions
-    _initialShipPos = _shipGroupNode->getTranslation();
-    _initialShipRot = _shipGroupNode->getRotation();
-    _initialCameraPos = _cameraNode->getTranslation();
-}
-
-void SpaceshipGame::initializeSpaceship()
-{
-    Material* material;
-
-    _shipGroupNode = _scene->findNode("gSpaceShip");
-
-    // Setup spaceship model
-    // Part 0
-    _shipNode = _scene->findNode("pSpaceShip");
-    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 0);
-    material->getParameter("u_diffuseColor")->setValue(Vector4(0.53544f, 0.53544f, 0.53544f, 1.0f));
-    initializeMaterial(material, true, true);
-    // Part 1
-    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 1);
-    material->getParameter("u_diffuseColor")->setValue(Vector4(0.8f, 0.8f, 0.8f, 1.0f));
-    _shipSpecularParameter = material->getParameter("u_specularExponent");
-    initializeMaterial(material, true, true);
-    // Part 2
-    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 2);
-    material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
-    initializeMaterial(material, true, true);
-
-    // Setup spaceship propulsion model
-    _propulsionNode = _scene->findNode("pPropulsion");
-    material = _propulsionNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
-    material->getParameter("u_diffuseColor")->setValue(Vector4(0.8f, 0.8f, 0.8f, 1.0f));
-    initializeMaterial(material, true, true);
-
-    // Glow effect node
-    _glowNode = _scene->findNode("pGlow");
-    material = _glowNode->getModel()->setMaterial("res/shaders/textured.vert", "res/shaders/textured.frag", "MODULATE_COLOR");
-    material->getParameter("u_diffuseTexture")->setValue("res/propulsion_glow.png", true);
-    _glowDiffuseParameter = material->getParameter("u_modulateColor");
-    initializeMaterial(material, false, false);
-
-    // Setup the sound
-    _spaceshipSound = AudioSource::create("res/spaceship.wav");
-    if (_spaceshipSound)
-    {
-        _spaceshipSound->setLooped(true);
-    }
-}
-
-void SpaceshipGame::initializeEnvironment()
-{
-    Material* material;
-    std::vector<Node*> nodes;
-
-    // Setup ground model
-    _scene->findNodes("pGround", nodes, true, false);
-    for (size_t i = 0, count = nodes.size(); i < count; ++i)
-    {
-        Node* pGround = nodes[i];
-        material = pGround->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
-        material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
-        initializeMaterial(material, true, true);
-    }
-
-    // Setup roof model
-    nodes.clear();
-    _scene->findNodes("pRoof", nodes, true, false);
-    for (size_t i = 0, count = nodes.size(); i < count; ++i)
-    {
-        Node* pRoof = nodes[i];
-        material = pRoof->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
-        material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
-        initializeMaterial(material, true, true);
-    }
-
-    // Setup background model
-    nodes.clear();
-    Node* pBackground = _scene->findNode("pBackground");
-    material = pBackground->getModel()->setMaterial("res/shaders/textured.vert", "res/shaders/textured.frag", "DIRECTIONAL_LIGHT_COUNT 1");
-    material->getParameter("u_diffuseTexture")->setValue("res/background.png", true);
-    initializeMaterial(material, true, false);
-}
-
-void SpaceshipGame::initializeMaterial(Material* material, bool lighting, bool specular)
-{
-    // Set the common render state block for the material
-    material->setStateBlock(_stateBlock);
-
-    // Bind the WorldViewProjection matrix
-    material->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX);
-
-    if (lighting)
-    {
-        // Apply lighting material parameters
-        material->setParameterAutoBinding("u_inverseTransposeWorldViewMatrix", RenderState::INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX);
-        material->getParameter("u_ambientColor")->setValue(AMBIENT_LIGHT_COLOR);
-
-        Node* lightNode = _scene->findNode("directionalLight1");
-        Vector3 lightDirection = lightNode->getForwardVector();
-        lightDirection.normalize();
-        if (lightNode)
-        {
-            material->getParameter("u_directionalLightColor[0]")->setValue(lightNode->getLight()->getColor());
-            material->getParameter("u_directionalLightDirection[0]")->setValue(lightDirection);
-        }
-
-        if (specular)
-        {
-            // Apply specular lighting parameters
-            material->getParameter("u_specularExponent")->setValue(SPECULAR);
-            material->setParameterAutoBinding("u_worldViewMatrix", RenderState::WORLD_VIEW_MATRIX);
-            material->setParameterAutoBinding("u_cameraPosition", RenderState::CAMERA_WORLD_POSITION);
-        }
-    }
-}
-
-void SpaceshipGame::finalize()
-{
-    SAFE_RELEASE(_backgroundSound);
-    SAFE_RELEASE(_spaceshipSound);
-    SAFE_RELEASE(_font);
-    SAFE_RELEASE(_stateBlock);
-    SAFE_RELEASE(_scene);
-}
-
-void SpaceshipGame::update(float elapsedTime)
-{
-    // Calculate elapsed time in seconds
-    float t = (float)elapsedTime / 1000.0;
-
-    if (!_finished)
-    {
-        _time += t;
-
-        // Play the background track
-        if (_backgroundSound->getState() != AudioSource::PLAYING)
-            _backgroundSound->play();
-    }
-    else
-    {
-        // Stop the background track
-        if (_backgroundSound->getState() == AudioSource::PLAYING || _backgroundSound->getState() == AudioSource::PAUSED)
-		{
-            _backgroundSound->stop();
-        	_throttle = 0.0f;
-		}
-    }
-
-    // Set initial force due to gravity
-    _force.set(0, -GRAVITATIONAL_FORCE);
-
-    // While we are pushing/touching the screen, apply a push force vector based on the distance from
-    // the touch point to the center of the space ship.
-    if (_pushing)
-    {
-        // Get the center point of the space ship in screen coordinates
-        Vector3 shipCenterScreen;
-        _scene->getActiveCamera()->project(getViewport(), _shipGroupNode->getBoundingSphere().center, &shipCenterScreen.x, &shipCenterScreen.y);
-
-        // Compute a screen-space vector between the center point of the ship and the touch point.
-        // We will use this vector to apply a "pushing" force to the space ship, similar to what
-        // happens when you hold a magnet close to an object with opposite polarity.
-        Vector2 pushForce((shipCenterScreen.x - _pushPoint.x), -(shipCenterScreen.y - _pushPoint.y));
-
-        // Transform the vector so that a smaller magnitude emits a larger force and applying the
-        // maximum touch distance.
-        float distance = (std::max)(TOUCH_DISTANCE_MAX - pushForce.length(), 0.0f);
-        pushForce.normalize();
-        pushForce.scale(distance * FORCE_SCALE);
-        _force.add(pushForce);
-
-        // Compute a throttle value based on our force vector, minus gravity
-        Vector2 throttleVector(_force.x, _force.y + GRAVITATIONAL_FORCE);
-        _throttle += throttleVector.length() / FORCE_MAX * t;
-    }
-    else
-    {
-        // Gradually decrease the throttle
-        if (_throttle > 0.0f)
-        {
-            _throttle *= 1.0f - t;
-        }
-    }
-
-    // Clamp the throttle
-    _throttle = CLAMP(_throttle, 0.0f, 1.0f);
-
-    // Update acceleration (a = F/m)
-    _acceleration.set(_force.x / MASS, _force.y / MASS);
-
-    // Update velocity (v1 = v0 + at)
-    _velocity.x += _acceleration.x * t;
-    _velocity.y += _acceleration.y * t;
-
-    // Clamp velocity to its maximum range
-    _velocity.x = CLAMP(_velocity.x, -VELOCITY_MAX, VELOCITY_MAX);
-    _velocity.y = CLAMP(_velocity.y, -VELOCITY_MAX, VELOCITY_MAX);
-
-    // Move the spaceship based on its current velocity (x1 = x0 + vt)
-    _shipGroupNode->translate(_velocity.x * t, _velocity.y * t, 0);
-
-    // Check for collisions
-    handleCollisions(t);
-
-    // Update camera
-    updateCamera();
-
-    // Reset ship rotation
-    _shipGroupNode->setRotation(_initialShipRot);
-
-    // Apply ship tilt
-    if (_force.x != 0 && fabs(_velocity.x) > 0.1f)
-    {
-        // Compute an angle based on the dot product between the force vector and the Y axis
-        Vector2 fn;
-        _force.normalize(&fn);
-        float angle = MATH_RAD_TO_DEG(acos(Vector2::dot(Vector2(0, 1), fn)));
-        if (_force.x > 0)
-            angle = -angle;
-        angle *= _throttle * t;
-        _shipTilt += angle;
-        _shipTilt = _shipTilt < -SHIP_TILT_MAX ? -SHIP_TILT_MAX : (_shipTilt > SHIP_TILT_MAX ? SHIP_TILT_MAX : _shipTilt);
-    }
-    else
-    {
-        // Interpolate tilt back towards zero when no force is applied
-        _shipTilt = (_shipTilt + ((0 - _shipTilt) * t * 2.0f));
-    }
-    _shipGroupNode->rotateZ(MATH_DEG_TO_RAD(_shipTilt));
-
-    if (_throttle > MATH_EPSILON)
-    {
-        // Apply ship spin
-        _shipNode->rotateY(MATH_DEG_TO_RAD(SHIP_ROTATE_SPEED_MAX * t * _throttle));
-
-        // Play sound effect
-        if (_spaceshipSound->getState() != AudioSource::PLAYING)
-            _spaceshipSound->play();
-
-        // Set the pitch based on the throttle
-        _spaceshipSound->setPitch(_throttle * SOUND_PITCH_SCALE);
-    }
-    else
-    {
-        // Stop sound effect
-        _spaceshipSound->stop();
-    }
-
-    // Modify ship glow effect based on the throttle
-    _glowDiffuseParameter->setValue(Vector4(1, 1, 1, _throttle * ENGINE_POWER));
-    _shipSpecularParameter->setValue(SPECULAR - ((SPECULAR-2.0f) * _throttle));
-}
-
-void SpaceshipGame::handleCollisions(float t)
-{
-    float friction = 0.0f;
-
-    // Use the ship's bounding sphere for roof collisions
-    const BoundingSphere& shipBounds = _shipNode->getBoundingSphere();
-
-    // Compute a bounding box for floor collisions
-    BoundingBox propulsionBounds = _propulsionNode->getModel()->getMesh()->getBoundingBox();
-    propulsionBounds.transform(_propulsionNode->getWorldMatrix());
-
-    if (propulsionBounds.min.y <= FLOOR_HEIGHT)
-    {
-        // Floor collision
-        friction = FLOOR_FRICTION;
-        _shipGroupNode->translateY(FLOOR_HEIGHT - propulsionBounds.min.y);
-        if (_velocity.y < 0.0f)
-        {
-            // Cancel vertical velocity
-            _velocity.y = 0.0f;
-        }
-    }
-    else if ((shipBounds.center.y + shipBounds.radius) >= ROOF_HEIGHT)
-    {
-        // Roof collision
-        friction = ROOF_FRICTION;
-        _shipGroupNode->translateY(ROOF_HEIGHT - (shipBounds.center.y + shipBounds.radius));
-        if (_velocity.y >= 0.0f)
-        {
-            // Cancel vertical velocity
-            _velocity.y = 0.0f;
-        }
-    }
-
-    // Apply friction to velocity
-    if (friction != 0.0f)
-    {
-        if (_velocity.x > 0)
-        {
-            _velocity.x = (std::max)(_velocity.x + friction * t, 0.0f);
-        }
-        else if (_velocity.x < 0)
-        {
-            _velocity.x = (std::min)(_velocity.x - friction  * t, 0.0f);
-        }
-		_hitSomething = true;
-    }
-
-    // Keep the ship within the playable area of the map
-    const Vector3& shipPos = _shipGroupNode->getTranslation();
-    if (shipPos.x < _initialShipPos.x)
-    {
-        _shipGroupNode->translateX(_initialShipPos.x - shipPos.x);
-        _velocity.x = 0.0f;
-    }
-    else if (shipPos.x > (_initialShipPos.x + MAP_LENGTH))
-    {
-        if (!_finished)
-        {
-            // Passed the finish line
-            _finished = true;
-            _finishedTime = getAbsoluteTime();
-            _pushing = false;
-        }
-    }
-}
-
-void SpaceshipGame::updateCamera()
-{
-    if (_finished)
-        return;
-
-    // Keep the camera focused on the ship
-    const Vector3& cameraPos = _cameraNode->getTranslation();
-    const Vector3& shipPos = _shipGroupNode->getTranslation();
-    float diff = cameraPos.x - shipPos.x;
-    if (diff > CAMERA_RANGE_BACK)
-    {
-        _cameraNode->translateX(-(diff - CAMERA_RANGE_BACK));
-    }
-    else if (diff < -CAMERA_RANGE_FRONT)
-    {
-        _cameraNode->translateX(-(diff + CAMERA_RANGE_FRONT));
-    }
-}
-
-void SpaceshipGame::resetGame()
-{
-    _time = 0;
-    _finished = false;
-    _velocity.set(0, 0);
-    _shipGroupNode->setTranslation(_initialShipPos);
-    _cameraNode->setTranslation(_initialCameraPos);
-    _hitSomething = false;
-}
-
-void SpaceshipGame::render(float elapsedTime)
-{
-    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
-
-    // Visit scene nodes for opaque drawing
-    _scene->visit(this, &SpaceshipGame::drawScene, (void*)0);
-
-    // Visit scene nodes for transparent drawing
-    _scene->visit(this, &SpaceshipGame::drawScene, (void*)1);
-
-    // Draw game text (yellow)
-    drawText();
-}
-
-void SpaceshipGame::drawSplash(void* param)
-{
-    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
-    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
-    batch->start();
-    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
-    batch->finish();
-    SAFE_DELETE(batch);
-}
-
-bool SpaceshipGame::drawScene(Node* node, void* cookie)
-{
-    Model* model = node->getModel();
-    if (model)
-    {
-        // Transparent nodes must be drawn last (stage 1)
-        bool isTransparent = (node == _glowNode);
-
-        // Skip transparent objects for stage 0
-        if ((!isTransparent && (int*)cookie == 0) || (isTransparent && (int*)cookie == (int*)1))
-            model->draw();
-    }
-
-    return true;
-}
-
-void SpaceshipGame::drawText()
-{
-    _font->start();
-    char text[1024];
-    sprintf(text, "%dsec.", (int)_time);
-    _font->drawText(text, getWidth() - 120, 10, Vector4(1, 1, 0, 1), _font->getSize());
-    if (_finished)
-    {
-        _font->drawText("Click to Play Again", getWidth()/2 - 175, getHeight()/2 - 40, Vector4::one(), _font->getSize());
-    }
-    _font->finish();
-}
-
-void SpaceshipGame::keyEvent(Keyboard::KeyEvent evt, int key)
-{
-    if (evt == Keyboard::KEY_PRESS)
-    {
-        switch (key)
-        {
-        case Keyboard::KEY_ESCAPE:
-            exit();
-            break;
-        }
-    }
-}
-
-void SpaceshipGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
-{
-    switch (evt)
-    {
-    case Touch::TOUCH_PRESS:
-        if (_finished && (getAbsoluteTime() - _finishedTime) > 1000L)
-        {
-            resetGame();
-        }
-    case Touch::TOUCH_MOVE:
-        if (!_finished)
-        {
-            _pushing = true;
-            _pushPoint.set(x, y);
-        }
-        break;
-
-    case Touch::TOUCH_RELEASE:
-        _pushing = false;
-        break;
-    }
-}
-
-
-
+#include "SpaceshipGame.h"
+
+// Declare our game instance
+SpaceshipGame game;
+
+// Collision constants
+#define ROOF_HEIGHT 11.6f
+#define FLOOR_HEIGHT 0.6f
+#define MAP_LENGTH 1000.0f
+#define CAMERA_RANGE_FRONT -1
+#define CAMERA_RANGE_BACK 8
+
+// Mass of the space ship
+#define MASS 50.0f
+
+// Gravity constant (earth's gravity is ~9.8m/s/s)
+#define GRAVITY 9.8f
+
+// Force applied due to gravity (F = mg)
+#define GRAVITATIONAL_FORCE (MASS * GRAVITY)
+
+// Normal force used in friction computations (Fn = -mg)
+#define FORCE_NORMAL (-GRAVITATIONAL_FORCE)
+
+// Friction between floor and spaceship (Ff = u * Fn)
+#define FLOOR_FRICTION (0.4f * FORCE_NORMAL)
+
+// Friction between roof and spaceship (Ff = u * Fn)
+#define ROOF_FRICTION (0.035f * FORCE_NORMAL)
+
+// Distance from space ship (screen-space) after which force is no longer applied to the ship
+#define TOUCH_DISTANCE_MAX 400.0f
+
+// Amount to scale screen-space push/force vector by
+#define FORCE_SCALE 4.0f
+
+// Constant for the maximum force that can be applied to the ship
+#define FORCE_MAX (TOUCH_DISTANCE_MAX * FORCE_SCALE)
+
+// Maximum velocity (+/-)
+#define VELOCITY_MAX 75.0f
+
+// Maximum ship tilt (degrees)
+#define SHIP_TILT_MAX 45.0f
+
+// Maximum ship rotation (degrees) at full throttle
+#define SHIP_ROTATE_SPEED_MAX 500.0f
+
+// Multiplier for engine glow effect (based on throttle)
+#define ENGINE_POWER 2.5f
+
+// Multiplier for sound pitch (based on throttle)
+#define SOUND_PITCH_SCALE 2.0f
+
+// Lighting constants
+#define AMBIENT_LIGHT_COLOR Vector3(0.2f, 0.2f, 0.2f)
+#define SPECULAR 20.0f
+
+// Clamp function
+#define CLAMP(x, min, max) (x < min ? min : (x > max ? max : x))
+
+SpaceshipGame::SpaceshipGame()
+    : _scene(NULL), _cameraNode(NULL), _shipGroupNode(NULL), _shipNode(NULL), _propulsionNode(NULL), _glowNode(NULL),
+      _stateBlock(NULL), _font(NULL), _throttle(0), _shipTilt(0), _finished(true), _finishedTime(0), _pushing(false), _time(0),
+       _glowDiffuseParameter(NULL), _shipSpecularParameter(NULL), _spaceshipSound(NULL)
+{
+}
+
+SpaceshipGame::~SpaceshipGame()
+{
+}
+
+void SpaceshipGame::initialize()
+{
+    // TODO: Not working on iOS
+    // Display the gameplay splash screen for at least 1 second.
+    displayScreen(this, &SpaceshipGame::drawSplash, NULL, 1000L);
+
+    // Create our render state block that will be reused across all materials
+    _stateBlock = RenderState::StateBlock::create();
+    _stateBlock->setDepthTest(true);
+    _stateBlock->setCullFace(true);
+    _stateBlock->setBlend(true);
+    _stateBlock->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
+    _stateBlock->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
+
+    // Load our scene from file
+    _scene = Scene::load("res/spaceship.gpb");
+
+    // Update the aspect ratio for our scene's camera to match the current device resolution
+    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
+
+    // Initialize scene data
+    initializeSpaceship();
+    initializeEnvironment();
+
+    // Create a background audio track
+    _backgroundSound = AudioSource::create("res/background.ogg");
+    if (_backgroundSound)
+        _backgroundSound->setLooped(true);
+
+    // Create font
+    _font = Font::create("res/airstrip.gpb");
+
+    // Store camera node
+    _cameraNode = _scene->findNode("camera1");
+
+    // Store initial ship and camera positions
+    _initialShipPos = _shipGroupNode->getTranslation();
+    _initialShipRot = _shipGroupNode->getRotation();
+    _initialCameraPos = _cameraNode->getTranslation();
+}
+
+void SpaceshipGame::initializeSpaceship()
+{
+    Material* material;
+
+    _shipGroupNode = _scene->findNode("gSpaceShip");
+
+    // Setup spaceship model
+    // Part 0
+    _shipNode = _scene->findNode("pSpaceShip");
+    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 0);
+    material->getParameter("u_diffuseColor")->setValue(Vector4(0.53544f, 0.53544f, 0.53544f, 1.0f));
+    initializeMaterial(material, true, true);
+    // Part 1
+    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 1);
+    material->getParameter("u_diffuseColor")->setValue(Vector4(0.8f, 0.8f, 0.8f, 1.0f));
+    _shipSpecularParameter = material->getParameter("u_specularExponent");
+    initializeMaterial(material, true, true);
+    // Part 2
+    material = _shipNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1", 2);
+    material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
+    initializeMaterial(material, true, true);
+
+    // Setup spaceship propulsion model
+    _propulsionNode = _scene->findNode("pPropulsion");
+    material = _propulsionNode->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
+    material->getParameter("u_diffuseColor")->setValue(Vector4(0.8f, 0.8f, 0.8f, 1.0f));
+    initializeMaterial(material, true, true);
+
+    // Glow effect node
+    _glowNode = _scene->findNode("pGlow");
+    material = _glowNode->getModel()->setMaterial("res/shaders/textured.vert", "res/shaders/textured.frag", "MODULATE_COLOR");
+    material->getParameter("u_diffuseTexture")->setValue("res/propulsion_glow.png", true);
+    _glowDiffuseParameter = material->getParameter("u_modulateColor");
+    initializeMaterial(material, false, false);
+
+    // Setup the sound
+    _spaceshipSound = AudioSource::create("res/spaceship.wav");
+    if (_spaceshipSound)
+    {
+        _spaceshipSound->setLooped(true);
+    }
+}
+
+void SpaceshipGame::initializeEnvironment()
+{
+    Material* material;
+    std::vector<Node*> nodes;
+
+    // Setup ground model
+    _scene->findNodes("pGround", nodes, true, false);
+    for (size_t i = 0, count = nodes.size(); i < count; ++i)
+    {
+        Node* pGround = nodes[i];
+        material = pGround->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
+        material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
+        initializeMaterial(material, true, true);
+    }
+
+    // Setup roof model
+    nodes.clear();
+    _scene->findNodes("pRoof", nodes, true, false);
+    for (size_t i = 0, count = nodes.size(); i < count; ++i)
+    {
+        Node* pRoof = nodes[i];
+        material = pRoof->getModel()->setMaterial("res/shaders/colored.vert", "res/shaders/colored.frag", "SPECULAR;DIRECTIONAL_LIGHT_COUNT 1");
+        material->getParameter("u_diffuseColor")->setValue(Vector4(0.280584f, 0.5584863f, 0.6928f, 1.0f));
+        initializeMaterial(material, true, true);
+    }
+
+    // Setup background model
+    nodes.clear();
+    Node* pBackground = _scene->findNode("pBackground");
+    material = pBackground->getModel()->setMaterial("res/shaders/textured.vert", "res/shaders/textured.frag", "DIRECTIONAL_LIGHT_COUNT 1");
+    material->getParameter("u_diffuseTexture")->setValue("res/background.png", true);
+    initializeMaterial(material, true, false);
+}
+
+void SpaceshipGame::initializeMaterial(Material* material, bool lighting, bool specular)
+{
+    // Set the common render state block for the material
+    material->setStateBlock(_stateBlock);
+
+    // Bind the WorldViewProjection matrix
+    material->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX);
+
+    if (lighting)
+    {
+        // Apply lighting material parameters
+        material->setParameterAutoBinding("u_inverseTransposeWorldViewMatrix", RenderState::INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX);
+        material->getParameter("u_ambientColor")->setValue(AMBIENT_LIGHT_COLOR);
+
+        Node* lightNode = _scene->findNode("directionalLight1");
+        Vector3 lightDirection = lightNode->getForwardVector();
+        lightDirection.normalize();
+        if (lightNode)
+        {
+            material->getParameter("u_directionalLightColor[0]")->setValue(lightNode->getLight()->getColor());
+            material->getParameter("u_directionalLightDirection[0]")->setValue(lightDirection);
+        }
+
+        if (specular)
+        {
+            // Apply specular lighting parameters
+            material->getParameter("u_specularExponent")->setValue(SPECULAR);
+            material->setParameterAutoBinding("u_worldViewMatrix", RenderState::WORLD_VIEW_MATRIX);
+            material->setParameterAutoBinding("u_cameraPosition", RenderState::CAMERA_WORLD_POSITION);
+        }
+    }
+}
+
+void SpaceshipGame::finalize()
+{
+    SAFE_RELEASE(_backgroundSound);
+    SAFE_RELEASE(_spaceshipSound);
+    SAFE_RELEASE(_font);
+    SAFE_RELEASE(_stateBlock);
+    SAFE_RELEASE(_scene);
+}
+
+void SpaceshipGame::update(float elapsedTime)
+{
+    // Calculate elapsed time in seconds
+    float t = (float)elapsedTime / 1000.0;
+
+    if (!_finished)
+    {
+        _time += t;
+
+        // Play the background track
+        if (_backgroundSound->getState() != AudioSource::PLAYING)
+            _backgroundSound->play();
+    }
+    else
+    {
+        // Stop the background track
+        if (_backgroundSound->getState() == AudioSource::PLAYING || _backgroundSound->getState() == AudioSource::PAUSED)
+		{
+            _backgroundSound->stop();
+        	_throttle = 0.0f;
+		}
+    }
+
+    // Set initial force due to gravity
+    _force.set(0, -GRAVITATIONAL_FORCE);
+
+    // While we are pushing/touching the screen, apply a push force vector based on the distance from
+    // the touch point to the center of the space ship.
+    if (_pushing)
+    {
+        // Get the center point of the space ship in screen coordinates
+        Vector3 shipCenterScreen;
+        _scene->getActiveCamera()->project(getViewport(), _shipGroupNode->getBoundingSphere().center, &shipCenterScreen.x, &shipCenterScreen.y);
+
+        // Compute a screen-space vector between the center point of the ship and the touch point.
+        // We will use this vector to apply a "pushing" force to the space ship, similar to what
+        // happens when you hold a magnet close to an object with opposite polarity.
+        Vector2 pushForce((shipCenterScreen.x - _pushPoint.x), -(shipCenterScreen.y - _pushPoint.y));
+
+        // Transform the vector so that a smaller magnitude emits a larger force and applying the
+        // maximum touch distance.
+        float distance = (std::max)(TOUCH_DISTANCE_MAX - pushForce.length(), 0.0f);
+        pushForce.normalize();
+        pushForce.scale(distance * FORCE_SCALE);
+        _force.add(pushForce);
+
+        // Compute a throttle value based on our force vector, minus gravity
+        Vector2 throttleVector(_force.x, _force.y + GRAVITATIONAL_FORCE);
+        _throttle += throttleVector.length() / FORCE_MAX * t;
+    }
+    else
+    {
+        // Gradually decrease the throttle
+        if (_throttle > 0.0f)
+        {
+            _throttle *= 1.0f - t;
+        }
+    }
+
+    // Clamp the throttle
+    _throttle = CLAMP(_throttle, 0.0f, 1.0f);
+
+    // Update acceleration (a = F/m)
+    _acceleration.set(_force.x / MASS, _force.y / MASS);
+
+    // Update velocity (v1 = v0 + at)
+    _velocity.x += _acceleration.x * t;
+    _velocity.y += _acceleration.y * t;
+
+    // Clamp velocity to its maximum range
+    _velocity.x = CLAMP(_velocity.x, -VELOCITY_MAX, VELOCITY_MAX);
+    _velocity.y = CLAMP(_velocity.y, -VELOCITY_MAX, VELOCITY_MAX);
+
+    // Move the spaceship based on its current velocity (x1 = x0 + vt)
+    _shipGroupNode->translate(_velocity.x * t, _velocity.y * t, 0);
+
+    // Check for collisions
+    handleCollisions(t);
+
+    // Update camera
+    updateCamera();
+
+    // Reset ship rotation
+    _shipGroupNode->setRotation(_initialShipRot);
+
+    // Apply ship tilt
+    if (_force.x != 0 && fabs(_velocity.x) > 0.1f)
+    {
+        // Compute an angle based on the dot product between the force vector and the Y axis
+        Vector2 fn;
+        _force.normalize(&fn);
+        float angle = MATH_RAD_TO_DEG(acos(Vector2::dot(Vector2(0, 1), fn)));
+        if (_force.x > 0)
+            angle = -angle;
+        angle *= _throttle * t;
+        _shipTilt += angle;
+        _shipTilt = _shipTilt < -SHIP_TILT_MAX ? -SHIP_TILT_MAX : (_shipTilt > SHIP_TILT_MAX ? SHIP_TILT_MAX : _shipTilt);
+    }
+    else
+    {
+        // Interpolate tilt back towards zero when no force is applied
+        _shipTilt = (_shipTilt + ((0 - _shipTilt) * t * 2.0f));
+    }
+    _shipGroupNode->rotateZ(MATH_DEG_TO_RAD(_shipTilt));
+
+    if (_throttle > MATH_EPSILON)
+    {
+        // Apply ship spin
+        _shipNode->rotateY(MATH_DEG_TO_RAD(SHIP_ROTATE_SPEED_MAX * t * _throttle));
+
+        // Play sound effect
+        if (_spaceshipSound->getState() != AudioSource::PLAYING)
+            _spaceshipSound->play();
+
+        // Set the pitch based on the throttle
+        _spaceshipSound->setPitch(_throttle * SOUND_PITCH_SCALE);
+    }
+    else
+    {
+        // Stop sound effect
+        _spaceshipSound->stop();
+    }
+
+    // Modify ship glow effect based on the throttle
+    _glowDiffuseParameter->setValue(Vector4(1, 1, 1, _throttle * ENGINE_POWER));
+    _shipSpecularParameter->setValue(SPECULAR - ((SPECULAR-2.0f) * _throttle));
+}
+
+void SpaceshipGame::handleCollisions(float t)
+{
+    float friction = 0.0f;
+
+    // Use the ship's bounding sphere for roof collisions
+    const BoundingSphere& shipBounds = _shipNode->getBoundingSphere();
+
+    // Compute a bounding box for floor collisions
+    BoundingBox propulsionBounds = _propulsionNode->getModel()->getMesh()->getBoundingBox();
+    propulsionBounds.transform(_propulsionNode->getWorldMatrix());
+
+    if (propulsionBounds.min.y <= FLOOR_HEIGHT)
+    {
+        // Floor collision
+        friction = FLOOR_FRICTION;
+        _shipGroupNode->translateY(FLOOR_HEIGHT - propulsionBounds.min.y);
+        if (_velocity.y < 0.0f)
+        {
+            // Cancel vertical velocity
+            _velocity.y = 0.0f;
+        }
+    }
+    else if ((shipBounds.center.y + shipBounds.radius) >= ROOF_HEIGHT)
+    {
+        // Roof collision
+        friction = ROOF_FRICTION;
+        _shipGroupNode->translateY(ROOF_HEIGHT - (shipBounds.center.y + shipBounds.radius));
+        if (_velocity.y >= 0.0f)
+        {
+            // Cancel vertical velocity
+            _velocity.y = 0.0f;
+        }
+    }
+
+    // Apply friction to velocity
+    if (friction != 0.0f)
+    {
+        if (_velocity.x > 0)
+        {
+            _velocity.x = (std::max)(_velocity.x + friction * t, 0.0f);
+        }
+        else if (_velocity.x < 0)
+        {
+            _velocity.x = (std::min)(_velocity.x - friction  * t, 0.0f);
+        }
+		_hitSomething = true;
+    }
+
+    // Keep the ship within the playable area of the map
+    const Vector3& shipPos = _shipGroupNode->getTranslation();
+    if (shipPos.x < _initialShipPos.x)
+    {
+        _shipGroupNode->translateX(_initialShipPos.x - shipPos.x);
+        _velocity.x = 0.0f;
+    }
+    else if (shipPos.x > (_initialShipPos.x + MAP_LENGTH))
+    {
+        if (!_finished)
+        {
+            // Passed the finish line
+            _finished = true;
+            _finishedTime = getAbsoluteTime();
+            _pushing = false;
+        }
+    }
+}
+
+void SpaceshipGame::updateCamera()
+{
+    if (_finished)
+        return;
+
+    // Keep the camera focused on the ship
+    const Vector3& cameraPos = _cameraNode->getTranslation();
+    const Vector3& shipPos = _shipGroupNode->getTranslation();
+    float diff = cameraPos.x - shipPos.x;
+    if (diff > CAMERA_RANGE_BACK)
+    {
+        _cameraNode->translateX(-(diff - CAMERA_RANGE_BACK));
+    }
+    else if (diff < -CAMERA_RANGE_FRONT)
+    {
+        _cameraNode->translateX(-(diff + CAMERA_RANGE_FRONT));
+    }
+}
+
+void SpaceshipGame::resetGame()
+{
+    _time = 0;
+    _finished = false;
+    _velocity.set(0, 0);
+    _shipGroupNode->setTranslation(_initialShipPos);
+    _cameraNode->setTranslation(_initialCameraPos);
+    _hitSomething = false;
+}
+
+void SpaceshipGame::render(float elapsedTime)
+{
+    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
+
+    // Visit scene nodes for opaque drawing
+    _scene->visit(this, &SpaceshipGame::drawScene, (void*)0);
+
+    // Visit scene nodes for transparent drawing
+    _scene->visit(this, &SpaceshipGame::drawScene, (void*)1);
+
+    // Draw game text (yellow)
+    drawText();
+}
+
+void SpaceshipGame::drawSplash(void* param)
+{
+    clear(CLEAR_COLOR_DEPTH, Vector4(0, 0, 0, 1), 1.0f, 0);
+    SpriteBatch* batch = SpriteBatch::create("res/logo_powered_white.png");
+    batch->start();
+    batch->draw(this->getWidth() * 0.5f, this->getHeight() * 0.5f, 0.0f, 512.0f, 512.0f, 0.0f, 1.0f, 1.0f, 0.0f, Vector4::one(), true);
+    batch->finish();
+    SAFE_DELETE(batch);
+}
+
+bool SpaceshipGame::drawScene(Node* node, void* cookie)
+{
+    Model* model = node->getModel();
+    if (model)
+    {
+        // Transparent nodes must be drawn last (stage 1)
+        bool isTransparent = (node == _glowNode);
+
+        // Skip transparent objects for stage 0
+        if ((!isTransparent && (int*)cookie == 0) || (isTransparent && (int*)cookie == (int*)1))
+            model->draw();
+    }
+
+    return true;
+}
+
+void SpaceshipGame::drawText()
+{
+    _font->start();
+    char text[1024];
+    sprintf(text, "%dsec.", (int)_time);
+    _font->drawText(text, getWidth() - 120, 10, Vector4(1, 1, 0, 1), _font->getSize());
+    if (_finished)
+    {
+        _font->drawText("Click to Play Again", getWidth()/2 - 175, getHeight()/2 - 40, Vector4::one(), _font->getSize());
+    }
+    _font->finish();
+}
+
+void SpaceshipGame::keyEvent(Keyboard::KeyEvent evt, int key)
+{
+    if (evt == Keyboard::KEY_PRESS)
+    {
+        switch (key)
+        {
+        case Keyboard::KEY_ESCAPE:
+            exit();
+            break;
+        }
+    }
+}
+
+void SpaceshipGame::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+{
+    switch (evt)
+    {
+    case Touch::TOUCH_PRESS:
+        if (_finished && (getAbsoluteTime() - _finishedTime) > 1000L)
+        {
+            resetGame();
+        }
+    case Touch::TOUCH_MOVE:
+        if (!_finished)
+        {
+            _pushing = true;
+            _pushPoint.set(x, y);
+        }
+        break;
+
+    case Touch::TOUCH_RELEASE:
+        _pushing = false;
+        break;
+    }
+}
+
+
+

+ 152 - 152
samples/spaceship/src/SpaceshipGame.h

@@ -1,152 +1,152 @@
-#ifndef SPACESHIPGAME_H_
-#define SPACESHIPGAME_H_
-
-#include "gameplay.h"
-
-using namespace gameplay;
-
-/**
- * Spaceship game.
- */
-class SpaceshipGame : public Game
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    SpaceshipGame();
-
-    /**
-     * Destructor.
-     */
-    virtual ~SpaceshipGame();
-
-    /**
-     * @see Game::keyEvent
-     */
-    void keyEvent(Keyboard::KeyEvent evt, int key);
-
-    /**
-     * @see Game::touchEvent
-     */
-    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
-
-protected:
-
-    /**
-     * @see Game::initialize
-     */
-    void initialize();
-
-    /**
-     * @see Game::finalize
-     */
-    void finalize();
-
-    /**
-     * @see Game::update
-     */
-    void update(float elapsedTime);
-
-    /**
-     * @see Game::render
-     */
-    void render(float elapsedTime);
-
-
-
-private:
-
-    /**
-     * Initializes the spaceship.
-     */
-    void initializeSpaceship();
-
-    /**
-     * Initializes the environment including ground, roof and background.
-     */
-    void initializeEnvironment();
-
-    /**
-     * Initializes the material with common parameter bindings.
-     *
-     * @param lighting true if the material should receive lighting parameters.
-     * @param specular true if the material should receive specular lighting parameters.
-     */
-    void initializeMaterial(Material* material, bool lighting, bool specular);
-
-    /**
-     * Handles foe collisions with the ground and roof.
-     */
-    void handleCollisions(float t);
-
-    /**
-     * Updates the camera based on the ships position.
-     */
-    void updateCamera();
-
-    /**
-     * Resets the games
-     */
-    void resetGame();
-
-    /**
-     * Draws the default "gameplay powered" splash screen.
-     */
-    void drawSplash(void* param);
-
-    /**
-     * Draws the scene
-     */
-    bool drawScene(Node* node, void* cookie);
-
-    /**
-     * Draws the text.
-     */
-    void drawText();
-
-
-    // Scene variables
-    Scene* _scene;
-    Node* _cameraNode;
-    Node* _shipGroupNode;
-    Node* _shipNode;
-    Node* _propulsionNode;
-    Node* _glowNode;
-    RenderState::StateBlock* _stateBlock;
-    Vector3 _initialShipPos;
-    Quaternion _initialShipRot;
-    Vector3 _initialCameraPos;
-
-    // Font for text rendering
-    Font* _font;
-
-    // Ship physics variables
-    Vector2 _velocity;
-    Vector2 _acceleration;
-    Vector2 _force;
-    float _throttle;
-    float _shipTilt;
-
-    // State variables
-    bool _finished;
-    double _finishedTime;
-    bool _pushing;
-    Vector2 _pushPoint;
-
-    // Game time in seconds
-    float _time;
-
-    // Frequently updated material parameters
-    MaterialParameter* _glowDiffuseParameter;
-    MaterialParameter* _shipSpecularParameter;
-
-    // Sounds
-    AudioSource* _backgroundSound;
-    AudioSource* _spaceshipSound;
-
-    bool _hitSomething;
-};
-
-#endif
+#ifndef SPACESHIPGAME_H_
+#define SPACESHIPGAME_H_
+
+#include "gameplay.h"
+
+using namespace gameplay;
+
+/**
+ * Spaceship game.
+ */
+class SpaceshipGame : public Game
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    SpaceshipGame();
+
+    /**
+     * Destructor.
+     */
+    virtual ~SpaceshipGame();
+
+    /**
+     * @see Game::keyEvent
+     */
+    void keyEvent(Keyboard::KeyEvent evt, int key);
+
+    /**
+     * @see Game::touchEvent
+     */
+    void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+
+protected:
+
+    /**
+     * @see Game::initialize
+     */
+    void initialize();
+
+    /**
+     * @see Game::finalize
+     */
+    void finalize();
+
+    /**
+     * @see Game::update
+     */
+    void update(float elapsedTime);
+
+    /**
+     * @see Game::render
+     */
+    void render(float elapsedTime);
+
+
+
+private:
+
+    /**
+     * Initializes the spaceship.
+     */
+    void initializeSpaceship();
+
+    /**
+     * Initializes the environment including ground, roof and background.
+     */
+    void initializeEnvironment();
+
+    /**
+     * Initializes the material with common parameter bindings.
+     *
+     * @param lighting true if the material should receive lighting parameters.
+     * @param specular true if the material should receive specular lighting parameters.
+     */
+    void initializeMaterial(Material* material, bool lighting, bool specular);
+
+    /**
+     * Handles foe collisions with the ground and roof.
+     */
+    void handleCollisions(float t);
+
+    /**
+     * Updates the camera based on the ships position.
+     */
+    void updateCamera();
+
+    /**
+     * Resets the games
+     */
+    void resetGame();
+
+    /**
+     * Draws the default "gameplay powered" splash screen.
+     */
+    void drawSplash(void* param);
+
+    /**
+     * Draws the scene
+     */
+    bool drawScene(Node* node, void* cookie);
+
+    /**
+     * Draws the text.
+     */
+    void drawText();
+
+
+    // Scene variables
+    Scene* _scene;
+    Node* _cameraNode;
+    Node* _shipGroupNode;
+    Node* _shipNode;
+    Node* _propulsionNode;
+    Node* _glowNode;
+    RenderState::StateBlock* _stateBlock;
+    Vector3 _initialShipPos;
+    Quaternion _initialShipRot;
+    Vector3 _initialCameraPos;
+
+    // Font for text rendering
+    Font* _font;
+
+    // Ship physics variables
+    Vector2 _velocity;
+    Vector2 _acceleration;
+    Vector2 _force;
+    float _throttle;
+    float _shipTilt;
+
+    // State variables
+    bool _finished;
+    double _finishedTime;
+    bool _pushing;
+    Vector2 _pushPoint;
+
+    // Game time in seconds
+    float _time;
+
+    // Frequently updated material parameters
+    MaterialParameter* _glowDiffuseParameter;
+    MaterialParameter* _shipSpecularParameter;
+
+    // Sounds
+    AudioSource* _backgroundSound;
+    AudioSource* _spaceshipSound;
+
+    bool _hitSomething;
+};
+
+#endif

+ 95 - 95
template/android/template.build.xml

@@ -1,95 +1,95 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="TEMPLATE_PROJECT" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked into
-         Version Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The ant.properties file can be created by you. It is only edited by the
-         'android' tool to add properties to it.
-         This is the place to change some Ant specific build properties.
-         Here are some properties you may want to change/update:
-
-         source.dir
-             The name of the source directory. Default is 'src'.
-         out.dir
-             The name of the output directory. Default is 'bin'.
-
-         For other overridable properties, look at the beginning of the rules
-         files in the SDK, at tools/ant/build.xml
-
-         Properties related to the SDK location or the project target should
-         be updated using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems.
-
-         -->
-    <property file="ant.properties" />
-
-    <!-- The project.properties file is created and updated by the 'android'
-         tool, as well as ADT.
-
-         This contains project specific properties such as project target, and library
-         dependencies. Lower level build properties are stored in ant.properties
-         (or in .classpath for Eclipse projects).
-
-         This file is an integral part of the build system for your
-         application and should be checked into Version Control Systems. -->
-    <loadproperties srcFile="project.properties" />
-
-    <!-- quick check on sdk.dir -->
-    <fail
-            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
-            unless="sdk.dir"
-    />
-
-
-<!-- extension targets. Uncomment the ones where you want to do custom work
-     in between standard targets -->
-
-    <target name="-pre-build">
-		<mkdir dir="src"/>
-    </target>
-	
-<!--
-    <target name="-pre-compile">
-    </target>
-
-    /* This is typically used for code obfuscation.
-       Compiled code location: ${out.classes.absolute.dir}
-       If this is not done in place, override ${out.dex.input.absolute.dir} */
-       -->
-    <target name="-post-compile">
-    	<delete dir="assets/res"/>
-        <copy todir="assets/res">
-            <fileset dir="../res" />
-        </copy>
-        <copy todir="assets/res/shaders">
-            <fileset dir="../GAMEPLAY_PATH/gameplay/res/shaders" />
-       </copy>
-    </target>
-
-    <!-- Import the actual build file.
-
-         To customize existing targets, there are two options:
-         - Customize only one target:
-             - copy/paste the target into this file, *before* the
-               <import> task.
-             - customize it to your needs.
-         - Customize the whole content of build.xml
-             - copy/paste the content of the rules files (minus the top node)
-               into this file, replacing the <import> task.
-             - customize to your needs.
-
-         ***********************
-         ****** IMPORTANT ******
-         ***********************
-         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
-         in order to avoid having your file be overridden by tools such as "android update project"
-    -->
-    <!-- version-tag: 1 -->
-    <import file="${sdk.dir}/tools/ant/build.xml" />
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="TEMPLATE_PROJECT" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+            unless="sdk.dir"
+    />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+     in between standard targets -->
+
+    <target name="-pre-build">
+		<mkdir dir="src"/>
+    </target>
+	
+<!--
+    <target name="-pre-compile">
+    </target>
+
+    /* This is typically used for code obfuscation.
+       Compiled code location: ${out.classes.absolute.dir}
+       If this is not done in place, override ${out.dex.input.absolute.dir} */
+       -->
+    <target name="-post-compile">
+    	<delete dir="assets/res"/>
+        <copy todir="assets/res">
+            <fileset dir="../res" />
+        </copy>
+        <copy todir="assets/res/shaders">
+            <fileset dir="../GAMEPLAY_PATH/gameplay/res/shaders" />
+       </copy>
+    </target>
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>

+ 6 - 6
template/game.config

@@ -1,7 +1,7 @@
-window
-{
-    title = TEMPLATE_TITLE
-    width = 1280
-    height = 720
-    fullscreen = false
+window
+{
+    title = TEMPLATE_TITLE
+    width = 1280
+    height = 720
+    fullscreen = false
 }

+ 84 - 84
template/template.bar-descriptor.xml

@@ -1,84 +1,84 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>TEMPLATE_UUID</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>TEMPLATE_TITLE</name>
-
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>TEMPLATE_DESCRIPTION</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>TEMPLATE_AUTHOR</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-        <transparent>false</transparent>
-    </initialWindow>
-
-    <category>core.games</category>
-
-    <asset path="icon.png">icon.png</asset>
-    <asset path="res">res</asset>
-    <asset path="GAMEPLAY_PATH/gameplay/res/shaders">res/shaders</asset>
-    <asset path="GAMEPLAY_PATH/gameplay/res/ui">res/ui</asset>
-
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
-    </configuration>
-    <configuration name="Simulator">
-        <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
-    </configuration>
-
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-
-    <!-- The splash screen that will appear when your application is launching. Should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-
-    <!-- The permissions requested by your application. -->
-    <!--  <action>access_shared</action> -->
-    <!--  <action>record_audio</action> -->
-    <!--  <action>read_geolocation</action> -->
-    <!--  <action>use_camera</action> -->
-    <!--  <action>access_internet</action> -->
-    <!--  <action>play_audio</action> -->
-    <!--  <action>post_notification</action> -->
-    <!--  <action>set_audio_volume</action> -->
-    <!--  <action>read_device_identifying_information</action> -->
-
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-
-</qnx>
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
+
+<!-- BlackBerry OS application descriptor file.
+    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
+-->
+
+    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
+         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
+    <id>TEMPLATE_UUID</id>
+
+    <!-- The name that is displayed in the BlackBerry OS application installer. 
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <name>TEMPLATE_TITLE</name>
+
+    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
+         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
+         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
+    <versionNumber>1.0.0</versionNumber>
+
+    <!-- Fourth digit segment of the package version. First three segments are taken from the 
+         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
+    <buildId>1</buildId>
+
+    <!-- Description, displayed in the BlackBerry OS application installer.
+         May have multiple values for each language. See samples or xsd schema file. Optional. -->
+    <description>TEMPLATE_DESCRIPTION</description>
+
+    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
+    <author>TEMPLATE_AUTHOR</author>
+
+    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
+    <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
+
+    <initialWindow>
+        <aspectRatio>landscape</aspectRatio>
+        <autoOrients>false</autoOrients>
+        <systemChrome>none</systemChrome>
+        <transparent>false</transparent>
+    </initialWindow>
+
+    <category>core.games</category>
+
+    <asset path="icon.png">icon.png</asset>
+    <asset path="res">res</asset>
+    <asset path="GAMEPLAY_PATH/gameplay/res/shaders">res/shaders</asset>
+    <asset path="GAMEPLAY_PATH/gameplay/res/ui">res/ui</asset>
+
+    <configuration name="Device-Debug">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Debug/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
+    </configuration>
+    <configuration name="Device-Release">
+       <platformArchitecture>armle-v7</platformArchitecture>
+       <asset path="Device-Release/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
+    </configuration>
+    <configuration name="Simulator">
+        <platformArchitecture>x86</platformArchitecture>
+       <asset path="Simulator/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
+    </configuration>
+
+    <!-- The icon for the application, which should be 114x114. -->
+    <icon>
+        <image>icon.png</image>
+    </icon>
+
+    <!-- The splash screen that will appear when your application is launching. Should be 1280x720. -->
+    <!-- <splashscreen></splashscreen> -->
+
+    <!-- The permissions requested by your application. -->
+    <!--  <action>access_shared</action> -->
+    <!--  <action>record_audio</action> -->
+    <!--  <action>read_geolocation</action> -->
+    <!--  <action>use_camera</action> -->
+    <!--  <action>access_internet</action> -->
+    <!--  <action>play_audio</action> -->
+    <!--  <action>post_notification</action> -->
+    <!--  <action>set_audio_volume</action> -->
+    <!--  <action>read_device_identifying_information</action> -->
+
+    <!-- Ensure that shared libraries in the package are found at run-time. -->
+    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
+
+</qnx>

+ 87 - 87
template/template.project

@@ -1,87 +1,87 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>TEMPLATE_PROJECT</name>
-	<comment></comment>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-				<dictionary>
-					<key>?name?</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.append_environment</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value></value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildCommand</key>
-					<value>make</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.buildLocation</key>
-					<value>${workspace_loc:/TEMPLATE_PROJECT/Device-Debug}</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
-					<value>clean</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.contents</key>
-					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
-					<value>false</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
-					<value>all</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.stopOnError</key>
-					<value>true</value>
-				</dictionary>
-				<dictionary>
-					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
-					<value>true</value>
-				</dictionary>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-		<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
-		<nature>org.eclipse.cdt.core.ccnature</nature>
-	</natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>TEMPLATE_PROJECT</name>
+	<comment></comment>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+					<value>all</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>make</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildLocation</key>
+					<value>${workspace_loc:/TEMPLATE_PROJECT/Device-Debug}</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+					<value>all</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>true</value>
+				</dictionary>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+		<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+	</natures>
+</projectDescription>

+ 342 - 342
template/template.vcxproj

@@ -1,343 +1,343 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugMem|Win32">
-      <Configuration>DebugMem</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugMem|x64">
-      <Configuration>DebugMem</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>TEMPLATE_PROJECT</RootNamespace>
-    <ProjectGuid>{30BEE126-8B04-4F96-84A1-30CBF8B3E491}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
-    <CustomBuildBeforeTargets />
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(Configuration)\</OutDir>
-    <CustomBuildBeforeTargets />
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <ShowIncludes>false</ShowIncludes>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-      <RuntimeTypeInfo>true</RuntimeTypeInfo>
-      <ShowIncludes>false</ShowIncludes>
-      <PreprocessToFile>false</PreprocessToFile>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <PreBuildEvent>
-      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
-xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
-    </Link>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-      <Message>
-      </Message>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <None Include="bar-descriptor.xml">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="game.config" />
-    <None Include="icon.png" />
-    <None Include="res\demo.fbx" />
-    <None Include="res\demo.gpb" />
-    <None Include="res\demo.material" />
-    <None Include="res\demo.scene" />
-    <None Include="res\shaders\colored.frag" />
-    <None Include="res\shaders\colored.vert" />
-    <None Include="res\shaders\font.frag" />
-    <None Include="res\shaders\font.vert" />
-    <None Include="res\shaders\form.frag" />
-    <None Include="res\shaders\form.vert" />
-    <None Include="res\shaders\lighting.frag" />
-    <None Include="res\shaders\lighting.vert" />
-    <None Include="res\shaders\skinning-none.vert" />
-    <None Include="res\shaders\skinning.vert" />
-    <None Include="res\shaders\sprite.frag" />
-    <None Include="res\shaders\sprite.vert" />
-    <None Include="res\shaders\terrain.frag" />
-    <None Include="res\shaders\terrain.vert" />
-    <None Include="res\shaders\textured.frag" />
-    <None Include="res\shaders\textured.vert" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\TemplateGame.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\TemplateGame.h" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugMem|Win32">
+      <Configuration>DebugMem</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|x64">
+      <Configuration>DebugMem</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>TEMPLATE_PROJECT</RootNamespace>
+    <ProjectGuid>{30BEE126-8B04-4F96-84A1-30CBF8B3E491}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ShowIncludes>false</ShowIncludes>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GP_USE_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <ShowIncludes>false</ShowIncludes>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x86;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x86;GAMEPLAY_PATH\external-deps\openal\lib\windows\x86;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x86;GAMEPLAY_PATH\external-deps\glew\lib\windows\x86;GAMEPLAY_PATH\external-deps\png\lib\windows\x86;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x86;GAMEPLAY_PATH\gameplay\windows\x86\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+    <PreBuildEvent>
+      <Command>xcopy GAMEPLAY_PATH\gameplay\res\shaders res\shaders\* /s /y /d
+xcopy GAMEPLAY_PATH\gameplay\res\ui res\ui\* /s /y /d</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH\external-deps\lua\include;GAMEPLAY_PATH\external-deps\bullet\include;GAMEPLAY_PATH\gameplay\src;GAMEPLAY_PATH\external-deps\openal\include\AL;GAMEPLAY_PATH\external-deps\oggvorbis\include;GAMEPLAY_PATH\external-deps\png\include;GAMEPLAY_PATH\external-deps\zlib\include;GAMEPLAY_PATH\external-deps\glew\include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH\external-deps\lua\lib\windows\x64;GAMEPLAY_PATH\external-deps\bullet\lib\windows\x64;GAMEPLAY_PATH\external-deps\openal\lib\windows\x64;GAMEPLAY_PATH\external-deps\oggvorbis\lib\windows\x64;GAMEPLAY_PATH\external-deps\glew\lib\windows\x64;GAMEPLAY_PATH\external-deps\png\lib\windows\x64;GAMEPLAY_PATH\external-deps\zlib\lib\windows\x64;GAMEPLAY_PATH\gameplay\windows\x64\$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="bar-descriptor.xml">
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="game.config" />
+    <None Include="icon.png" />
+    <None Include="res\demo.fbx" />
+    <None Include="res\demo.gpb" />
+    <None Include="res\demo.material" />
+    <None Include="res\demo.scene" />
+    <None Include="res\shaders\colored.frag" />
+    <None Include="res\shaders\colored.vert" />
+    <None Include="res\shaders\font.frag" />
+    <None Include="res\shaders\font.vert" />
+    <None Include="res\shaders\form.frag" />
+    <None Include="res\shaders\form.vert" />
+    <None Include="res\shaders\lighting.frag" />
+    <None Include="res\shaders\lighting.vert" />
+    <None Include="res\shaders\skinning-none.vert" />
+    <None Include="res\shaders\skinning.vert" />
+    <None Include="res\shaders\sprite.frag" />
+    <None Include="res\shaders\sprite.vert" />
+    <None Include="res\shaders\terrain.frag" />
+    <None Include="res\shaders\terrain.vert" />
+    <None Include="res\shaders\textured.frag" />
+    <None Include="res\shaders\textured.vert" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\TemplateGame.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\TemplateGame.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
 </Project>

+ 26 - 26
template/template.vcxproj.user

@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x86;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x64;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-  </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x64;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
 </Project>

+ 44 - 44
tools/encoder/README.md

@@ -1,44 +1,44 @@
-## gameplay-encoder
-Command-line tool for encoding games assets like true-type fonts and 3D scene files
-into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
-The 'bin' folder contains pre-built versions of the gameplay-encoder executables for 
-Windows 7, MacOS X and Linux Ubuntu (32-bit) with support built-in support for:
-
-## TrueType Font
-TrueType Fonts represent a standard in defining outline fonts and has become the 
-most common format for fonts. The gameplay-encoder reads these fonts and binary encodes 
-them into a texture mapped base representation using a texture atlas and 8-bit alpha
-representation.
-
-## FBX Scene
-Autodesk® FBX® asset exchange technology facilitates higher-fidelity data exchange 
-between several Autodesk content creation packages
-Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
-For more information goto "http://www.autodesk.com/fbx".
-
-## Running gameplay-encoder
-Simply execute the gameplay-encoder command-line executable:
-
-`Usage: gameplay-encoder [options] <file(s)>`
-
-Note: On Linux Ubuntu (64-bit), you must first install the required 32-bit libs via:
-
-`sudo apt-get install ia32-libs`
-
-## Building gameplay-encoder
-
-See [Building gameplay-encoder](https://github.com/blackberry/GamePlay/wiki/Building-gameplay-encoder) on the wiki.
-
-## Bundle File Format
-The gameplay bundle file format is defined in the [tools/encoder/gameplay-bundle.txt](gameplay-bundle.txt) file.
-
-## Bundle File Loading
-Bundle files can easily be loaded using the `gameplay/Bundle.h` which is part of the gameplay runtime framework.
-
-## Disclaimer
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
-OTHER DEALINGS IN THE SOFTWARE.
+## gameplay-encoder
+Command-line tool for encoding games assets like true-type fonts and 3D scene files
+into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
+The 'bin' folder contains pre-built versions of the gameplay-encoder executables for 
+Windows 7, MacOS X and Linux Ubuntu (32-bit) with support built-in support for:
+
+## TrueType Font
+TrueType Fonts represent a standard in defining outline fonts and has become the 
+most common format for fonts. The gameplay-encoder reads these fonts and binary encodes 
+them into a texture mapped base representation using a texture atlas and 8-bit alpha
+representation.
+
+## FBX Scene
+Autodesk® FBX® asset exchange technology facilitates higher-fidelity data exchange 
+between several Autodesk content creation packages
+Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
+For more information goto "http://www.autodesk.com/fbx".
+
+## Running gameplay-encoder
+Simply execute the gameplay-encoder command-line executable:
+
+`Usage: gameplay-encoder [options] <file(s)>`
+
+Note: On Linux Ubuntu (64-bit), you must first install the required 32-bit libs via:
+
+`sudo apt-get install ia32-libs`
+
+## Building gameplay-encoder
+
+See [Building gameplay-encoder](https://github.com/blackberry/GamePlay/wiki/Building-gameplay-encoder) on the wiki.
+
+## Bundle File Format
+The gameplay bundle file format is defined in the [tools/encoder/gameplay-bundle.txt](gameplay-bundle.txt) file.
+
+## Bundle File Loading
+Bundle files can easily be loaded using the `gameplay/Bundle.h` which is part of the gameplay runtime framework.
+
+## Disclaimer
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+OTHER DEALINGS IN THE SOFTWARE.

+ 233 - 233
tools/encoder/gameplay-bundle.txt

@@ -1,233 +1,233 @@
-gameplay Bundle File Format (.gpb)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-File Description
-================
-A simple binary bundle file format supporting definition of primitive and built-in objects.
-
-File Extension and Mime Type
-============================
-File extension is '.gpb' and the mime type is 'application/gpb'
-
-File Structure
-==============
-
-Section      Name            Type
-------------------------------------------------------------------------------------------------------
-Header
-             Identifier      byte[9]     = { '\xAB', 'G', 'P', 'B', '\xBB', '\r', '\n', '\x1A', '\n' } 
-             Version         byte[2]     = { 1, 1 }
-             References      Reference[]
-Data
-             Objects         Object[]
-
-Objects
-=======
-Supported object types are defined in the table below. Object with unique ids are included
-in the Reference table (see below).
-
-References
-==========
-A Reference is an Object that has a unique id. The Reference contains the unique id of the
-object, a uint for the TypeID a uint for the offset into the package for the object definition.
-
-ID's
-====
-Object ID's are represented as a string which is guaranteed to be unique per file.
-Any object which host an object id should be added to the header Reference table so that it can
-be consumed by reference internally and externally.
-
-Xrefs
-=====
-Xrefs are string with a specific format used for referencing objects internal and external to
-a package. An xref with the format "#id" references an object within the current package with
-the given ID. Xrefs can also have the format "file#id", where "file" is the name of package file
-(relative to the location of the current package) and "id" is the unique identifier of an object
-in that bundle.
-
-Primitives
-==========
-
-Name            Description
-------------------------------------------------------------------------------------------------------
-string          8-bit char array prefixed by unint for length encoding.
-bool            8-bit unsigned char   false=0, true=1.
-byte            8-bit unsigned char
-uint            32-bit unsigned int, stored as four bytes, lowest byte first.
-int             32-bit signed int, stored as four bytes, lowest byte first.
-float           32-bit float, stored as four bytes, with the least significant 
-                    byte of the mantissa first, and the exponent byte last.
-enum X          A uint which is restricted to values from the given enum name "X".
-
-Arrays
-======
-Arrays of constant length are simply the array of data for the expected type. 
-Arrays of dynamic size length(uint) encoded followed by expected type of data.
-Notation:   byte[3]  - constant length notation = byte[3]
-            int[]    - dynamic length notation = length+int[count]
-            Mesh[]   - dynamic length notation = length+Mesh[count]
-
-Enums
-=====
-
-enum VertexUsage
-{
-    POSITION = 1,
-    NORMAL = 2,
-    COLOR = 3,
-    TANGENT = 4,
-    BINORMAL = 5,
-    BLENDWEIGHTS = 6,
-    BLENDINDICES = 7,
-    TEXCOORD0 = 8,
-    TEXCOORD1 = 9,
-    TEXCOORD2 = 10,
-    TEXCOORD3 = 11,
-    TEXCOORD4 = 12,
-    TEXCOORD5 = 13,
-    TEXCOORD6 = 14,
-    TEXCOORD7 = 15
-}
-
-enum FontStyle
-{
-    PLAIN = 0,
-    BOLD = 1,
-    ITALIC = 2,
-    BOLD_ITALIC = 4
-}
-
-enum FontFormat
-{
-    BITMAP = 0,
-    DISTANCE_FIELD = 1
-}
-
-enum PrimitiveType
-{
-    TRIANGLES = GL_TRIANGLES (4),
-    TRIANGLE_STRIP = GL_TRIANGLE_STRIP (5),
-    LINES = GL_LINES (1),
-    LINE_STRIP = GL_LINE_STRIP (3),
-    POINTS = GL_POINTS (0)
-}
-
-enum IndexFormat
-{
-    INDEX8 = GL_UNSIGNED_BYTE (0x1401),
-    INDEX16 = GL_UNSIGNED_SHORT (0x1403),
-    INDEX32 = GL_UNSIGNED_INT (0x1405)
-}
-
-enum NodeType
-{
-    NODE = 1,
-    JOINT = 2
-}
-
-
-Object Definitions
-==================
-TypeID->Name    Member                  Type
-------------------------------------------------------------------------------------------------------
-Reference
-                id                      string
-                type                    uint
-                offset                  uint
-------------------------------------------------------------------------------------------------------
-1->Scene
-                nodes                   Node[]
-                activeCameraNode        xref:Node
-                ambientColor            float[3]
-------------------------------------------------------------------------------------------------------
-2->Node
-                type                    enum NodeType
-                transform               float[16]
-                parent_id               string
-                children                Node[]
-                camera                  Camera
-                light                   Light
-                model                   Model
-------------------------------------------------------------------------------------------------------
-3->Animations
-                animations              Animation[]
-------------------------------------------------------------------------------------------------------
-4->Animation
-                id                      string
-                channels                AnimationChannel[]
------------------------------------------------------------------------------------------------------
-5->AnimationChannel
-                targetId                string
-                targetAttribute         uint
-                keyTimes                uint[]  (milliseconds)
-                values                  float[]
-                tangents_in             float[]
-                tangents_out            float[]
-                interpolation           uint[]
-------------------------------------------------------------------------------------------------------
-11->Model
-                mesh                    xref:Mesh
-                meshSkin                MeshSkin
-                materials               Material[]
-------------------------------------------------------------------------------------------------------
-16->Material
-                parameters              MaterialParameter[] { string name, float[] value, uint type }
-                effect                  xref:Effect
-------------------------------------------------------------------------------------------------------
-17->Effect
-                vertexShader            string
-                fragmentShader          string
-------------------------------------------------------------------------------------------------------
-32->Camera
-                cameraType              byte {perspective|orthographic}
-                aspectRatio             float
-                nearPlane               float
-                farPlane                float
-                [ cameraType : perspective
-                  fieldOfView           float
-                ]
-                [ cameraType : orthographic
-                  magnification         float[2]
-                ]
-------------------------------------------------------------------------------------------------------
-33->Light
-                lightType               byte {directional|point|spot}
-                color                   float[3]
-                [ lightType : point
-                  range                 float
-                ]
-                [ lightType : spot
-                  range                 float 
-                  innerAngle            float (in radians)
-                  outerAngle            float (in radians)
-                ]
-------------------------------------------------------------------------------------------------------
-34->Mesh
-                vertexFormat            VertexElement[] { enum VertexUsage usage, unint size }
-                vertices                byte[]
-                boundingBox             BoundingBox { float[3] min, float[3] max }
-                boundingSphere          BoundingSphere { float[3] center, float radius }
-                parts                   MeshPart[]
-------------------------------------------------------------------------------------------------------
-35->MeshPart
-                primitiveType           enum PrimitiveType
-                indexFormat             enum IndexFormat
-                indices                 byte[]
-------------------------------------------------------------------------------------------------------
-36->MeshSkin
-                bindShape               float[16]
-                joints                  xref:Node[]
-                jointsBindPoses         float[] // 16 * joints.length
-                boundingBox             BoundingBox { float[3] min, float[3] max }
-                boundingSphere          BoundingSphere { float[3] center, float radius }
-------------------------------------------------------------------------------------------------------
-128->Font
-                family                  string
-                style                   enum FontStyle
-                size                    uint
-                charset                 string
-                glyphs                  Glyph[] { uint index, uint width, float[4] uvCoords }
-                texMapWidth             uint
-                texMapHeight            uint
-                texMap                  byte[]
-                format                  enum FontFormat      @since version [1,3]
+gameplay Bundle File Format (.gpb)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+File Description
+================
+A simple binary bundle file format supporting definition of primitive and built-in objects.
+
+File Extension and Mime Type
+============================
+File extension is '.gpb' and the mime type is 'application/gpb'
+
+File Structure
+==============
+
+Section      Name            Type
+------------------------------------------------------------------------------------------------------
+Header
+             Identifier      byte[9]     = { '\xAB', 'G', 'P', 'B', '\xBB', '\r', '\n', '\x1A', '\n' } 
+             Version         byte[2]     = { 1, 1 }
+             References      Reference[]
+Data
+             Objects         Object[]
+
+Objects
+=======
+Supported object types are defined in the table below. Object with unique ids are included
+in the Reference table (see below).
+
+References
+==========
+A Reference is an Object that has a unique id. The Reference contains the unique id of the
+object, a uint for the TypeID a uint for the offset into the package for the object definition.
+
+ID's
+====
+Object ID's are represented as a string which is guaranteed to be unique per file.
+Any object which host an object id should be added to the header Reference table so that it can
+be consumed by reference internally and externally.
+
+Xrefs
+=====
+Xrefs are string with a specific format used for referencing objects internal and external to
+a package. An xref with the format "#id" references an object within the current package with
+the given ID. Xrefs can also have the format "file#id", where "file" is the name of package file
+(relative to the location of the current package) and "id" is the unique identifier of an object
+in that bundle.
+
+Primitives
+==========
+
+Name            Description
+------------------------------------------------------------------------------------------------------
+string          8-bit char array prefixed by unint for length encoding.
+bool            8-bit unsigned char   false=0, true=1.
+byte            8-bit unsigned char
+uint            32-bit unsigned int, stored as four bytes, lowest byte first.
+int             32-bit signed int, stored as four bytes, lowest byte first.
+float           32-bit float, stored as four bytes, with the least significant 
+                    byte of the mantissa first, and the exponent byte last.
+enum X          A uint which is restricted to values from the given enum name "X".
+
+Arrays
+======
+Arrays of constant length are simply the array of data for the expected type. 
+Arrays of dynamic size length(uint) encoded followed by expected type of data.
+Notation:   byte[3]  - constant length notation = byte[3]
+            int[]    - dynamic length notation = length+int[count]
+            Mesh[]   - dynamic length notation = length+Mesh[count]
+
+Enums
+=====
+
+enum VertexUsage
+{
+    POSITION = 1,
+    NORMAL = 2,
+    COLOR = 3,
+    TANGENT = 4,
+    BINORMAL = 5,
+    BLENDWEIGHTS = 6,
+    BLENDINDICES = 7,
+    TEXCOORD0 = 8,
+    TEXCOORD1 = 9,
+    TEXCOORD2 = 10,
+    TEXCOORD3 = 11,
+    TEXCOORD4 = 12,
+    TEXCOORD5 = 13,
+    TEXCOORD6 = 14,
+    TEXCOORD7 = 15
+}
+
+enum FontStyle
+{
+    PLAIN = 0,
+    BOLD = 1,
+    ITALIC = 2,
+    BOLD_ITALIC = 4
+}
+
+enum FontFormat
+{
+    BITMAP = 0,
+    DISTANCE_FIELD = 1
+}
+
+enum PrimitiveType
+{
+    TRIANGLES = GL_TRIANGLES (4),
+    TRIANGLE_STRIP = GL_TRIANGLE_STRIP (5),
+    LINES = GL_LINES (1),
+    LINE_STRIP = GL_LINE_STRIP (3),
+    POINTS = GL_POINTS (0)
+}
+
+enum IndexFormat
+{
+    INDEX8 = GL_UNSIGNED_BYTE (0x1401),
+    INDEX16 = GL_UNSIGNED_SHORT (0x1403),
+    INDEX32 = GL_UNSIGNED_INT (0x1405)
+}
+
+enum NodeType
+{
+    NODE = 1,
+    JOINT = 2
+}
+
+
+Object Definitions
+==================
+TypeID->Name    Member                  Type
+------------------------------------------------------------------------------------------------------
+Reference
+                id                      string
+                type                    uint
+                offset                  uint
+------------------------------------------------------------------------------------------------------
+1->Scene
+                nodes                   Node[]
+                activeCameraNode        xref:Node
+                ambientColor            float[3]
+------------------------------------------------------------------------------------------------------
+2->Node
+                type                    enum NodeType
+                transform               float[16]
+                parent_id               string
+                children                Node[]
+                camera                  Camera
+                light                   Light
+                model                   Model
+------------------------------------------------------------------------------------------------------
+3->Animations
+                animations              Animation[]
+------------------------------------------------------------------------------------------------------
+4->Animation
+                id                      string
+                channels                AnimationChannel[]
+-----------------------------------------------------------------------------------------------------
+5->AnimationChannel
+                targetId                string
+                targetAttribute         uint
+                keyTimes                uint[]  (milliseconds)
+                values                  float[]
+                tangents_in             float[]
+                tangents_out            float[]
+                interpolation           uint[]
+------------------------------------------------------------------------------------------------------
+11->Model
+                mesh                    xref:Mesh
+                meshSkin                MeshSkin
+                materials               Material[]
+------------------------------------------------------------------------------------------------------
+16->Material
+                parameters              MaterialParameter[] { string name, float[] value, uint type }
+                effect                  xref:Effect
+------------------------------------------------------------------------------------------------------
+17->Effect
+                vertexShader            string
+                fragmentShader          string
+------------------------------------------------------------------------------------------------------
+32->Camera
+                cameraType              byte {perspective|orthographic}
+                aspectRatio             float
+                nearPlane               float
+                farPlane                float
+                [ cameraType : perspective
+                  fieldOfView           float
+                ]
+                [ cameraType : orthographic
+                  magnification         float[2]
+                ]
+------------------------------------------------------------------------------------------------------
+33->Light
+                lightType               byte {directional|point|spot}
+                color                   float[3]
+                [ lightType : point
+                  range                 float
+                ]
+                [ lightType : spot
+                  range                 float 
+                  innerAngle            float (in radians)
+                  outerAngle            float (in radians)
+                ]
+------------------------------------------------------------------------------------------------------
+34->Mesh
+                vertexFormat            VertexElement[] { enum VertexUsage usage, unint size }
+                vertices                byte[]
+                boundingBox             BoundingBox { float[3] min, float[3] max }
+                boundingSphere          BoundingSphere { float[3] center, float radius }
+                parts                   MeshPart[]
+------------------------------------------------------------------------------------------------------
+35->MeshPart
+                primitiveType           enum PrimitiveType
+                indexFormat             enum IndexFormat
+                indices                 byte[]
+------------------------------------------------------------------------------------------------------
+36->MeshSkin
+                bindShape               float[16]
+                joints                  xref:Node[]
+                jointsBindPoses         float[] // 16 * joints.length
+                boundingBox             BoundingBox { float[3] min, float[3] max }
+                boundingSphere          BoundingSphere { float[3] center, float radius }
+------------------------------------------------------------------------------------------------------
+128->Font
+                family                  string
+                style                   enum FontStyle
+                size                    uint
+                charset                 string
+                glyphs                  Glyph[] { uint index, uint width, float[4] uvCoords }
+                texMapWidth             uint
+                texMapHeight            uint
+                texMap                  byte[]
+                format                  enum FontFormat      @since version [1,3]

+ 20 - 20
tools/encoder/gameplay-encoder.sln

@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-encoder", "gameplay-encoder.vcxproj", "{9D69B743-4872-4DD1-8E30-0087C64298D7}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Debug|Win32.Build.0 = Debug|Win32
-		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.ActiveCfg = Release|Win32
-		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-encoder", "gameplay-encoder.vcxproj", "{9D69B743-4872-4DD1-8E30-0087C64298D7}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Debug|Win32.Build.0 = Debug|Win32
+		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.ActiveCfg = Release|Win32
+		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 305 - 305
tools/encoder/gameplay-encoder.vcxproj.filters

@@ -1,306 +1,306 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <ClCompile Include="src\Animation.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\AnimationChannel.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Animations.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Base.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\BoundingVolume.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Camera.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Effect.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\EncoderArguments.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\FBXSceneEncoder.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\FileIO.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Font.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Glyph.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\GPBDecoder.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\GPBFile.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Light.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\main.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Material.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\MaterialParameter.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Matrix.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Mesh.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\MeshPart.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\MeshSkin.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Model.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Node.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Object.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Quaternion.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Reference.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\ReferenceTable.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Scene.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\StringUtil.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Transform.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\TTFFontEncoder.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Vector2.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Vector3.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Vector4.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Vertex.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\VertexElement.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Curve.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Heightmap.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Image.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\NormalMapGenerator.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Constants.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\FBXUtil.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\MeshSubSet.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\Sampler.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="src\edtaa3func.c">
-      <Filter>src</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\VertexElement.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Animation.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\AnimationChannel.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Animations.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Base.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\BoundingVolume.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Camera.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Effect.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\EncoderArguments.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\FBXSceneEncoder.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\FileIO.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Font.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Glyph.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\GPBDecoder.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\GPBFile.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Light.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Material.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\MaterialParameter.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Matrix.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Mesh.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\MeshPart.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\MeshSkin.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Model.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Node.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Object.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Quaternion.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Reference.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\ReferenceTable.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Scene.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\StringUtil.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Transform.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\TTFFontEncoder.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Vector2.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Vector3.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Vector4.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Vertex.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Curve.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Thread.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Heightmap.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Image.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\NormalMapGenerator.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Constants.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\FBXUtil.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\MeshSubSet.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\Sampler.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\edtaa3func.h">
-      <Filter>src</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="src\Vector2.inl">
-      <Filter>src</Filter>
-    </None>
-    <None Include="src\Vector3.inl">
-      <Filter>src</Filter>
-    </None>
-    <None Include="src\Vector4.inl">
-      <Filter>src</Filter>
-    </None>
-    <None Include="src\Quaternion.inl">
-      <Filter>src</Filter>
-    </None>
-    <None Include="src\Curve.inl">
-      <Filter>src</Filter>
-    </None>
-    <None Include="gameplay-bundle.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <Filter Include="src">
-      <UniqueIdentifier>{6393521c-00fb-48f6-b480-87f8d978a74f}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="src\Animation.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\AnimationChannel.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Animations.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Base.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\BoundingVolume.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Camera.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Effect.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\EncoderArguments.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\FBXSceneEncoder.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\FileIO.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Font.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Glyph.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\GPBDecoder.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\GPBFile.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Light.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\main.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Material.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\MaterialParameter.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Matrix.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Mesh.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\MeshPart.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\MeshSkin.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Model.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Node.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Object.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Quaternion.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Reference.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\ReferenceTable.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Scene.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\StringUtil.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Transform.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\TTFFontEncoder.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Vector2.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Vector3.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Vector4.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Vertex.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\VertexElement.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Curve.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Heightmap.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Image.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\NormalMapGenerator.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Constants.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\FBXUtil.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\MeshSubSet.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Sampler.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\edtaa3func.c">
+      <Filter>src</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="src\VertexElement.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Animation.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\AnimationChannel.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Animations.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Base.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\BoundingVolume.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Camera.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Effect.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\EncoderArguments.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\FBXSceneEncoder.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\FileIO.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Font.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Glyph.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\GPBDecoder.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\GPBFile.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Light.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Material.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\MaterialParameter.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Matrix.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Mesh.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\MeshPart.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\MeshSkin.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Model.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Node.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Object.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Quaternion.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Reference.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\ReferenceTable.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Scene.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\StringUtil.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Transform.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\TTFFontEncoder.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Vector2.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Vector3.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Vector4.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Vertex.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Curve.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Thread.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Heightmap.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Image.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\NormalMapGenerator.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Constants.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\FBXUtil.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\MeshSubSet.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Sampler.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\edtaa3func.h">
+      <Filter>src</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="src\Vector2.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Vector3.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Vector4.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Quaternion.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Curve.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="gameplay-bundle.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{6393521c-00fb-48f6-b480-87f8d978a74f}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
 </Project>

+ 18 - 18
tools/encoder/gameplay-encoder.vcxproj.user

@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerCommandArguments>
-    </LocalDebuggerCommandArguments>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerEnvironment>
-    </LocalDebuggerEnvironment>
-    <LocalDebuggerWorkingDirectory>.\Debug</LocalDebuggerWorkingDirectory>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>
-    </LocalDebuggerEnvironment>
-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>
-    </LocalDebuggerCommandArguments>
-    <LocalDebuggerWorkingDirectory>.\Release</LocalDebuggerWorkingDirectory>
-  </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommandArguments>
+    </LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerEnvironment>
+    </LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>.\Debug</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerEnvironment>
+    </LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>
+    </LocalDebuggerCommandArguments>
+    <LocalDebuggerWorkingDirectory>.\Release</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
 </Project>

+ 74 - 74
tools/encoder/src/Animation.cpp

@@ -1,74 +1,74 @@
-#include "Base.h"
-#include "Animation.h"
-
-namespace gameplay
-{
-
-Animation::Animation(void)
-{
-}
-
-Animation::~Animation(void)
-{
-}
-
-unsigned int Animation::getTypeId(void) const
-{
-    return ANIMATION_ID;
-}
-const char* Animation::getElementName(void) const
-{
-    return "Animation";
-}
-
-void Animation::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    // Animation writes its ID because it is not listed in the ref table.
-    write(getId(), file);
-    write((unsigned int)_channels.size(), file);
-    for (std::vector<AnimationChannel*>::iterator i = _channels.begin(); i != _channels.end(); ++i)
-    {
-        (*i)->writeBinary(file);
-    }
-}
-
-void Animation::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    if (_channels.size() > 0 )
-    {
-        for (std::vector<AnimationChannel*>::iterator i = _channels.begin(); i != _channels.end(); ++i)
-        {
-            (*i)->writeText(file);
-        }
-    }
-    fprintElementEnd(file);
-}
-
-void Animation::add(AnimationChannel* animationChannel)
-{
-    _channels.push_back(animationChannel);
-}
-
-void Animation::remove(AnimationChannel* animationChannel)
-{
-    std::vector<AnimationChannel*>::iterator it = std::find(_channels.begin(), _channels.end(), animationChannel);
-    if (it != _channels.end())
-    {
-        _channels.erase(it);
-    }
-}
-
-unsigned int Animation::getAnimationChannelCount() const
-{
-    return _channels.size();
-}
-
-AnimationChannel* Animation::getAnimationChannel(unsigned int index) const
-{
-    assert(index < _channels.size());
-    return _channels[index];
-}
-
-}
+#include "Base.h"
+#include "Animation.h"
+
+namespace gameplay
+{
+
+Animation::Animation(void)
+{
+}
+
+Animation::~Animation(void)
+{
+}
+
+unsigned int Animation::getTypeId(void) const
+{
+    return ANIMATION_ID;
+}
+const char* Animation::getElementName(void) const
+{
+    return "Animation";
+}
+
+void Animation::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    // Animation writes its ID because it is not listed in the ref table.
+    write(getId(), file);
+    write((unsigned int)_channels.size(), file);
+    for (std::vector<AnimationChannel*>::iterator i = _channels.begin(); i != _channels.end(); ++i)
+    {
+        (*i)->writeBinary(file);
+    }
+}
+
+void Animation::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    if (_channels.size() > 0 )
+    {
+        for (std::vector<AnimationChannel*>::iterator i = _channels.begin(); i != _channels.end(); ++i)
+        {
+            (*i)->writeText(file);
+        }
+    }
+    fprintElementEnd(file);
+}
+
+void Animation::add(AnimationChannel* animationChannel)
+{
+    _channels.push_back(animationChannel);
+}
+
+void Animation::remove(AnimationChannel* animationChannel)
+{
+    std::vector<AnimationChannel*>::iterator it = std::find(_channels.begin(), _channels.end(), animationChannel);
+    if (it != _channels.end())
+    {
+        _channels.erase(it);
+    }
+}
+
+unsigned int Animation::getAnimationChannelCount() const
+{
+    return _channels.size();
+}
+
+AnimationChannel* Animation::getAnimationChannel(unsigned int index) const
+{
+    assert(index < _channels.size());
+    return _channels[index];
+}
+
+}

+ 66 - 66
tools/encoder/src/Animation.h

@@ -1,66 +1,66 @@
-#ifndef ANIMATION_H_
-#define ANIMATION_H_
-
-#include "Object.h"
-#include "AnimationChannel.h"
-
-namespace gameplay
-{
-
-class Animation : public Object
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    Animation(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~Animation(void);
-
-    virtual unsigned int getTypeId(void) const;
-    virtual const char* getElementName(void) const;
-    virtual void writeBinary(FILE* file);
-    virtual void writeText(FILE* file);
-
-    /**
-     * Adds the given animation channel to this animation.
-     * 
-     * @param animationChannel The animation channel to add.
-     */
-    void add(AnimationChannel* animationChannel);
-
-    /**
-     * Removes the given animation channel from this animation.
-     * 
-     * @param animationChannel The animation channel to remove.
-     */
-    void remove(AnimationChannel* animationChannel);
-
-    /**
-     * Returns the number of animation channels contained in this animation.
-     * 
-     * @return The number of animation channels.
-     */
-    unsigned int getAnimationChannelCount() const;
-
-    /**
-     * Returns the animation channel at the given index.
-     * 
-     * @param index The index of the animation channel to get.
-     * 
-     * @return The pointer to the animation channel or NULL if not found.
-     */
-    AnimationChannel* getAnimationChannel(unsigned int index) const;
-
-private:
-
-    std::vector<AnimationChannel*> _channels;
-};
-
-}
-
-#endif
+#ifndef ANIMATION_H_
+#define ANIMATION_H_
+
+#include "Object.h"
+#include "AnimationChannel.h"
+
+namespace gameplay
+{
+
+class Animation : public Object
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Animation(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~Animation(void);
+
+    virtual unsigned int getTypeId(void) const;
+    virtual const char* getElementName(void) const;
+    virtual void writeBinary(FILE* file);
+    virtual void writeText(FILE* file);
+
+    /**
+     * Adds the given animation channel to this animation.
+     * 
+     * @param animationChannel The animation channel to add.
+     */
+    void add(AnimationChannel* animationChannel);
+
+    /**
+     * Removes the given animation channel from this animation.
+     * 
+     * @param animationChannel The animation channel to remove.
+     */
+    void remove(AnimationChannel* animationChannel);
+
+    /**
+     * Returns the number of animation channels contained in this animation.
+     * 
+     * @return The number of animation channels.
+     */
+    unsigned int getAnimationChannelCount() const;
+
+    /**
+     * Returns the animation channel at the given index.
+     * 
+     * @param index The index of the animation channel to get.
+     * 
+     * @return The pointer to the animation channel or NULL if not found.
+     */
+    AnimationChannel* getAnimationChannel(unsigned int index) const;
+
+private:
+
+    std::vector<AnimationChannel*> _channels;
+};
+
+}
+
+#endif

+ 248 - 248
tools/encoder/src/AnimationChannel.cpp

@@ -1,248 +1,248 @@
-#include "Base.h"
-#include "AnimationChannel.h"
-#include "Transform.h"
-
-namespace gameplay
-{
-
-AnimationChannel::AnimationChannel(void) :
-    _targetAttrib(0)
-{
-}
-
-AnimationChannel::~AnimationChannel(void)
-{
-}
-
-unsigned int AnimationChannel::getTypeId(void) const
-{
-    return ANIMATIONCHANNEL_ID;
-}
-const char* AnimationChannel::getElementName(void) const
-{
-    return "AnimationChannel";
-}
-
-void AnimationChannel::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    write(_targetId, file);
-    write(_targetAttrib, file);
-    write((unsigned int)_keytimes.size(), file);
-    for (std::vector<float>::const_iterator i = _keytimes.begin(); i != _keytimes.end(); ++i)
-    {
-        write((unsigned int)*i, file);
-    }
-    write(_keyValues, file);
-    write(_tangentsIn, file);
-    write(_tangentsOut, file);
-    write(_interpolations, file);
-}
-
-void AnimationChannel::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    fprintfElement(file, "targetId", _targetId);
-    fprintf(file, "<%s>%u %s</%s>\n", "targetAttrib", _targetAttrib, Transform::getPropertyString(_targetAttrib), "targetAttrib");
-    fprintfElement(file, "%f ", "keytimes", _keytimes);
-    fprintfElement(file, "%f ", "values", _keyValues);
-    fprintfElement(file, "%f ", "tangentsIn", _tangentsIn);
-    fprintfElement(file, "%f ", "tangentsOut", _tangentsOut);
-    fprintfElement(file, "%u ", "interpolations", _interpolations);
-    fprintElementEnd(file);
-}
-
-void AnimationChannel::setInterpolation(unsigned int interpolation)
-{
-    _interpolations.clear();
-    _interpolations.push_back(interpolation);
-}
-
-const std::string& AnimationChannel::getTargetId() const
-{
-    return _targetId;
-}
-
-unsigned int AnimationChannel::getTargetAttribute() const
-{
-    return _targetAttrib;
-}
-
-std::vector<float>& AnimationChannel::getKeyValues()
-{
-    return _keyValues;
-}
-
-std::vector<float>& AnimationChannel::getKeyTimes()
-{
-    return _keytimes;
-}
-
-std::vector<float>& AnimationChannel::getTangentsIn()
-{
-    return _tangentsIn;
-}
-
-std::vector<float>& AnimationChannel::getTangentsOut()
-{
-    return _tangentsOut;
-}
-
-std::vector<unsigned int>& AnimationChannel::getInterpolationTypes()
-{
-    return _interpolations;
-}
-
-void AnimationChannel::setTargetId(const std::string& str)
-{
-    _targetId = str;
-}
-
-void AnimationChannel::setTargetAttribute(unsigned int attrib)
-{
-    _targetAttrib = attrib;
-}
-
-void AnimationChannel::setKeyTimes(const std::vector<float>& values)
-{
-    _keytimes = values;
-}
-
-void AnimationChannel::setKeyValues(const std::vector<float>& values)
-{
-    _keyValues = values;
-}
-
-void AnimationChannel::setTangentsIn(const std::vector<float>& values)
-{
-    _tangentsIn = values;
-}
-
-void AnimationChannel::setTangentsOut(const std::vector<float>& values)
-{
-    _tangentsOut = values;
-}
-
-void AnimationChannel::setInterpolations(const std::vector<unsigned int>& values)
-{
-    _interpolations = values;
-}
-
-void AnimationChannel::removeDuplicates()
-{
-    LOG(3, "      Removing duplicates for channel with target attribute: %u.\n", _targetAttrib);
-
-    int startCount = _keytimes.size();
-
-    size_t propSize = Transform::getPropertySize(_targetAttrib);
-
-    if (propSize > 1 && !_interpolations.empty() && _interpolations[0] == LINEAR)
-    {
-        size_t prevIndex = 0;
-
-        std::vector<float>::iterator prevStart = _keyValues.begin();
-        std::vector<float>::iterator prevEnd = prevStart + propSize - 1;
-        
-        size_t i = 1;
-        for (i = 1; i < _keytimes.size(); ++i)
-        {
-            std::vector<float>::iterator start = _keyValues.begin() + i * propSize;
-            std::vector<float>::iterator end = start + propSize - 1;
-
-            if (!equal(prevStart, prevEnd, start) || i == _keytimes.size() - 1)
-            {
-                if (i - prevIndex > 2)
-                {
-                    deleteRange(prevIndex+1, i, propSize);
-                    i = prevIndex;
-                    prevStart = _keyValues.begin() + i * propSize;
-                    prevEnd = prevStart + propSize - 1;
-                }
-                else
-                {
-                    prevStart = start;
-                    prevEnd = end;
-                    prevIndex = i;
-                }
-            }
-        }
-        if (i - 1 - prevIndex >= 2)
-        {
-            deleteRange(prevIndex+1, i, propSize);
-        }
-    }
-
-    LOG(3, "      Removed %d duplicate keyframes from channel.\n", startCount- _keytimes.size());
-}
-
-unsigned int AnimationChannel::getInterpolationType(const char* str)
-{
-    unsigned int value = 0;
-    switch (str[0])
-    {
-    case 'L':
-        if (strcmp(str, "LINEAR") == 0)
-        {
-            value = AnimationChannel::LINEAR;
-        }
-        break;
-    case 'B':
-        if (strcmp(str, "BEZIER") == 0)
-        {
-            value = AnimationChannel::BEZIER;
-        }
-        else if (strcmp(str, "BSPLINE") == 0)
-        {
-            value = AnimationChannel::BSPLINE;
-        }
-        break;
-    case 'C':
-        if (strcmp(str, "CARDINAL") == 0)
-        {
-            value = AnimationChannel::CARDINAL;
-        }
-        break;
-    case 'H':
-        if (strcmp(str, "HERMITE") == 0)
-        {
-            value = AnimationChannel::HERMITE;
-        }
-        break;
-    case 'S':
-        if (strcmp(str, "STEP") == 0)
-        {
-            value = AnimationChannel::STEP;
-        }
-        break;
-    default:
-        break;
-    }
-    return value;
-}
-
-void AnimationChannel::deleteRange(size_t begin, size_t end, size_t propSize)
-{
-    assert(end > begin);
-
-    // delete range
-    LOG(4, "        delete %lu to %lu\n", begin, end - 1);
-
-    std::vector<float>::iterator a = _keyValues.begin() + begin * propSize;
-    std::vector<float>::iterator b = _keyValues.begin() + end * propSize;
-    _keyValues.erase(a, b);
-
-    a = _keytimes.begin() + begin;
-    b = _keytimes.begin() + end;
-    _keytimes.erase(a, b);
-
-    if (_interpolations.size() > 1)
-    {
-        std::vector<unsigned int>::iterator a = _interpolations.begin() + begin;
-        std::vector<unsigned int>::iterator b = _interpolations.begin() + end * propSize;
-        _interpolations.erase(a, b);
-    }
-
-    // TODO: also remove key frames from _tangentsIn and _tangentsOut once other curve types are supported.
-}
-
-}
+#include "Base.h"
+#include "AnimationChannel.h"
+#include "Transform.h"
+
+namespace gameplay
+{
+
+AnimationChannel::AnimationChannel(void) :
+    _targetAttrib(0)
+{
+}
+
+AnimationChannel::~AnimationChannel(void)
+{
+}
+
+unsigned int AnimationChannel::getTypeId(void) const
+{
+    return ANIMATIONCHANNEL_ID;
+}
+const char* AnimationChannel::getElementName(void) const
+{
+    return "AnimationChannel";
+}
+
+void AnimationChannel::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    write(_targetId, file);
+    write(_targetAttrib, file);
+    write((unsigned int)_keytimes.size(), file);
+    for (std::vector<float>::const_iterator i = _keytimes.begin(); i != _keytimes.end(); ++i)
+    {
+        write((unsigned int)*i, file);
+    }
+    write(_keyValues, file);
+    write(_tangentsIn, file);
+    write(_tangentsOut, file);
+    write(_interpolations, file);
+}
+
+void AnimationChannel::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    fprintfElement(file, "targetId", _targetId);
+    fprintf(file, "<%s>%u %s</%s>\n", "targetAttrib", _targetAttrib, Transform::getPropertyString(_targetAttrib), "targetAttrib");
+    fprintfElement(file, "%f ", "keytimes", _keytimes);
+    fprintfElement(file, "%f ", "values", _keyValues);
+    fprintfElement(file, "%f ", "tangentsIn", _tangentsIn);
+    fprintfElement(file, "%f ", "tangentsOut", _tangentsOut);
+    fprintfElement(file, "%u ", "interpolations", _interpolations);
+    fprintElementEnd(file);
+}
+
+void AnimationChannel::setInterpolation(unsigned int interpolation)
+{
+    _interpolations.clear();
+    _interpolations.push_back(interpolation);
+}
+
+const std::string& AnimationChannel::getTargetId() const
+{
+    return _targetId;
+}
+
+unsigned int AnimationChannel::getTargetAttribute() const
+{
+    return _targetAttrib;
+}
+
+std::vector<float>& AnimationChannel::getKeyValues()
+{
+    return _keyValues;
+}
+
+std::vector<float>& AnimationChannel::getKeyTimes()
+{
+    return _keytimes;
+}
+
+std::vector<float>& AnimationChannel::getTangentsIn()
+{
+    return _tangentsIn;
+}
+
+std::vector<float>& AnimationChannel::getTangentsOut()
+{
+    return _tangentsOut;
+}
+
+std::vector<unsigned int>& AnimationChannel::getInterpolationTypes()
+{
+    return _interpolations;
+}
+
+void AnimationChannel::setTargetId(const std::string& str)
+{
+    _targetId = str;
+}
+
+void AnimationChannel::setTargetAttribute(unsigned int attrib)
+{
+    _targetAttrib = attrib;
+}
+
+void AnimationChannel::setKeyTimes(const std::vector<float>& values)
+{
+    _keytimes = values;
+}
+
+void AnimationChannel::setKeyValues(const std::vector<float>& values)
+{
+    _keyValues = values;
+}
+
+void AnimationChannel::setTangentsIn(const std::vector<float>& values)
+{
+    _tangentsIn = values;
+}
+
+void AnimationChannel::setTangentsOut(const std::vector<float>& values)
+{
+    _tangentsOut = values;
+}
+
+void AnimationChannel::setInterpolations(const std::vector<unsigned int>& values)
+{
+    _interpolations = values;
+}
+
+void AnimationChannel::removeDuplicates()
+{
+    LOG(3, "      Removing duplicates for channel with target attribute: %u.\n", _targetAttrib);
+
+    int startCount = _keytimes.size();
+
+    size_t propSize = Transform::getPropertySize(_targetAttrib);
+
+    if (propSize > 1 && !_interpolations.empty() && _interpolations[0] == LINEAR)
+    {
+        size_t prevIndex = 0;
+
+        std::vector<float>::iterator prevStart = _keyValues.begin();
+        std::vector<float>::iterator prevEnd = prevStart + propSize - 1;
+        
+        size_t i = 1;
+        for (i = 1; i < _keytimes.size(); ++i)
+        {
+            std::vector<float>::iterator start = _keyValues.begin() + i * propSize;
+            std::vector<float>::iterator end = start + propSize - 1;
+
+            if (!equal(prevStart, prevEnd, start) || i == _keytimes.size() - 1)
+            {
+                if (i - prevIndex > 2)
+                {
+                    deleteRange(prevIndex+1, i, propSize);
+                    i = prevIndex;
+                    prevStart = _keyValues.begin() + i * propSize;
+                    prevEnd = prevStart + propSize - 1;
+                }
+                else
+                {
+                    prevStart = start;
+                    prevEnd = end;
+                    prevIndex = i;
+                }
+            }
+        }
+        if (i - 1 - prevIndex >= 2)
+        {
+            deleteRange(prevIndex+1, i, propSize);
+        }
+    }
+
+    LOG(3, "      Removed %d duplicate keyframes from channel.\n", startCount- _keytimes.size());
+}
+
+unsigned int AnimationChannel::getInterpolationType(const char* str)
+{
+    unsigned int value = 0;
+    switch (str[0])
+    {
+    case 'L':
+        if (strcmp(str, "LINEAR") == 0)
+        {
+            value = AnimationChannel::LINEAR;
+        }
+        break;
+    case 'B':
+        if (strcmp(str, "BEZIER") == 0)
+        {
+            value = AnimationChannel::BEZIER;
+        }
+        else if (strcmp(str, "BSPLINE") == 0)
+        {
+            value = AnimationChannel::BSPLINE;
+        }
+        break;
+    case 'C':
+        if (strcmp(str, "CARDINAL") == 0)
+        {
+            value = AnimationChannel::CARDINAL;
+        }
+        break;
+    case 'H':
+        if (strcmp(str, "HERMITE") == 0)
+        {
+            value = AnimationChannel::HERMITE;
+        }
+        break;
+    case 'S':
+        if (strcmp(str, "STEP") == 0)
+        {
+            value = AnimationChannel::STEP;
+        }
+        break;
+    default:
+        break;
+    }
+    return value;
+}
+
+void AnimationChannel::deleteRange(size_t begin, size_t end, size_t propSize)
+{
+    assert(end > begin);
+
+    // delete range
+    LOG(4, "        delete %lu to %lu\n", begin, end - 1);
+
+    std::vector<float>::iterator a = _keyValues.begin() + begin * propSize;
+    std::vector<float>::iterator b = _keyValues.begin() + end * propSize;
+    _keyValues.erase(a, b);
+
+    a = _keytimes.begin() + begin;
+    b = _keytimes.begin() + end;
+    _keytimes.erase(a, b);
+
+    if (_interpolations.size() > 1)
+    {
+        std::vector<unsigned int>::iterator a = _interpolations.begin() + begin;
+        std::vector<unsigned int>::iterator b = _interpolations.begin() + end * propSize;
+        _interpolations.erase(a, b);
+    }
+
+    // TODO: also remove key frames from _tangentsIn and _tangentsOut once other curve types are supported.
+}
+
+}

+ 102 - 102
tools/encoder/src/AnimationChannel.h

@@ -1,102 +1,102 @@
-#ifndef ANIMATIONCHANNEL_H_
-#define ANIMATIONCHANNEL_H_
-
-#include "Object.h"
-
-namespace gameplay
-{
-
-class AnimationChannel : public Object
-{
-public:
-
-    enum InterpolationTypes
-    {
-        LINEAR = 1,
-        BEZIER = 2,
-        CARDINAL = 3,
-        HERMITE = 4,
-        BSPLINE = 5,
-        STEP = 6
-    };
-
-    /**
-     * Constructor.
-     */
-    AnimationChannel(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~AnimationChannel(void);
-
-    virtual unsigned int getTypeId(void) const;
-    virtual const char* getElementName(void) const;
-    virtual void writeBinary(FILE* file);
-    virtual void writeText(FILE* file);
-
-    const std::string& getTargetId() const;
-
-    /**
-     * Sets the interpolation type of the entire animation channel.
-     * 
-     * @param interpolation The interpolation type from InterpolationTypes enum.
-     */
-    void setInterpolation(unsigned int interpolation);
-
-    void setTargetId(const std::string& str);
-    void setTargetAttribute(unsigned int attrib);
-
-    void setKeyTimes(const std::vector<float>& values);
-    void setKeyValues(const std::vector<float>& values);
-    void setTangentsIn(const std::vector<float>& values);
-    void setTangentsOut(const std::vector<float>& values);
-    void setInterpolations(const std::vector<unsigned int>& values);
-
-    unsigned int getTargetAttribute() const;
-    std::vector<float>& getKeyValues();
-    std::vector<float>& getKeyTimes();
-    std::vector<float>& getTangentsIn();
-    std::vector<float>& getTangentsOut();
-    std::vector<unsigned int>& getInterpolationTypes();
-
-    /**
-     * Removes duplicate key frames from the animation channel.
-     */
-    void removeDuplicates();
-
-    /**
-     * Returns the interpolation type value for the given string or zero if not valid.
-     * Example: "LINEAR" returns AnimationChannel::LINEAR
-     * 
-     * @param str Interpolation such as "LINEAR" or "BSPLINE".
-     * 
-     * @return A value from InterpolationTypes enum or zero if not valid.
-     */
-    static unsigned int getInterpolationType(const char* str);
-
-private:
-
-    /**
-     * Deletes all key frames from key time index begin to key time index end (exclusive).
-     * 
-     * @param begin The start index to delete.
-     * @param end The index to delete up to but not including.
-     * @param propSize The size of the animation propery to delete. Example: Translate(x,y,z) is size 3.
-     */
-    void deleteRange(size_t begin, size_t end, size_t propSize);
-
-private:
-
-    std::string _targetId;
-    unsigned int _targetAttrib;
-    std::vector<float> _keytimes;
-    std::vector<float> _keyValues;
-    std::vector<float> _tangentsIn;
-    std::vector<float> _tangentsOut;
-    std::vector<unsigned int> _interpolations;
-};
-
-}
-
-#endif
+#ifndef ANIMATIONCHANNEL_H_
+#define ANIMATIONCHANNEL_H_
+
+#include "Object.h"
+
+namespace gameplay
+{
+
+class AnimationChannel : public Object
+{
+public:
+
+    enum InterpolationTypes
+    {
+        LINEAR = 1,
+        BEZIER = 2,
+        CARDINAL = 3,
+        HERMITE = 4,
+        BSPLINE = 5,
+        STEP = 6
+    };
+
+    /**
+     * Constructor.
+     */
+    AnimationChannel(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~AnimationChannel(void);
+
+    virtual unsigned int getTypeId(void) const;
+    virtual const char* getElementName(void) const;
+    virtual void writeBinary(FILE* file);
+    virtual void writeText(FILE* file);
+
+    const std::string& getTargetId() const;
+
+    /**
+     * Sets the interpolation type of the entire animation channel.
+     * 
+     * @param interpolation The interpolation type from InterpolationTypes enum.
+     */
+    void setInterpolation(unsigned int interpolation);
+
+    void setTargetId(const std::string& str);
+    void setTargetAttribute(unsigned int attrib);
+
+    void setKeyTimes(const std::vector<float>& values);
+    void setKeyValues(const std::vector<float>& values);
+    void setTangentsIn(const std::vector<float>& values);
+    void setTangentsOut(const std::vector<float>& values);
+    void setInterpolations(const std::vector<unsigned int>& values);
+
+    unsigned int getTargetAttribute() const;
+    std::vector<float>& getKeyValues();
+    std::vector<float>& getKeyTimes();
+    std::vector<float>& getTangentsIn();
+    std::vector<float>& getTangentsOut();
+    std::vector<unsigned int>& getInterpolationTypes();
+
+    /**
+     * Removes duplicate key frames from the animation channel.
+     */
+    void removeDuplicates();
+
+    /**
+     * Returns the interpolation type value for the given string or zero if not valid.
+     * Example: "LINEAR" returns AnimationChannel::LINEAR
+     * 
+     * @param str Interpolation such as "LINEAR" or "BSPLINE".
+     * 
+     * @return A value from InterpolationTypes enum or zero if not valid.
+     */
+    static unsigned int getInterpolationType(const char* str);
+
+private:
+
+    /**
+     * Deletes all key frames from key time index begin to key time index end (exclusive).
+     * 
+     * @param begin The start index to delete.
+     * @param end The index to delete up to but not including.
+     * @param propSize The size of the animation propery to delete. Example: Translate(x,y,z) is size 3.
+     */
+    void deleteRange(size_t begin, size_t end, size_t propSize);
+
+private:
+
+    std::string _targetId;
+    unsigned int _targetAttrib;
+    std::vector<float> _keytimes;
+    std::vector<float> _keyValues;
+    std::vector<float> _tangentsIn;
+    std::vector<float> _tangentsOut;
+    std::vector<unsigned int> _interpolations;
+};
+
+}
+
+#endif

+ 70 - 70
tools/encoder/src/Animations.cpp

@@ -1,70 +1,70 @@
-#include "Base.h"
-#include "Animations.h"
-
-namespace gameplay
-{
-
-Animations::Animations(void)
-{
-    // There will only be one Animations.
-    // It requires an ID because it will be stores in the ref table.
-    setId("__Animations__");
-}
-
-Animations::~Animations(void)
-{
-}
-
-unsigned int Animations::getTypeId(void) const
-{
-    return ANIMATIONS_ID;
-}
-const char* Animations::getElementName(void) const
-{
-    return "Animations";
-}
-
-void Animations::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    write((unsigned int)_animations.size(), file);
-    for (std::vector<Animation*>::iterator i = _animations.begin(); i != _animations.end(); ++i)
-    {
-        (*i)->writeBinary(file);
-    }
-}
-
-void Animations::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    if (_animations.size() > 0 )
-    {
-        for (std::vector<Animation*>::iterator i = _animations.begin(); i != _animations.end(); ++i)
-        {
-            (*i)->writeText(file);
-        }
-    }
-    fprintElementEnd(file);
-}
-
-void Animations::add(Animation* animation)
-{
-    _animations.push_back(animation);
-}
-
-unsigned int Animations::getAnimationCount() const
-{
-    return _animations.size();
-}
-
-Animation* Animations::getAnimation(unsigned int index) const
-{
-    return _animations[index];
-}
-
-void Animations::removeAnimation(unsigned int index)
-{
-    _animations.erase(_animations.begin() + index);
-}
-
-}
+#include "Base.h"
+#include "Animations.h"
+
+namespace gameplay
+{
+
+Animations::Animations(void)
+{
+    // There will only be one Animations.
+    // It requires an ID because it will be stores in the ref table.
+    setId("__Animations__");
+}
+
+Animations::~Animations(void)
+{
+}
+
+unsigned int Animations::getTypeId(void) const
+{
+    return ANIMATIONS_ID;
+}
+const char* Animations::getElementName(void) const
+{
+    return "Animations";
+}
+
+void Animations::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    write((unsigned int)_animations.size(), file);
+    for (std::vector<Animation*>::iterator i = _animations.begin(); i != _animations.end(); ++i)
+    {
+        (*i)->writeBinary(file);
+    }
+}
+
+void Animations::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    if (_animations.size() > 0 )
+    {
+        for (std::vector<Animation*>::iterator i = _animations.begin(); i != _animations.end(); ++i)
+        {
+            (*i)->writeText(file);
+        }
+    }
+    fprintElementEnd(file);
+}
+
+void Animations::add(Animation* animation)
+{
+    _animations.push_back(animation);
+}
+
+unsigned int Animations::getAnimationCount() const
+{
+    return _animations.size();
+}
+
+Animation* Animations::getAnimation(unsigned int index) const
+{
+    return _animations[index];
+}
+
+void Animations::removeAnimation(unsigned int index)
+{
+    _animations.erase(_animations.begin() + index);
+}
+
+}

+ 44 - 44
tools/encoder/src/Animations.h

@@ -1,44 +1,44 @@
-#ifndef LIBRARYANIMATIONS_H_
-#define LIBRARYANIMATIONS_H_
-
-#include "Object.h"
-#include "Animation.h"
-
-namespace gameplay
-{
-
-/**
- * Animations contains all of the animations in the GamePlay Binary file.
- */
-class Animations : public Object
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    Animations(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~Animations(void);
-
-    virtual unsigned int getTypeId(void) const;
-    virtual const char* getElementName(void) const;
-    virtual void writeBinary(FILE* file);
-    virtual void writeText(FILE* file);
-
-    void add(Animation* animation);
-    unsigned int getAnimationCount() const;
-    Animation* getAnimation(unsigned int index) const;
-    void removeAnimation(unsigned int index);
-
-private:
-
-    std::vector<Animation*> _animations;
-};
-
-}
-
-#endif
+#ifndef LIBRARYANIMATIONS_H_
+#define LIBRARYANIMATIONS_H_
+
+#include "Object.h"
+#include "Animation.h"
+
+namespace gameplay
+{
+
+/**
+ * Animations contains all of the animations in the GamePlay Binary file.
+ */
+class Animations : public Object
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Animations(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~Animations(void);
+
+    virtual unsigned int getTypeId(void) const;
+    virtual const char* getElementName(void) const;
+    virtual void writeBinary(FILE* file);
+    virtual void writeText(FILE* file);
+
+    void add(Animation* animation);
+    unsigned int getAnimationCount() const;
+    Animation* getAnimation(unsigned int index) const;
+    void removeAnimation(unsigned int index);
+
+private:
+
+    std::vector<Animation*> _animations;
+};
+
+}
+
+#endif

+ 25 - 25
tools/encoder/src/Base.cpp

@@ -1,26 +1,26 @@
-#include "Base.h"
-
-namespace gameplay
-{
-
-void fillArray(float values[], float value, size_t length)
-{
-    for (size_t i = 0; i < length; ++i)
-    {
-        values[i] = value;
-    }
-}
-
-std::string getBaseName(const std::string& filepath)
-{
-    size_t index1 = filepath.find_last_of('\\');
-    size_t index2 = filepath.find_last_of('/');
-    size_t index = (index1 != -1 && index1 > index2 ? index1 : index2);
-    size_t length = filepath.length();
-    std::string filename = filepath.substr(index + 1, length);
-    length = filename.length();
-    std::string output = filename.substr(0, (length-4));
-    return output;
-}
-
+#include "Base.h"
+
+namespace gameplay
+{
+
+void fillArray(float values[], float value, size_t length)
+{
+    for (size_t i = 0; i < length; ++i)
+    {
+        values[i] = value;
+    }
+}
+
+std::string getBaseName(const std::string& filepath)
+{
+    size_t index1 = filepath.find_last_of('\\');
+    size_t index2 = filepath.find_last_of('/');
+    size_t index = (index1 != -1 && index1 > index2 ? index1 : index2);
+    size_t length = filepath.length();
+    std::string filename = filepath.substr(index + 1, length);
+    length = filename.length();
+    std::string output = filename.substr(0, (length-4));
+    return output;
+}
+
 }

+ 146 - 146
tools/encoder/src/BoundingVolume.cpp

@@ -1,146 +1,146 @@
-#include "Base.h"
-#include "BoundingVolume.h"
-
-namespace gameplay
-{
-
-BoundingVolume::BoundingVolume()
-    : radius(0.0f)
-{
-}
-
-void updateMinMax(Vector3* point, Vector3* min, Vector3* max)
-{
-    // Leftmost point.
-    if (point->x < min->x)
-    {
-        min->x = point->x;
-    }
-
-    // Rightmost point.
-    if (point->x > max->x)
-    {
-        max->x = point->x;
-    }
-
-    // Lowest point.
-    if (point->y < min->y)
-    {
-        min->y = point->y;
-    }
-
-    // Highest point.
-    if (point->y > max->y)
-    {
-        max->y = point->y;
-    }
-
-    // Farthest point.
-    if (point->z < min->z)
-    {
-        min->z = point->z;
-    }
-
-    // Nearest point.
-    if (point->z > max->z)
-    {
-        max->z = point->z;
-    }
-}
-
-void BoundingVolume::transform(const Matrix& m)
-{
-    // Transform the bounding sphere
-    m.transformPoint(center, &center);
-    Vector3 translate;
-    m.decompose(&translate, NULL, NULL);
-    float r = radius * translate.x;
-    r = std::max(radius, radius * translate.y);
-    r = std::max(radius, radius * translate.z);
-    radius = r;
-
-    // Transform the bounding box
-    Vector3 corners[8];
-    corners[0].set(min.x, max.y, max.z);
-    // Left-bottom-front.
-    corners[1].set(min.x, min.y, max.z);
-    // Right-bottom-front.
-    corners[2].set(max.x, min.y, max.z);
-    // Right-top-front.
-    corners[3].set(max.x, max.y, max.z);
-    // Right-top-back.
-    corners[4].set(max.x, max.y, min.z);
-    // Right-bottom-back.
-    corners[5].set(max.x, min.y, min.z);
-    // Left-bottom-back.
-    corners[6].set(min.x, min.y, min.z);
-    // Left-top-back.
-    corners[7].set(min.x, max.y, min.z);
-
-    // Transform the corners, recalculating the min and max points along the way.
-    m.transformPoint(corners[0], &corners[0]);
-    Vector3 newMin = corners[0];
-    Vector3 newMax = corners[0];
-    for (int i = 1; i < 8; i++)
-    {
-        m.transformPoint(corners[i], &corners[i]);
-        updateMinMax(&corners[i], &newMin, &newMax);
-    }
-    min = newMin;
-    max = newMax;
-}
-
-void BoundingVolume::merge(const BoundingVolume& v)
-{
-    // Merge the box portion
-    min.x = std::min(min.x, v.min.x);
-    min.y = std::min(min.y, v.min.y);
-    min.z = std::min(min.z, v.min.z);
-    max.x = std::max(max.x, v.max.x);
-    max.y = std::max(max.y, v.max.y);
-    max.z = std::max(max.z, v.max.z);
-
-    // Merge the sphere portion
-    // Calculate the distance between the two centers.
-    float vx = center.x - v.center.x;
-    float vy = center.y - v.center.y;
-    float vz = center.z - v.center.z;
-    float d = sqrt(vx * vx + vy * vy + vz * vz);
-
-    // If one sphere is contained inside the other, set to the larger sphere.
-    if (d <= (v.radius - radius))
-    {
-        // Use targert volume
-        radius = v.radius;
-        center = v.center;
-    }
-    else if (d <= (radius - v.radius))
-    {
-        // No change
-    }
-    else
-    {
-        // Calculate the unit vector between the two centers.
-        float dI = 1.0f / d;
-        vx *= dI;
-        vy *= dI;
-        vz *= dI;
-
-        // Calculate the new radius.
-        float r = (radius + v.radius + d) * 0.5f;
-
-        // Calculate the new center.
-        float scaleFactor = (r - v.radius);
-        vx = vx * scaleFactor + v.center.x;
-        vy = vy * scaleFactor + v.center.y;
-        vz = vz * scaleFactor + v.center.z;
-
-        // Set the new center and radius.
-        center.x = vx;
-        center.y = vy;
-        center.z = vz;
-        radius = r;
-    }
-}
-
-}
+#include "Base.h"
+#include "BoundingVolume.h"
+
+namespace gameplay
+{
+
+BoundingVolume::BoundingVolume()
+    : radius(0.0f)
+{
+}
+
+void updateMinMax(Vector3* point, Vector3* min, Vector3* max)
+{
+    // Leftmost point.
+    if (point->x < min->x)
+    {
+        min->x = point->x;
+    }
+
+    // Rightmost point.
+    if (point->x > max->x)
+    {
+        max->x = point->x;
+    }
+
+    // Lowest point.
+    if (point->y < min->y)
+    {
+        min->y = point->y;
+    }
+
+    // Highest point.
+    if (point->y > max->y)
+    {
+        max->y = point->y;
+    }
+
+    // Farthest point.
+    if (point->z < min->z)
+    {
+        min->z = point->z;
+    }
+
+    // Nearest point.
+    if (point->z > max->z)
+    {
+        max->z = point->z;
+    }
+}
+
+void BoundingVolume::transform(const Matrix& m)
+{
+    // Transform the bounding sphere
+    m.transformPoint(center, &center);
+    Vector3 translate;
+    m.decompose(&translate, NULL, NULL);
+    float r = radius * translate.x;
+    r = std::max(radius, radius * translate.y);
+    r = std::max(radius, radius * translate.z);
+    radius = r;
+
+    // Transform the bounding box
+    Vector3 corners[8];
+    corners[0].set(min.x, max.y, max.z);
+    // Left-bottom-front.
+    corners[1].set(min.x, min.y, max.z);
+    // Right-bottom-front.
+    corners[2].set(max.x, min.y, max.z);
+    // Right-top-front.
+    corners[3].set(max.x, max.y, max.z);
+    // Right-top-back.
+    corners[4].set(max.x, max.y, min.z);
+    // Right-bottom-back.
+    corners[5].set(max.x, min.y, min.z);
+    // Left-bottom-back.
+    corners[6].set(min.x, min.y, min.z);
+    // Left-top-back.
+    corners[7].set(min.x, max.y, min.z);
+
+    // Transform the corners, recalculating the min and max points along the way.
+    m.transformPoint(corners[0], &corners[0]);
+    Vector3 newMin = corners[0];
+    Vector3 newMax = corners[0];
+    for (int i = 1; i < 8; i++)
+    {
+        m.transformPoint(corners[i], &corners[i]);
+        updateMinMax(&corners[i], &newMin, &newMax);
+    }
+    min = newMin;
+    max = newMax;
+}
+
+void BoundingVolume::merge(const BoundingVolume& v)
+{
+    // Merge the box portion
+    min.x = std::min(min.x, v.min.x);
+    min.y = std::min(min.y, v.min.y);
+    min.z = std::min(min.z, v.min.z);
+    max.x = std::max(max.x, v.max.x);
+    max.y = std::max(max.y, v.max.y);
+    max.z = std::max(max.z, v.max.z);
+
+    // Merge the sphere portion
+    // Calculate the distance between the two centers.
+    float vx = center.x - v.center.x;
+    float vy = center.y - v.center.y;
+    float vz = center.z - v.center.z;
+    float d = sqrt(vx * vx + vy * vy + vz * vz);
+
+    // If one sphere is contained inside the other, set to the larger sphere.
+    if (d <= (v.radius - radius))
+    {
+        // Use targert volume
+        radius = v.radius;
+        center = v.center;
+    }
+    else if (d <= (radius - v.radius))
+    {
+        // No change
+    }
+    else
+    {
+        // Calculate the unit vector between the two centers.
+        float dI = 1.0f / d;
+        vx *= dI;
+        vy *= dI;
+        vz *= dI;
+
+        // Calculate the new radius.
+        float r = (radius + v.radius + d) * 0.5f;
+
+        // Calculate the new center.
+        float scaleFactor = (r - v.radius);
+        vx = vx * scaleFactor + v.center.x;
+        vy = vy * scaleFactor + v.center.y;
+        vz = vz * scaleFactor + v.center.z;
+
+        // Set the new center and radius.
+        center.x = vx;
+        center.y = vy;
+        center.z = vz;
+        radius = r;
+    }
+}
+
+}

+ 57 - 57
tools/encoder/src/BoundingVolume.h

@@ -1,57 +1,57 @@
-#ifndef BOUNDINGVOLUME_H_
-#define BOUNDINGVOLUME_H_
-
-#include "Vector3.h"
-#include "Matrix.h"
-
-namespace gameplay
-{
-
-/**
- * Represents a 3D bounding volumes, which defines both a
- * bounding sphere and an axis-aligned bounding box (AABB).
- */
-class BoundingVolume
-{
-public:
-
-    /**
-     * Radius of the bounding sphere.
-     */
-    float radius;
-
-    /**
-     * Center point of the bounding sphere.
-     */
-    Vector3 center;
-
-    /**
-     * Minimum point of the AABB.
-     */
-    Vector3 min;
-
-    /**
-     * Maximum point of the AABB.
-     */
-    Vector3 max;
-
-    /**
-     * Constructor.
-     */
-    BoundingVolume();
-
-    /**
-     * Transforms this bounding volume by the specified matrix.
-     */
-    void transform(const Matrix& m);
-
-    /**
-     * Merges this bounding volume with the specified one and
-     * stores the result in this BoundingVolume.
-     */
-    void merge(const BoundingVolume& v);
-};
-
-}
-
-#endif
+#ifndef BOUNDINGVOLUME_H_
+#define BOUNDINGVOLUME_H_
+
+#include "Vector3.h"
+#include "Matrix.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a 3D bounding volumes, which defines both a
+ * bounding sphere and an axis-aligned bounding box (AABB).
+ */
+class BoundingVolume
+{
+public:
+
+    /**
+     * Radius of the bounding sphere.
+     */
+    float radius;
+
+    /**
+     * Center point of the bounding sphere.
+     */
+    Vector3 center;
+
+    /**
+     * Minimum point of the AABB.
+     */
+    Vector3 min;
+
+    /**
+     * Maximum point of the AABB.
+     */
+    Vector3 max;
+
+    /**
+     * Constructor.
+     */
+    BoundingVolume();
+
+    /**
+     * Transforms this bounding volume by the specified matrix.
+     */
+    void transform(const Matrix& m);
+
+    /**
+     * Merges this bounding volume with the specified one and
+     * stores the result in this BoundingVolume.
+     */
+    void merge(const BoundingVolume& v);
+};
+
+}
+
+#endif

+ 126 - 126
tools/encoder/src/Camera.cpp

@@ -1,126 +1,126 @@
-#include "Base.h"
-#include "Camera.h"
-
-namespace gameplay
-{
-
-Camera::Camera(void) :
-    _cameraType(CameraPerspective), 
-    _fieldOfView(0.0f),
-    _aspectRatio(0.0f),
-    _nearPlane(0.0f),
-    _farPlane(0.0f),
-    _viewportWidth(0.0f),
-    _viewportHeight(0.0f)
-{
-}
-
-Camera::~Camera(void)
-{
-}
-
-void Camera::setFieldOfView(float value)
-{
-    _fieldOfView = value;
-}
-
-
-void Camera::setAspectRatio(float value)
-{
-    _aspectRatio = value;
-}
-
-
-void Camera::setNearPlane(float value)
-{
-    _nearPlane = value;
-}
-
-
-void Camera::setFarPlane(float value)
-{
-    _farPlane = value;
-}
-
-unsigned int Camera::getTypeId(void) const
-{
-    return CAMERA_ID;
-}
-const char* Camera::getElementName(void) const
-{
-    return "Camera";
-}
-
-void Camera::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    write(_cameraType, file);
-    write(_aspectRatio, file);
-    write(_nearPlane, file);
-    write(_farPlane, file);
-
-    if (_cameraType == CameraPerspective)
-    {
-        write(_fieldOfView, file);
-    }
-    else if (_cameraType == CameraOrthographic)
-    {
-        write(getViewPortWidth(), file);
-        write(getViewPortHeight(), file);
-    }
-    else
-    {
-        assert(false);
-    }
-}
-void Camera::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    fprintfElement(file, "cameraType", _cameraType == CameraPerspective ? "CameraPerspective" : "CameraOrthographic");
-    fprintfElement(file, "aspectRatio", _aspectRatio);
-    fprintfElement(file, "nearPlane", _nearPlane);
-    fprintfElement(file, "farPlane", _farPlane);
-
-    if (_cameraType == CameraPerspective)
-    {
-        fprintfElement(file, "fieldOfView", _fieldOfView);
-    }
-    else if (_cameraType == CameraOrthographic)
-    {
-        fprintfElement(file, "viewportWidth", _viewportWidth);
-        fprintfElement(file, "viewportHeight", _viewportHeight);
-    }
-    else
-    {
-        assert(false);
-    }
-    fprintElementEnd(file);
-}
-
-void Camera::setPerspective()
-{
-    _cameraType = CameraPerspective;
-}
-void Camera::setOrthographic()
-{
-    _cameraType = CameraOrthographic;
-}
-void Camera::setViewportWidth(float width)
-{
-    _viewportWidth = width;
-}
-void Camera::setViewportHeight(float height)
-{
-    _viewportHeight = height;
-}
-
-float Camera::getViewPortWidth()
-{
-    return _viewportWidth;
-}
-float Camera::getViewPortHeight()
-{
-    return _viewportHeight;
-}
-
-}
+#include "Base.h"
+#include "Camera.h"
+
+namespace gameplay
+{
+
+Camera::Camera(void) :
+    _cameraType(CameraPerspective), 
+    _fieldOfView(0.0f),
+    _aspectRatio(0.0f),
+    _nearPlane(0.0f),
+    _farPlane(0.0f),
+    _viewportWidth(0.0f),
+    _viewportHeight(0.0f)
+{
+}
+
+Camera::~Camera(void)
+{
+}
+
+void Camera::setFieldOfView(float value)
+{
+    _fieldOfView = value;
+}
+
+
+void Camera::setAspectRatio(float value)
+{
+    _aspectRatio = value;
+}
+
+
+void Camera::setNearPlane(float value)
+{
+    _nearPlane = value;
+}
+
+
+void Camera::setFarPlane(float value)
+{
+    _farPlane = value;
+}
+
+unsigned int Camera::getTypeId(void) const
+{
+    return CAMERA_ID;
+}
+const char* Camera::getElementName(void) const
+{
+    return "Camera";
+}
+
+void Camera::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    write(_cameraType, file);
+    write(_aspectRatio, file);
+    write(_nearPlane, file);
+    write(_farPlane, file);
+
+    if (_cameraType == CameraPerspective)
+    {
+        write(_fieldOfView, file);
+    }
+    else if (_cameraType == CameraOrthographic)
+    {
+        write(getViewPortWidth(), file);
+        write(getViewPortHeight(), file);
+    }
+    else
+    {
+        assert(false);
+    }
+}
+void Camera::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    fprintfElement(file, "cameraType", _cameraType == CameraPerspective ? "CameraPerspective" : "CameraOrthographic");
+    fprintfElement(file, "aspectRatio", _aspectRatio);
+    fprintfElement(file, "nearPlane", _nearPlane);
+    fprintfElement(file, "farPlane", _farPlane);
+
+    if (_cameraType == CameraPerspective)
+    {
+        fprintfElement(file, "fieldOfView", _fieldOfView);
+    }
+    else if (_cameraType == CameraOrthographic)
+    {
+        fprintfElement(file, "viewportWidth", _viewportWidth);
+        fprintfElement(file, "viewportHeight", _viewportHeight);
+    }
+    else
+    {
+        assert(false);
+    }
+    fprintElementEnd(file);
+}
+
+void Camera::setPerspective()
+{
+    _cameraType = CameraPerspective;
+}
+void Camera::setOrthographic()
+{
+    _cameraType = CameraOrthographic;
+}
+void Camera::setViewportWidth(float width)
+{
+    _viewportWidth = width;
+}
+void Camera::setViewportHeight(float height)
+{
+    _viewportHeight = height;
+}
+
+float Camera::getViewPortWidth()
+{
+    return _viewportWidth;
+}
+float Camera::getViewPortHeight()
+{
+    return _viewportHeight;
+}
+
+}

+ 59 - 59
tools/encoder/src/Camera.h

@@ -1,59 +1,59 @@
-#ifndef CAMERA_H_
-#define CAMERA_H_
-
-#include "Object.h"
-
-namespace gameplay
-{
-
-class Camera : public Object
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    Camera(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~Camera(void);
-
-    virtual unsigned int getTypeId(void) const;
-    virtual const char* getElementName(void) const;
-    virtual void writeBinary(FILE* file);
-    virtual void writeText(FILE* file);
-
-    void setPerspective();
-    void setOrthographic();
-    void setAspectRatio(float value);
-    void setNearPlane(float value);
-    void setFarPlane(float value);
-    void setViewportWidth(float width);
-    void setViewportHeight(float height);
-    void setFieldOfView(float value);
-
-    float getViewPortWidth();
-    float getViewPortHeight();
-
-    enum CameraType
-    {
-        CameraPerspective = 1,
-        CameraOrthographic = 2
-    };
-
-private:
-    
-    unsigned char _cameraType;
-    float _fieldOfView;
-    float _aspectRatio;
-    float _nearPlane;
-    float _farPlane;
-    float _viewportWidth;
-    float _viewportHeight;
-};
-
-}
-
-#endif
+#ifndef CAMERA_H_
+#define CAMERA_H_
+
+#include "Object.h"
+
+namespace gameplay
+{
+
+class Camera : public Object
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Camera(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~Camera(void);
+
+    virtual unsigned int getTypeId(void) const;
+    virtual const char* getElementName(void) const;
+    virtual void writeBinary(FILE* file);
+    virtual void writeText(FILE* file);
+
+    void setPerspective();
+    void setOrthographic();
+    void setAspectRatio(float value);
+    void setNearPlane(float value);
+    void setFarPlane(float value);
+    void setViewportWidth(float width);
+    void setViewportHeight(float height);
+    void setFieldOfView(float value);
+
+    float getViewPortWidth();
+    float getViewPortHeight();
+
+    enum CameraType
+    {
+        CameraPerspective = 1,
+        CameraOrthographic = 2
+    };
+
+private:
+    
+    unsigned char _cameraType;
+    float _fieldOfView;
+    float _aspectRatio;
+    float _nearPlane;
+    float _farPlane;
+    float _viewportWidth;
+    float _viewportHeight;
+};
+
+}
+
+#endif

+ 31 - 31
tools/encoder/src/Constants.cpp

@@ -1,31 +1,31 @@
-#include "Constants.h"
-
-
-namespace gameplay
-{
-
-const std::string SPOT_LIGHT = "SPOT_LIGHT";
-const std::string POINT_LIGHT = "POINT_LIGHT";
-
-const std::string VERTEX_COLOR = "VERTEX_COLOR";
-
-const std::string SPECULAR = "SPECULAR";
-const std::string LINEAR = "LINEAR";
-const std::string CLAMP = "CLAMP";
-const std::string REPEAT = "REPEAT";
-const std::string LINEAR_MIPMAP_LINEAR = "LINEAR_MIPMAP_LINEAR";
-const std::string WORLD_VIEW_PROJECTION_MATRIX = "WORLD_VIEW_PROJECTION_MATRIX";
-
-const std::string TEXTURE_REPEAT = "TEXTURE_REPEAT";
-const std::string TEXTURE_OFFSET = "TEXTURE_OFFSET";
-
-const std::string u_diffuseTexture = "u_diffuseTexture";
-
-const std::string MIN_FILTER = "minFilter";
-const std::string MAG_FILTER = "magFilter";
-
-
-
-
-
-}
+#include "Constants.h"
+
+
+namespace gameplay
+{
+
+const std::string SPOT_LIGHT = "SPOT_LIGHT";
+const std::string POINT_LIGHT = "POINT_LIGHT";
+
+const std::string VERTEX_COLOR = "VERTEX_COLOR";
+
+const std::string SPECULAR = "SPECULAR";
+const std::string LINEAR = "LINEAR";
+const std::string CLAMP = "CLAMP";
+const std::string REPEAT = "REPEAT";
+const std::string LINEAR_MIPMAP_LINEAR = "LINEAR_MIPMAP_LINEAR";
+const std::string WORLD_VIEW_PROJECTION_MATRIX = "WORLD_VIEW_PROJECTION_MATRIX";
+
+const std::string TEXTURE_REPEAT = "TEXTURE_REPEAT";
+const std::string TEXTURE_OFFSET = "TEXTURE_OFFSET";
+
+const std::string u_diffuseTexture = "u_diffuseTexture";
+
+const std::string MIN_FILTER = "minFilter";
+const std::string MAG_FILTER = "magFilter";
+
+
+
+
+
+}

+ 33 - 33
tools/encoder/src/Constants.h

@@ -1,33 +1,33 @@
-#ifndef CONSTANTS_H_
-#define CONSTANTS_H_
-
-#include "string"
-
-namespace gameplay
-{
-
-extern const std::string SPOT_LIGHT;
-extern const std::string POINT_LIGHT;
-
-extern const std::string VERTEX_COLOR;
-
-extern const std::string SPECULAR;
-extern const std::string LINEAR;
-
-extern const std::string CLAMP;
-extern const std::string REPEAT;
-extern const std::string LINEAR_MIPMAP_LINEAR;
-extern const std::string WORLD_VIEW_PROJECTION_MATRIX;
-
-extern const std::string TEXTURE_REPEAT;
-extern const std::string TEXTURE_OFFSET;
-
-extern const std::string u_diffuseTexture;
-
-extern const std::string MIN_FILTER;
-extern const std::string MAG_FILTER;
-
-
-}
-
-#endif
+#ifndef CONSTANTS_H_
+#define CONSTANTS_H_
+
+#include "string"
+
+namespace gameplay
+{
+
+extern const std::string SPOT_LIGHT;
+extern const std::string POINT_LIGHT;
+
+extern const std::string VERTEX_COLOR;
+
+extern const std::string SPECULAR;
+extern const std::string LINEAR;
+
+extern const std::string CLAMP;
+extern const std::string REPEAT;
+extern const std::string LINEAR_MIPMAP_LINEAR;
+extern const std::string WORLD_VIEW_PROJECTION_MATRIX;
+
+extern const std::string TEXTURE_REPEAT;
+extern const std::string TEXTURE_OFFSET;
+
+extern const std::string u_diffuseTexture;
+
+extern const std::string MIN_FILTER;
+extern const std::string MAG_FILTER;
+
+
+}
+
+#endif

+ 1346 - 1346
tools/encoder/src/Curve.cpp

@@ -1,1346 +1,1346 @@
-// Purposely not including Base.h here, or any other gameplay dependencies
-// so this class can be reused between gameplay and gameplay-encoder.
-#include "Curve.h"
-#include "Quaternion.h"
-#include <cassert>
-#include <cmath>
-#include <memory>
-
-using std::memcpy;
-using std::fabs;
-using std::sqrt;
-using std::cos;
-using std::sin;
-using std::exp;
-using std::strcmp;
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef MATH_PI
-#define MATH_PI 3.14159265358979323846f
-#endif
-
-#ifndef MATH_PIOVER2 
-#define MATH_PIOVER2 1.57079632679489661923f
-#endif
-
-#ifndef MATH_PIX2
-#define MATH_PIX2 6.28318530717958647693f
-#endif
-
-// Object deletion macro
-#ifndef SAFE_DELETE
-#define SAFE_DELETE(x) \
-    if (x) \
-    { \
-        delete x; \
-        x = NULL; \
-    }
-#endif
-
-// Array deletion macro
-#ifndef SAFE_DELETE_ARRAY
-#define SAFE_DELETE_ARRAY(x) \
-    if (x) \
-    { \
-        delete[] x; \
-        x = NULL; \
-    }
-#endif
-
-
-namespace gameplay
-{
-
-Curve::Curve(unsigned int pointCount, unsigned int componentCount)
-    : _pointCount(pointCount), _componentCount(componentCount), _componentSize(sizeof(float)*componentCount), _quaternionOffset(NULL), _points(NULL)
-{
-    _points = new Point[_pointCount];
-    for (unsigned int i = 0; i < _pointCount; i++)
-    {
-        _points[i].time = 0.0f;
-        _points[i].value = new float[_componentCount];
-        _points[i].inValue = new float[_componentCount];
-        _points[i].outValue = new float[_componentCount];
-        _points[i].type = LINEAR;
-    }
-    _points[_pointCount - 1].time = 1.0f;
-}
-
-Curve::~Curve()
-{
-    SAFE_DELETE_ARRAY(_points);
-    SAFE_DELETE_ARRAY(_quaternionOffset);
-}
-
-Curve::Point::Point()
-    : time(0.0f), value(NULL), inValue(NULL), outValue(NULL)
-{
-}
-
-Curve::Point::~Point()
-{
-    SAFE_DELETE_ARRAY(value);
-    SAFE_DELETE_ARRAY(inValue);
-    SAFE_DELETE_ARRAY(outValue);
-}
-
-unsigned int Curve::getPointCount() const
-{
-    return _pointCount;
-}
-
-unsigned int Curve::getComponentCount() const
-{
-    return _componentCount;
-}
-
-float Curve::getStartTime() const
-{
-    return _points[0].time;
-}
-
-float Curve::getEndTime() const
-{
-    return _points[_pointCount-1].time;
-}
-
-void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type)
-{
-    setPoint(index, time, value, type, NULL, NULL);
-}
-
-void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type, float* inValue, float* outValue)
-{
-    assert(index < _pointCount && time >= 0.0f && time <= 1.0f && !(index == 0 && time != 0.0f) && !(index == _pointCount - 1 && time != 1.0f));
-
-    _points[index].time = time;
-    _points[index].type = type;
-
-    if (value)
-        memcpy(_points[index].value, value, _componentSize);
-
-    if (inValue)
-        memcpy(_points[index].inValue, inValue, _componentSize);
-
-    if (outValue)
-        memcpy(_points[index].outValue, outValue, _componentSize);
-}
-
-void Curve::setTangent(unsigned int index, InterpolationType type, float* inValue, float* outValue)
-{
-    assert(index < _pointCount);
-
-    _points[index].type = type;
-
-    if (inValue)
-        memcpy(_points[index].inValue, inValue, _componentSize);
-
-    if (outValue)
-        memcpy(_points[index].outValue, outValue, _componentSize);
-}
-
-void Curve::evaluate(float time, float* dst) const
-{
-    assert(dst && time >= 0 && time <= 1.0f);
-
-    // Check if we are at or beyond the bounds of the curve.
-    if (time <= _points[0].time)
-    {
-        memcpy(dst, _points[0].value, _componentSize);
-        return;
-    }
-    else if (time >= _points[_pointCount - 1].time)
-    {
-        memcpy(dst, _points[_pointCount - 1].value, _componentSize);
-        return;
-    }
-
-    // Locate the points we are interpolating between using a binary search.
-    unsigned int index = determineIndex(time);
-    
-    Point* from = _points + index;
-    Point* to = _points + (index + 1);
-
-    // Calculate the fractional time between the two points.
-    float scale = (to->time - from->time);
-    float t = (time - from->time) / scale;
-
-    // Calculate the value of the curve discretely if appropriate.
-    switch (from->type)
-    {
-        case BEZIER:
-        {
-            interpolateBezier(t, from, to, dst);
-            return;
-        }
-        case BSPLINE:
-        {
-            Point* c0;
-            Point* c1;
-            if (index == 0)
-            {
-                c0 = from;
-            }
-            else
-            {
-                c0 = (_points + index - 1);
-            }
-            
-            if (index == _pointCount - 2)
-            {
-                c1 = to;
-            }
-            else
-            {
-                c1 = (_points + index + 2);
-            }
-            interpolateBSpline(t, c0, from, to, c1, dst);
-            return;
-        }
-        case FLAT:
-        {
-            interpolateHermiteFlat(t, from, to, dst);
-            return;
-        }
-        case HERMITE:
-        {
-            interpolateHermite(t, from, to, dst);
-            return;
-        }
-        case LINEAR:
-        {
-            // Can just break here because linear formula follows switch
-            break;
-        }
-        case SMOOTH:
-        {
-            interpolateHermiteSmooth(t, index, from, to, dst);
-            return;
-        }
-        case STEP:
-        {
-            memcpy(dst, from->value, _componentSize);
-            return;
-        }
-        case QUADRATIC_IN:
-        {
-            t *= t;
-            break;
-        }
-        case QUADRATIC_OUT:
-        {
-            t *= -(t - 2.0f);
-            break;
-        }
-        case QUADRATIC_IN_OUT:
-        {
-            float tx2 = t * 2.0f;
-
-            if (tx2 < 1.0f)
-                t = 0.5f * (tx2 * tx2);
-            else
-            {
-                float temp = tx2 - 1.0f;
-                t = 0.5f * (-( temp * (temp - 2.0f)) + 1.0f);
-            }
-            break;
-        }
-        case QUADRATIC_OUT_IN:
-        {
-            if (t < 0.5f)
-            {
-                t = 2.0f * t * (1.0f - t);
-            }
-            else
-            {
-                t = 1.0f + 2.0f * t * (t - 1.0f);
-            }
-            break;
-        }
-        case CUBIC_IN:
-        {
-            t *= t * t;
-            break;
-        }
-        case CUBIC_OUT:
-        {
-            t--;
-            t = t * t * t + 1;
-            break;
-        }
-        case CUBIC_IN_OUT:
-        {
-            if ((t *= 2.0f) < 1.0f)
-            {
-                t = t * t * t * 0.5f;
-            }
-            else
-            {
-                t -= 2.0f;
-                t = (t * t * t + 2.0f) * 0.5f;
-            }
-            break;
-        }
-        case CUBIC_OUT_IN:
-        {
-            t = (2.0f * t - 1.0f);
-            t = (t * t * t + 1) * 0.5f;
-            break;
-        }
-        case QUARTIC_IN:
-        {
-            t *= t * t * t;
-            break;
-        }
-        case QUARTIC_OUT:
-        {
-            t--;
-            t = -(t * t * t * t) + 1.0f;
-            break;
-        }
-        case QUARTIC_IN_OUT:
-        {
-            t *= 2.0f;
-            if (t < 1.0f)
-            {
-                t = 0.5f * t * t * t * t;
-            }
-            else
-            {
-                t -= 2.0f;
-                t = -0.5f * (t * t * t * t - 2.0f);
-            }
-            break;
-        }
-        case QUARTIC_OUT_IN:
-        {
-            t = 2.0f * t - 1.0f;
-            if (t < 0.0f)
-            {
-                t = 0.5f * (-(t * t) * t * t + 1.0f);
-            }
-            else
-            {
-                t = 0.5f * (t * t * t * t + 1.0f);
-            }
-            break;
-        }
-        case QUINTIC_IN:
-        {
-            t *= t * t * t * t;
-            break;
-        }
-        case QUINTIC_OUT:
-        {
-            t--;
-            t = t * t * t * t * t + 1.0f;
-            break;
-        }
-        case QUINTIC_IN_OUT:
-        {
-            t *= 2.0f;
-            if (t < 1.0f)
-            {
-                t = 0.5f * t * t * t * t * t;
-            }
-            else
-            {
-                t -= 2.0f;
-                t = 0.5f * (t * t * t * t * t + 2.0f);
-            }
-            break;
-        }
-        case QUINTIC_OUT_IN:
-        {
-            t = 2.0f * t - 1.0f;
-            t = 0.5f * (t * t * t * t * t + 1.0f);
-            break;
-        }
-        case SINE_IN:
-        {
-            t = -(cos(t * MATH_PIOVER2) - 1.0f);
-            break;
-        }
-        case SINE_OUT:
-        {
-            t = sin(t * MATH_PIOVER2);
-            break;
-        }
-        case SINE_IN_OUT:
-        {
-            t = -0.5f * (cos(MATH_PI * t) - 1.0f);
-            break;
-        }
-        case SINE_OUT_IN:
-        {
-            if (t < 0.5f)
-            {
-                t = 0.5f * sin(MATH_PI * t);
-            }
-            else
-            {
-                t = -0.5f * cos(MATH_PIOVER2 * (2.0f * t - 1.0f)) + 1.0f;
-            }
-            break;
-        }
-        case EXPONENTIAL_IN:
-        {
-            if (t != 0.0f)
-            {
-                t = exp(10.0f * (t - 1.0f));
-            }
-            break;
-        }
-        case EXPONENTIAL_OUT:
-        {
-            if (t != 1.0f)
-            {
-                t = -exp(-10.0f * t) + 1.0f;
-            }
-            break;
-        }
-        case EXPONENTIAL_IN_OUT:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                if (t < 0.5f)
-                {
-                    t = 0.5f * exp(10.0f * (2.0f * t - 1.0f));
-                }
-                else
-                {
-                    t = -0.5f * exp(10.0f * (-2.0f * t + 1.0f)) + 1.0f;
-                }
-            }
-            break;
-        }
-        case EXPONENTIAL_OUT_IN:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                if (t < 0.5f)
-                {
-                    t = -0.5f * exp(-20.0f * t) + 0.5f;
-                }
-                else
-                {
-                    t = 0.5f * exp(20.0f * (t - 1.0f)) + 0.5f;
-                }
-            }
-            break;
-        }
-        case CIRCULAR_IN:
-        {
-            t = -(sqrt(1.0f - t * t) - 1.0f);
-            break;
-        }
-        case CIRCULAR_OUT:
-        {
-            t--;
-            t = sqrt(1.0f - t * t);
-            break;
-        }
-        case CIRCULAR_IN_OUT:
-        {
-            t *= 2.0f;
-            if (t < 1.0f)
-            {
-                t = 0.5f * (-sqrt((1.0f - t * t)) + 1.0f);
-            }
-            else
-            {
-                t -= 2.0f;
-                t = 0.5f * (sqrt((1.0f - t * t)) + 1.0f);
-            }
-            break;
-        }
-        case CIRCULAR_OUT_IN:
-        {
-            t = 2.0f * t - 1.0f;
-            if (t < 0.0f)
-            {
-                t = 0.5f * sqrt(1.0f - t * t);
-            }
-            else
-            {
-                t = 0.5f * (2.0f - sqrt(1.0f - t * t));
-            }
-            break;
-        }
-        case ELASTIC_IN:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                t = t - 1.0f;
-                t = -1.0f * ( exp(10.0f * t) * sin( (t - 0.075f) * MATH_PIX2 / 0.3f ) );
-            }
-            break;
-        }
-        case ELASTIC_OUT:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                t = exp(-10.0f * t) * sin((t - 0.075f) * MATH_PIX2 / 0.3f) + 1.0f;
-            }
-            break;
-        }
-        case ELASTIC_IN_OUT:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                t = 2.0f * t - 1.0f;
-                if (t < 0.0f)
-                {
-                    t = -0.5f * (exp((10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)));
-                }
-                else
-                {
-                    t = 0.5f * exp((-10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)) + 1.0f;
-                }
-            }
-            break;
-        }
-        case ELASTIC_OUT_IN:
-        {
-            if (t != 0.0f && t != 1.0f)
-            {
-                t *= 2.0f;
-                if (t < 1.0f)
-                {
-                    t = 0.5f * (exp((-10 * t)) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
-                }
-                else
-                {
-                    t = 0.5f * (exp((10 *(t - 2))) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
-                }
-            }
-            break;
-        }
-        case OVERSHOOT_IN:
-        {
-            t = t * t * (2.70158f * t - 1.70158f);
-            break;
-        }
-        case OVERSHOOT_OUT:
-        {
-            t--;
-            t = t * t * (2.70158f * t + 1.70158f) + 1;
-            break;
-        }
-        case OVERSHOOT_IN_OUT:
-        {
-            t *= 2.0f;
-            if (t < 1.0f)
-            {
-                t = 0.5f * t * t * (3.5949095f * t - 2.5949095f);
-            }
-            else
-            {
-                t -= 2.0f;
-                t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 2.0f);
-            }
-            break;
-        }
-        case OVERSHOOT_OUT_IN:
-        {
-            t = 2.0f * t - 1.0f;
-            if (t < 0.0f)
-            {
-                t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 1.0f);
-            }
-            else
-            {
-                t = 0.5f * (t * t * (3.5949095f * t - 2.5949095f) + 1.0f);
-            }
-            break;
-        }
-        case BOUNCE_IN:
-        {
-            t = 1.0f - t;
-
-            if (t < 0.36363636363636365f)
-            {
-                t = 7.5625f * t * t;
-            }
-            else if (t < 0.7272727272727273f)
-            {
-                t -= 0.5454545454545454f;
-                t = 7.5625f * t * t + 0.75f;
-            }
-            else if (t < 0.9090909090909091f)
-            {
-                t -= 0.8181818181818182f;
-                t = 7.5625f * t * t + 0.9375f;
-            }
-            else
-            {
-                t -= 0.9545454545454546f;
-                t = 7.5625f * t * t + 0.984375f;
-            }
-
-            t = 1.0f - t;
-            break;
-        }
-        case BOUNCE_OUT:
-        {
-            if (t < 0.36363636363636365f)
-            {
-                t = 7.5625f * t * t;
-            }
-            else if (t < 0.7272727272727273f)
-            {
-                t -= 0.5454545454545454f;
-                t = 7.5625f * t * t + 0.75f;
-            }
-            else if (t < 0.9090909090909091f)
-            {
-                t -= 0.8181818181818182f;
-                t = 7.5625f * t * t + 0.9375f;
-            }
-            else
-            {
-                t -= 0.9545454545454546f;
-                t = 7.5625f * t * t + 0.984375f;
-            }
-            break;
-        }
-        case BOUNCE_IN_OUT:
-        {
-            if (t < 0.5f)
-            {
-                t = 1.0f - t * 2.0f;
-
-                if (t < 0.36363636363636365f)
-                {
-                    t = 7.5625f * t * t;
-                }
-                else if (t < 0.7272727272727273f)
-                {
-                    t -= 0.5454545454545454f;
-                    t = 7.5625f * t * t + 0.75f;
-                }
-                else if (t < 0.9090909090909091f)
-                {
-                    t -= 0.8181818181818182f;
-                    t = 7.5625f * t * t + 0.9375f;
-                }
-                else
-                {
-                    t -= 0.9545454545454546f;
-                    t = 7.5625f * t * t + 0.984375f;
-                }
-
-                t = (1.0f - t) * 0.5f;
-            }
-            else
-            {
-                t = t * 2.0f - 1.0f;
-                if (t < 0.36363636363636365f)
-                {
-                    t = 7.5625f * t * t;
-                }
-                else if (t < 0.7272727272727273f)
-                {
-                    t -= 0.5454545454545454f;
-                    t = 7.5625f * t * t + 0.75f;
-                }
-                else if (t < 0.9090909090909091f)
-                {
-                    t -= 0.8181818181818182f;
-                    t = 7.5625f * t * t + 0.9375f;
-                }
-                else
-                {
-                    t -= 0.9545454545454546f;
-                    t = 7.5625f * t * t + 0.984375f;
-                }
-
-                t = 0.5f * t + 0.5f;
-            }
-            break;
-        }
-        case BOUNCE_OUT_IN:
-        {
-            if (t < 0.1818181818f)
-            {
-                t = 15.125f * t * t;
-            }
-            else if (t < 0.3636363636f)
-            {
-                t = 1.5f + (-8.250000001f + 15.125f * t) * t;
-            }
-            else if (t < 0.4545454546f)
-            {
-                t = 3.0f + (-12.375f + 15.125f * t) * t;
-            }
-            else if (t < 0.5f)
-            {
-                t = 3.9375f + (-14.4375f + 15.125f * t) * t;
-            }
-            else if (t <= 0.5454545455f)
-            {
-                t = -3.625000004f + (15.81250001f - 15.125f * t) * t;
-            }
-            else if (t <= 0.6363636365f)
-            {
-                t = -4.75f + (17.875f - 15.125f * t) * t;
-            }
-            else if (t <= 0.8181818180f)
-            {
-                t = -7.374999995f + (21.99999999f - 15.125f * t) * t;
-            }
-            else
-            {
-                t = -14.125f + (30.25f - 15.125f * t) * t;
-            }
-            break;
-        }
-    }
-
-    interpolateLinear(t, from, to, dst);
-}
-
-float Curve::lerp(float t, float from, float to)
-{
-    return lerpInl(t, from, to);
-}
-
-void Curve::setQuaternionOffset(unsigned int offset)
-{
-    assert(offset <= (_componentCount - 4));
-
-    if (!_quaternionOffset)
-        _quaternionOffset = new unsigned int[1];
-    
-    *_quaternionOffset = offset;
-}
-
-void Curve::interpolateBezier(float s, Point* from, Point* to, float* dst) const
-{
-    float s_2 = s * s;
-    float eq0 = 1 - s;
-    float eq0_2 = eq0 * eq0;
-    float eq1 = eq0_2 * eq0;
-    float eq2 = 3 * s * eq0_2;
-    float eq3 = 3 * s_2 * eq0;
-    float eq4 = s_2 * s;
-
-    float* fromValue = from->value;
-    float* toValue = to->value;
-    float* outValue = from->outValue;
-    float* inValue = to->inValue;
-
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-
-        // Handle quaternion component.
-        float interpTime = bezier(eq1, eq2, eq3, eq4, from->time, outValue[i], to->time, inValue[i]);
-        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
-        
-        // Handle remaining components (if any) as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-    }
-}
-
-void Curve::interpolateBSpline(float s, Point* c0, Point* c1, Point* c2, Point* c3, float* dst) const
-{   
-    float s_2 = s * s;
-    float s_3 = s_2 * s;
-    float eq0 = (-s_3 + 3 * s_2 - 3 * s + 1) / 6.0f;
-    float eq1 = (3 * s_3 - 6 * s_2 + 4) / 6.0f;
-    float eq2 = (-3 * s_3 + 3 * s_2 + 3 * s + 1) / 6.0f;
-    float eq3 = s_3 / 6.0f;
-
-    float* c0Value = c0->value;
-    float* c1Value = c1->value;
-    float* c2Value = c2->value;
-    float* c3Value = c3->value;
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (c1Value[i] == c2Value[i])
-                dst[i] = c1Value[i];
-            else
-                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {
-            if (c1Value[i] == c2Value[i])
-                dst[i] = c1Value[i];
-            else
-                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
-        }
-
-        // Handle quaternion component.
-        float interpTime;
-        if (c0->time == c1->time)
-            interpTime = bspline(eq0, eq1, eq2, eq3, -c0->time, c1->time, c2->time, c3->time);
-        else if (c2->time == c3->time)
-            interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, -c3->time); 
-        else
-            interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, c3->time);
-        interpolateQuaternion(s, (c1Value + i) , (c2Value + i), (dst + i));
-            
-        // Handle remaining components (if any) as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (c1Value[i] == c2Value[i])
-                dst[i] = c1Value[i];
-            else
-                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
-        }
-    }
-}
-
-void Curve::interpolateHermite(float s, Point* from, Point* to, float* dst) const
-{
-    // Calculate the hermite basis functions.
-    float s_2 = s * s;                   // t^2
-    float s_3 = s_2 * s;                 // t^3
-    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
-    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
-    float h10 = s_3 - 2 * s_2 + s;       // basis function 2
-    float h11 = s_3 - s_2;               // basis function 3
-
-    float* fromValue = from->value;
-    float* toValue = to->value;
-    float* outValue = from->outValue;
-    float* inValue = to->inValue;
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-
-        // Handle quaternion component.
-        float interpTime = hermite(h00, h01, h10, h11, from->time, outValue[i], to->time, inValue[i]);
-        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
-        
-        // Handle remaining components (if any) as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
-        }
-    }
-}
-
-void Curve::interpolateHermiteFlat(float s, Point* from, Point* to, float* dst) const
-{
-    // Calculate the hermite basis functions.
-    float s_2 = s * s;                   // t^2
-    float s_3 = s_2 * s;                 // t^3
-    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
-    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
-
-    float* fromValue = from->value;
-    float* toValue = to->value;
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
-        }
-
-        // Handle quaternion component.
-        float interpTime = hermiteFlat(h00, h01, from->time, to->time);
-        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
-        
-        // Handle remaining components (if any) as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
-        }
-    }
-}
-
-void Curve::interpolateHermiteSmooth(float s, unsigned int index, Point* from, Point* to, float* dst) const
-{
-    // Calculate the hermite basis functions.
-    float s_2 = s * s;                   // t^2
-    float s_3 = s_2 * s;                 // t^3
-    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
-    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
-    float h10 = s_3 - 2 * s_2 + s;       // basis function 2
-    float h11 = s_3 - s_2;               // basis function 3
-
-    float inValue;
-    float outValue;
-
-    float* fromValue = from->value;
-    float* toValue = to->value;
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-            {
-                dst[i] = fromValue[i];
-            }
-            else
-            {
-                if (index == 0)
-                {
-                    outValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
-                }
-
-                if (index == _pointCount - 2)
-                {
-                    inValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
-                }
-
-                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
-            }
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {   
-            if (fromValue[i] == toValue[i])
-            {
-                dst[i] = fromValue[i];
-            }
-            else
-            {    
-                if (index == 0)
-                {
-                    outValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
-                }
-
-                if (index == _pointCount - 2)
-                {
-                    inValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
-                }
-
-                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
-            }
-        }
-
-        // Handle quaternion component.
-        if (index == 0)
-        {
-            outValue = to->time - from->time;
-        }
-        else
-        {
-            outValue = (to->time - (from - 1)->time) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
-        }
-
-        if (index == _pointCount - 2)
-        {
-            inValue = to->time - from->time;
-        }
-        else
-        {
-            inValue = ((to + 1)->time - from->time) * ((to->time - from->time) / ((to + 1)->time - from->time));
-        }
-
-        float interpTime = hermiteSmooth(h00, h01, h10, h11, from->time, outValue, to->time, inValue);
-        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
-        
-        // Handle remaining components (if any) as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-            {
-                dst[i] = fromValue[i];
-            }
-            else
-            {
-                // Interpolate as scalar.
-                if (index == 0)
-                {
-                    outValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
-                }
-
-                if (index == _pointCount - 2)
-                {
-                    inValue = toValue[i] - fromValue[i];
-                }
-                else
-                {
-                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
-                }
-
-                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
-            }
-        }
-    }
-}
-
-void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
-{
-    float* fromValue = from->value;
-    float* toValue = to->value;
-
-    if (!_quaternionOffset)
-    {
-        for (unsigned int i = 0; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
-        }
-    }
-    else
-    {
-        // Interpolate any values up to the quaternion offset as scalars.
-        unsigned int quaternionOffset = *_quaternionOffset;
-        unsigned int i = 0;
-        for (i = 0; i < quaternionOffset; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
-        }
-
-        // Handle quaternion component.
-        interpolateQuaternion(s, (fromValue + i), (toValue + i), (dst + i));
-        
-        // handle any remaining components as scalars
-        for (i += 4; i < _componentCount; i++)
-        {
-            if (fromValue[i] == toValue[i])
-                dst[i] = fromValue[i];
-            else
-                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
-        }
-    }
-}
-
-void Curve::interpolateQuaternion(float s, float* from, float* to, float* dst) const
-{
-    // Evaluate.
-    if (s >= 0)
-    {
-        Quaternion::slerp(from[0], from[1], from[2], from[3], to[0], to[1], to[2], to[3], s, dst, dst + 1, dst + 2, dst + 3);
-    }
-    else
-        Quaternion::slerp(to[0], to[1], to[2], to[3], from[0], from[1], from[2], from[3], s, dst, dst + 1, dst + 2, dst + 3);
-
-    //((Quaternion*) dst)->normalize();
-}
-
-int Curve::determineIndex(float time) const
-{
-    unsigned int min = 0;
-    unsigned int max = _pointCount - 1;
-    unsigned int mid = 0;
-
-    // Do a binary search to determine the index.
-    do 
-    {
-        mid = (min + max) >> 1;
-
-        if (time >= _points[mid].time && time <= _points[mid + 1].time)
-            return mid;
-        else if (time < _points[mid].time)
-            max = mid - 1;
-        else
-            min = mid + 1;
-    } while (min <= max);
-    
-    // We should never hit this!
-    return -1;
-}
-
-int Curve::getInterpolationType(const char* curveId)
-{
-    if (strcmp(curveId, "BEZIER") == 0)
-    {
-        return Curve::BEZIER;
-    }
-    else if (strcmp(curveId, "BSPLINE") == 0)
-    {
-        return Curve::BSPLINE;
-    }
-    else if (strcmp(curveId, "FLAT") == 0)
-    {
-        return Curve::FLAT;
-    }
-    else if (strcmp(curveId, "HERMITE") == 0)
-    {
-        return Curve::HERMITE;
-    }
-    else if (strcmp(curveId, "LINEAR") == 0)
-    {
-        return Curve::LINEAR;
-    }
-    else if (strcmp(curveId, "SMOOTH") == 0)
-    {
-        return Curve::SMOOTH;
-    }
-    else if (strcmp(curveId, "STEP") == 0)
-    {
-        return Curve::STEP;
-    }
-    else if (strcmp(curveId, "QUADRATIC_IN") == 0)
-    {
-        return Curve::QUADRATIC_IN;
-    }
-    else if (strcmp(curveId, "QUADRATIC_OUT") == 0)
-    {
-        return Curve::QUADRATIC_OUT;
-    }
-    else if (strcmp(curveId, "QUADRATIC_IN_OUT") == 0)
-    {
-        return Curve::QUADRATIC_IN_OUT;
-    }
-    else if (strcmp(curveId, "QUADRATIC_OUT_IN") == 0)
-    {
-        return Curve::QUADRATIC_OUT_IN;
-    }
-    else if (strcmp(curveId, "CUBIC_IN") == 0)
-    {
-        return Curve::CUBIC_IN;
-    }
-    else if (strcmp(curveId, "CUBIC_OUT") == 0)
-    {
-        return Curve::CUBIC_OUT;
-    }
-    else if (strcmp(curveId, "CUBIC_IN_OUT") == 0)
-    {
-        return Curve::CUBIC_IN_OUT;
-    }
-    else if (strcmp(curveId, "CUBIC_OUT_IN") == 0)
-    {
-        return Curve::CUBIC_OUT_IN;
-    }
-    else if (strcmp(curveId, "QUARTIC_IN") == 0)
-    {
-        return Curve::QUARTIC_IN;
-    }
-    else if (strcmp(curveId, "QUARTIC_OUT") == 0)
-    {
-        return Curve::QUARTIC_OUT;
-    }
-    else if (strcmp(curveId, "QUARTIC_IN_OUT") == 0)
-    {
-        return Curve::QUARTIC_IN_OUT;
-    }
-    else if (strcmp(curveId, "QUARTIC_OUT_IN") == 0)
-    {
-        return Curve::QUARTIC_OUT_IN;
-    }
-    else if (strcmp(curveId, "QUINTIC_IN") == 0)
-    {
-        return Curve::QUINTIC_IN;
-    }
-    else if (strcmp(curveId, "QUINTIC_OUT") == 0)
-    {
-        return Curve::QUINTIC_OUT;
-    }
-    else if (strcmp(curveId, "QUINTIC_IN_OUT") == 0)
-    {
-        return Curve::QUINTIC_IN_OUT;
-    }
-    else if (strcmp(curveId, "QUINTIC_OUT_IN") == 0)
-    {
-        return Curve::QUINTIC_OUT_IN;
-    }
-    else if (strcmp(curveId, "SINE_IN") == 0)
-    {
-        return Curve::SINE_IN;
-    }
-    else if (strcmp(curveId, "SINE_OUT") == 0)
-    {
-        return Curve::SINE_OUT;
-    }
-    else if (strcmp(curveId, "SINE_IN_OUT") == 0)
-    {
-        return Curve::SINE_IN_OUT;
-    }
-    else if (strcmp(curveId, "SINE_OUT_IN") == 0)
-    {
-        return Curve::SINE_OUT_IN;
-    }
-    else if (strcmp(curveId, "EXPONENTIAL_IN") == 0)
-    {
-        return Curve::EXPONENTIAL_IN;
-    }
-    else if (strcmp(curveId, "EXPONENTIAL_OUT") == 0)
-    {
-        return Curve::EXPONENTIAL_OUT;
-    }
-    else if (strcmp(curveId, "EXPONENTIAL_IN_OUT") == 0)
-    {
-        return Curve::EXPONENTIAL_IN_OUT;
-    }
-    else if (strcmp(curveId, "EXPONENTIAL_OUT_IN") == 0)
-    {
-        return Curve::EXPONENTIAL_OUT_IN;
-    }
-    else if (strcmp(curveId, "CIRCULAR_IN") == 0)
-    {
-        return Curve::CIRCULAR_IN;
-    }
-    else if (strcmp(curveId, "CIRCULAR_OUT") == 0)
-    {
-        return Curve::CIRCULAR_OUT;
-    }
-    else if (strcmp(curveId, "CIRCULAR_IN_OUT") == 0)
-    {
-        return Curve::CIRCULAR_IN_OUT;
-    }
-    else if (strcmp(curveId, "CIRCULAR_OUT_IN") == 0)
-    {
-        return Curve::CIRCULAR_OUT_IN;
-    }
-    else if (strcmp(curveId, "ELASTIC_IN") == 0)
-    {
-        return Curve::ELASTIC_IN;
-    }
-    else if (strcmp(curveId, "ELASTIC_OUT") == 0)
-    {
-        return Curve::ELASTIC_OUT;
-    }
-    else if (strcmp(curveId, "ELASTIC_IN_OUT") == 0)
-    {
-        return Curve::ELASTIC_IN_OUT;
-    }
-    else if (strcmp(curveId, "ELASTIC_OUT_IN") == 0)
-    {
-        return Curve::ELASTIC_OUT_IN;
-    }
-    else if (strcmp(curveId, "OVERSHOOT_IN") == 0)
-    {
-        return Curve::OVERSHOOT_IN;
-    }
-    else if (strcmp(curveId, "OVERSHOOT_OUT") == 0)
-    {
-        return Curve::OVERSHOOT_OUT;
-    }
-    else if (strcmp(curveId, "OVERSHOOT_IN_OUT") == 0)
-    {
-        return Curve::OVERSHOOT_IN_OUT;
-    }
-    else if (strcmp(curveId, "OVERSHOOT_OUT_IN") == 0)
-    {
-        return Curve::OVERSHOOT_OUT_IN;
-    }
-    else if (strcmp(curveId, "BOUNCE_IN") == 0)
-    {
-        return Curve::BOUNCE_IN;
-    }
-    else if (strcmp(curveId, "BOUNCE_OUT") == 0)
-    {
-        return Curve::BOUNCE_OUT;
-    }
-    else if (strcmp(curveId, "BOUNCE_IN_OUT") == 0)
-    {
-        return Curve::BOUNCE_IN_OUT;
-    }
-    else if (strcmp(curveId, "BOUNCE_OUT_IN") == 0)
-    {
-        return Curve::BOUNCE_OUT_IN;
-    }
-
-    return -1;
-}
-
-}
+// Purposely not including Base.h here, or any other gameplay dependencies
+// so this class can be reused between gameplay and gameplay-encoder.
+#include "Curve.h"
+#include "Quaternion.h"
+#include <cassert>
+#include <cmath>
+#include <memory>
+
+using std::memcpy;
+using std::fabs;
+using std::sqrt;
+using std::cos;
+using std::sin;
+using std::exp;
+using std::strcmp;
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef MATH_PI
+#define MATH_PI 3.14159265358979323846f
+#endif
+
+#ifndef MATH_PIOVER2 
+#define MATH_PIOVER2 1.57079632679489661923f
+#endif
+
+#ifndef MATH_PIX2
+#define MATH_PIX2 6.28318530717958647693f
+#endif
+
+// Object deletion macro
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(x) \
+    if (x) \
+    { \
+        delete x; \
+        x = NULL; \
+    }
+#endif
+
+// Array deletion macro
+#ifndef SAFE_DELETE_ARRAY
+#define SAFE_DELETE_ARRAY(x) \
+    if (x) \
+    { \
+        delete[] x; \
+        x = NULL; \
+    }
+#endif
+
+
+namespace gameplay
+{
+
+Curve::Curve(unsigned int pointCount, unsigned int componentCount)
+    : _pointCount(pointCount), _componentCount(componentCount), _componentSize(sizeof(float)*componentCount), _quaternionOffset(NULL), _points(NULL)
+{
+    _points = new Point[_pointCount];
+    for (unsigned int i = 0; i < _pointCount; i++)
+    {
+        _points[i].time = 0.0f;
+        _points[i].value = new float[_componentCount];
+        _points[i].inValue = new float[_componentCount];
+        _points[i].outValue = new float[_componentCount];
+        _points[i].type = LINEAR;
+    }
+    _points[_pointCount - 1].time = 1.0f;
+}
+
+Curve::~Curve()
+{
+    SAFE_DELETE_ARRAY(_points);
+    SAFE_DELETE_ARRAY(_quaternionOffset);
+}
+
+Curve::Point::Point()
+    : time(0.0f), value(NULL), inValue(NULL), outValue(NULL)
+{
+}
+
+Curve::Point::~Point()
+{
+    SAFE_DELETE_ARRAY(value);
+    SAFE_DELETE_ARRAY(inValue);
+    SAFE_DELETE_ARRAY(outValue);
+}
+
+unsigned int Curve::getPointCount() const
+{
+    return _pointCount;
+}
+
+unsigned int Curve::getComponentCount() const
+{
+    return _componentCount;
+}
+
+float Curve::getStartTime() const
+{
+    return _points[0].time;
+}
+
+float Curve::getEndTime() const
+{
+    return _points[_pointCount-1].time;
+}
+
+void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type)
+{
+    setPoint(index, time, value, type, NULL, NULL);
+}
+
+void Curve::setPoint(unsigned int index, float time, float* value, InterpolationType type, float* inValue, float* outValue)
+{
+    assert(index < _pointCount && time >= 0.0f && time <= 1.0f && !(index == 0 && time != 0.0f) && !(index == _pointCount - 1 && time != 1.0f));
+
+    _points[index].time = time;
+    _points[index].type = type;
+
+    if (value)
+        memcpy(_points[index].value, value, _componentSize);
+
+    if (inValue)
+        memcpy(_points[index].inValue, inValue, _componentSize);
+
+    if (outValue)
+        memcpy(_points[index].outValue, outValue, _componentSize);
+}
+
+void Curve::setTangent(unsigned int index, InterpolationType type, float* inValue, float* outValue)
+{
+    assert(index < _pointCount);
+
+    _points[index].type = type;
+
+    if (inValue)
+        memcpy(_points[index].inValue, inValue, _componentSize);
+
+    if (outValue)
+        memcpy(_points[index].outValue, outValue, _componentSize);
+}
+
+void Curve::evaluate(float time, float* dst) const
+{
+    assert(dst && time >= 0 && time <= 1.0f);
+
+    // Check if we are at or beyond the bounds of the curve.
+    if (time <= _points[0].time)
+    {
+        memcpy(dst, _points[0].value, _componentSize);
+        return;
+    }
+    else if (time >= _points[_pointCount - 1].time)
+    {
+        memcpy(dst, _points[_pointCount - 1].value, _componentSize);
+        return;
+    }
+
+    // Locate the points we are interpolating between using a binary search.
+    unsigned int index = determineIndex(time);
+    
+    Point* from = _points + index;
+    Point* to = _points + (index + 1);
+
+    // Calculate the fractional time between the two points.
+    float scale = (to->time - from->time);
+    float t = (time - from->time) / scale;
+
+    // Calculate the value of the curve discretely if appropriate.
+    switch (from->type)
+    {
+        case BEZIER:
+        {
+            interpolateBezier(t, from, to, dst);
+            return;
+        }
+        case BSPLINE:
+        {
+            Point* c0;
+            Point* c1;
+            if (index == 0)
+            {
+                c0 = from;
+            }
+            else
+            {
+                c0 = (_points + index - 1);
+            }
+            
+            if (index == _pointCount - 2)
+            {
+                c1 = to;
+            }
+            else
+            {
+                c1 = (_points + index + 2);
+            }
+            interpolateBSpline(t, c0, from, to, c1, dst);
+            return;
+        }
+        case FLAT:
+        {
+            interpolateHermiteFlat(t, from, to, dst);
+            return;
+        }
+        case HERMITE:
+        {
+            interpolateHermite(t, from, to, dst);
+            return;
+        }
+        case LINEAR:
+        {
+            // Can just break here because linear formula follows switch
+            break;
+        }
+        case SMOOTH:
+        {
+            interpolateHermiteSmooth(t, index, from, to, dst);
+            return;
+        }
+        case STEP:
+        {
+            memcpy(dst, from->value, _componentSize);
+            return;
+        }
+        case QUADRATIC_IN:
+        {
+            t *= t;
+            break;
+        }
+        case QUADRATIC_OUT:
+        {
+            t *= -(t - 2.0f);
+            break;
+        }
+        case QUADRATIC_IN_OUT:
+        {
+            float tx2 = t * 2.0f;
+
+            if (tx2 < 1.0f)
+                t = 0.5f * (tx2 * tx2);
+            else
+            {
+                float temp = tx2 - 1.0f;
+                t = 0.5f * (-( temp * (temp - 2.0f)) + 1.0f);
+            }
+            break;
+        }
+        case QUADRATIC_OUT_IN:
+        {
+            if (t < 0.5f)
+            {
+                t = 2.0f * t * (1.0f - t);
+            }
+            else
+            {
+                t = 1.0f + 2.0f * t * (t - 1.0f);
+            }
+            break;
+        }
+        case CUBIC_IN:
+        {
+            t *= t * t;
+            break;
+        }
+        case CUBIC_OUT:
+        {
+            t--;
+            t = t * t * t + 1;
+            break;
+        }
+        case CUBIC_IN_OUT:
+        {
+            if ((t *= 2.0f) < 1.0f)
+            {
+                t = t * t * t * 0.5f;
+            }
+            else
+            {
+                t -= 2.0f;
+                t = (t * t * t + 2.0f) * 0.5f;
+            }
+            break;
+        }
+        case CUBIC_OUT_IN:
+        {
+            t = (2.0f * t - 1.0f);
+            t = (t * t * t + 1) * 0.5f;
+            break;
+        }
+        case QUARTIC_IN:
+        {
+            t *= t * t * t;
+            break;
+        }
+        case QUARTIC_OUT:
+        {
+            t--;
+            t = -(t * t * t * t) + 1.0f;
+            break;
+        }
+        case QUARTIC_IN_OUT:
+        {
+            t *= 2.0f;
+            if (t < 1.0f)
+            {
+                t = 0.5f * t * t * t * t;
+            }
+            else
+            {
+                t -= 2.0f;
+                t = -0.5f * (t * t * t * t - 2.0f);
+            }
+            break;
+        }
+        case QUARTIC_OUT_IN:
+        {
+            t = 2.0f * t - 1.0f;
+            if (t < 0.0f)
+            {
+                t = 0.5f * (-(t * t) * t * t + 1.0f);
+            }
+            else
+            {
+                t = 0.5f * (t * t * t * t + 1.0f);
+            }
+            break;
+        }
+        case QUINTIC_IN:
+        {
+            t *= t * t * t * t;
+            break;
+        }
+        case QUINTIC_OUT:
+        {
+            t--;
+            t = t * t * t * t * t + 1.0f;
+            break;
+        }
+        case QUINTIC_IN_OUT:
+        {
+            t *= 2.0f;
+            if (t < 1.0f)
+            {
+                t = 0.5f * t * t * t * t * t;
+            }
+            else
+            {
+                t -= 2.0f;
+                t = 0.5f * (t * t * t * t * t + 2.0f);
+            }
+            break;
+        }
+        case QUINTIC_OUT_IN:
+        {
+            t = 2.0f * t - 1.0f;
+            t = 0.5f * (t * t * t * t * t + 1.0f);
+            break;
+        }
+        case SINE_IN:
+        {
+            t = -(cos(t * MATH_PIOVER2) - 1.0f);
+            break;
+        }
+        case SINE_OUT:
+        {
+            t = sin(t * MATH_PIOVER2);
+            break;
+        }
+        case SINE_IN_OUT:
+        {
+            t = -0.5f * (cos(MATH_PI * t) - 1.0f);
+            break;
+        }
+        case SINE_OUT_IN:
+        {
+            if (t < 0.5f)
+            {
+                t = 0.5f * sin(MATH_PI * t);
+            }
+            else
+            {
+                t = -0.5f * cos(MATH_PIOVER2 * (2.0f * t - 1.0f)) + 1.0f;
+            }
+            break;
+        }
+        case EXPONENTIAL_IN:
+        {
+            if (t != 0.0f)
+            {
+                t = exp(10.0f * (t - 1.0f));
+            }
+            break;
+        }
+        case EXPONENTIAL_OUT:
+        {
+            if (t != 1.0f)
+            {
+                t = -exp(-10.0f * t) + 1.0f;
+            }
+            break;
+        }
+        case EXPONENTIAL_IN_OUT:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                if (t < 0.5f)
+                {
+                    t = 0.5f * exp(10.0f * (2.0f * t - 1.0f));
+                }
+                else
+                {
+                    t = -0.5f * exp(10.0f * (-2.0f * t + 1.0f)) + 1.0f;
+                }
+            }
+            break;
+        }
+        case EXPONENTIAL_OUT_IN:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                if (t < 0.5f)
+                {
+                    t = -0.5f * exp(-20.0f * t) + 0.5f;
+                }
+                else
+                {
+                    t = 0.5f * exp(20.0f * (t - 1.0f)) + 0.5f;
+                }
+            }
+            break;
+        }
+        case CIRCULAR_IN:
+        {
+            t = -(sqrt(1.0f - t * t) - 1.0f);
+            break;
+        }
+        case CIRCULAR_OUT:
+        {
+            t--;
+            t = sqrt(1.0f - t * t);
+            break;
+        }
+        case CIRCULAR_IN_OUT:
+        {
+            t *= 2.0f;
+            if (t < 1.0f)
+            {
+                t = 0.5f * (-sqrt((1.0f - t * t)) + 1.0f);
+            }
+            else
+            {
+                t -= 2.0f;
+                t = 0.5f * (sqrt((1.0f - t * t)) + 1.0f);
+            }
+            break;
+        }
+        case CIRCULAR_OUT_IN:
+        {
+            t = 2.0f * t - 1.0f;
+            if (t < 0.0f)
+            {
+                t = 0.5f * sqrt(1.0f - t * t);
+            }
+            else
+            {
+                t = 0.5f * (2.0f - sqrt(1.0f - t * t));
+            }
+            break;
+        }
+        case ELASTIC_IN:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                t = t - 1.0f;
+                t = -1.0f * ( exp(10.0f * t) * sin( (t - 0.075f) * MATH_PIX2 / 0.3f ) );
+            }
+            break;
+        }
+        case ELASTIC_OUT:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                t = exp(-10.0f * t) * sin((t - 0.075f) * MATH_PIX2 / 0.3f) + 1.0f;
+            }
+            break;
+        }
+        case ELASTIC_IN_OUT:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                t = 2.0f * t - 1.0f;
+                if (t < 0.0f)
+                {
+                    t = -0.5f * (exp((10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)));
+                }
+                else
+                {
+                    t = 0.5f * exp((-10 * t)) * sin(((t - 0.1125f) * MATH_PIX2 / 0.45f)) + 1.0f;
+                }
+            }
+            break;
+        }
+        case ELASTIC_OUT_IN:
+        {
+            if (t != 0.0f && t != 1.0f)
+            {
+                t *= 2.0f;
+                if (t < 1.0f)
+                {
+                    t = 0.5f * (exp((-10 * t)) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
+                }
+                else
+                {
+                    t = 0.5f * (exp((10 *(t - 2))) * sin(((t - 0.1125f) * (MATH_PIX2) / 0.45f))) + 0.5f;
+                }
+            }
+            break;
+        }
+        case OVERSHOOT_IN:
+        {
+            t = t * t * (2.70158f * t - 1.70158f);
+            break;
+        }
+        case OVERSHOOT_OUT:
+        {
+            t--;
+            t = t * t * (2.70158f * t + 1.70158f) + 1;
+            break;
+        }
+        case OVERSHOOT_IN_OUT:
+        {
+            t *= 2.0f;
+            if (t < 1.0f)
+            {
+                t = 0.5f * t * t * (3.5949095f * t - 2.5949095f);
+            }
+            else
+            {
+                t -= 2.0f;
+                t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 2.0f);
+            }
+            break;
+        }
+        case OVERSHOOT_OUT_IN:
+        {
+            t = 2.0f * t - 1.0f;
+            if (t < 0.0f)
+            {
+                t = 0.5f * (t * t * (3.5949095f * t + 2.5949095f) + 1.0f);
+            }
+            else
+            {
+                t = 0.5f * (t * t * (3.5949095f * t - 2.5949095f) + 1.0f);
+            }
+            break;
+        }
+        case BOUNCE_IN:
+        {
+            t = 1.0f - t;
+
+            if (t < 0.36363636363636365f)
+            {
+                t = 7.5625f * t * t;
+            }
+            else if (t < 0.7272727272727273f)
+            {
+                t -= 0.5454545454545454f;
+                t = 7.5625f * t * t + 0.75f;
+            }
+            else if (t < 0.9090909090909091f)
+            {
+                t -= 0.8181818181818182f;
+                t = 7.5625f * t * t + 0.9375f;
+            }
+            else
+            {
+                t -= 0.9545454545454546f;
+                t = 7.5625f * t * t + 0.984375f;
+            }
+
+            t = 1.0f - t;
+            break;
+        }
+        case BOUNCE_OUT:
+        {
+            if (t < 0.36363636363636365f)
+            {
+                t = 7.5625f * t * t;
+            }
+            else if (t < 0.7272727272727273f)
+            {
+                t -= 0.5454545454545454f;
+                t = 7.5625f * t * t + 0.75f;
+            }
+            else if (t < 0.9090909090909091f)
+            {
+                t -= 0.8181818181818182f;
+                t = 7.5625f * t * t + 0.9375f;
+            }
+            else
+            {
+                t -= 0.9545454545454546f;
+                t = 7.5625f * t * t + 0.984375f;
+            }
+            break;
+        }
+        case BOUNCE_IN_OUT:
+        {
+            if (t < 0.5f)
+            {
+                t = 1.0f - t * 2.0f;
+
+                if (t < 0.36363636363636365f)
+                {
+                    t = 7.5625f * t * t;
+                }
+                else if (t < 0.7272727272727273f)
+                {
+                    t -= 0.5454545454545454f;
+                    t = 7.5625f * t * t + 0.75f;
+                }
+                else if (t < 0.9090909090909091f)
+                {
+                    t -= 0.8181818181818182f;
+                    t = 7.5625f * t * t + 0.9375f;
+                }
+                else
+                {
+                    t -= 0.9545454545454546f;
+                    t = 7.5625f * t * t + 0.984375f;
+                }
+
+                t = (1.0f - t) * 0.5f;
+            }
+            else
+            {
+                t = t * 2.0f - 1.0f;
+                if (t < 0.36363636363636365f)
+                {
+                    t = 7.5625f * t * t;
+                }
+                else if (t < 0.7272727272727273f)
+                {
+                    t -= 0.5454545454545454f;
+                    t = 7.5625f * t * t + 0.75f;
+                }
+                else if (t < 0.9090909090909091f)
+                {
+                    t -= 0.8181818181818182f;
+                    t = 7.5625f * t * t + 0.9375f;
+                }
+                else
+                {
+                    t -= 0.9545454545454546f;
+                    t = 7.5625f * t * t + 0.984375f;
+                }
+
+                t = 0.5f * t + 0.5f;
+            }
+            break;
+        }
+        case BOUNCE_OUT_IN:
+        {
+            if (t < 0.1818181818f)
+            {
+                t = 15.125f * t * t;
+            }
+            else if (t < 0.3636363636f)
+            {
+                t = 1.5f + (-8.250000001f + 15.125f * t) * t;
+            }
+            else if (t < 0.4545454546f)
+            {
+                t = 3.0f + (-12.375f + 15.125f * t) * t;
+            }
+            else if (t < 0.5f)
+            {
+                t = 3.9375f + (-14.4375f + 15.125f * t) * t;
+            }
+            else if (t <= 0.5454545455f)
+            {
+                t = -3.625000004f + (15.81250001f - 15.125f * t) * t;
+            }
+            else if (t <= 0.6363636365f)
+            {
+                t = -4.75f + (17.875f - 15.125f * t) * t;
+            }
+            else if (t <= 0.8181818180f)
+            {
+                t = -7.374999995f + (21.99999999f - 15.125f * t) * t;
+            }
+            else
+            {
+                t = -14.125f + (30.25f - 15.125f * t) * t;
+            }
+            break;
+        }
+    }
+
+    interpolateLinear(t, from, to, dst);
+}
+
+float Curve::lerp(float t, float from, float to)
+{
+    return lerpInl(t, from, to);
+}
+
+void Curve::setQuaternionOffset(unsigned int offset)
+{
+    assert(offset <= (_componentCount - 4));
+
+    if (!_quaternionOffset)
+        _quaternionOffset = new unsigned int[1];
+    
+    *_quaternionOffset = offset;
+}
+
+void Curve::interpolateBezier(float s, Point* from, Point* to, float* dst) const
+{
+    float s_2 = s * s;
+    float eq0 = 1 - s;
+    float eq0_2 = eq0 * eq0;
+    float eq1 = eq0_2 * eq0;
+    float eq2 = 3 * s * eq0_2;
+    float eq3 = 3 * s_2 * eq0;
+    float eq4 = s_2 * s;
+
+    float* fromValue = from->value;
+    float* toValue = to->value;
+    float* outValue = from->outValue;
+    float* inValue = to->inValue;
+
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+
+        // Handle quaternion component.
+        float interpTime = bezier(eq1, eq2, eq3, eq4, from->time, outValue[i], to->time, inValue[i]);
+        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
+        
+        // Handle remaining components (if any) as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = bezier(eq1, eq2, eq3, eq4, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+    }
+}
+
+void Curve::interpolateBSpline(float s, Point* c0, Point* c1, Point* c2, Point* c3, float* dst) const
+{   
+    float s_2 = s * s;
+    float s_3 = s_2 * s;
+    float eq0 = (-s_3 + 3 * s_2 - 3 * s + 1) / 6.0f;
+    float eq1 = (3 * s_3 - 6 * s_2 + 4) / 6.0f;
+    float eq2 = (-3 * s_3 + 3 * s_2 + 3 * s + 1) / 6.0f;
+    float eq3 = s_3 / 6.0f;
+
+    float* c0Value = c0->value;
+    float* c1Value = c1->value;
+    float* c2Value = c2->value;
+    float* c3Value = c3->value;
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (c1Value[i] == c2Value[i])
+                dst[i] = c1Value[i];
+            else
+                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {
+            if (c1Value[i] == c2Value[i])
+                dst[i] = c1Value[i];
+            else
+                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
+        }
+
+        // Handle quaternion component.
+        float interpTime;
+        if (c0->time == c1->time)
+            interpTime = bspline(eq0, eq1, eq2, eq3, -c0->time, c1->time, c2->time, c3->time);
+        else if (c2->time == c3->time)
+            interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, -c3->time); 
+        else
+            interpTime = bspline(eq0, eq1, eq2, eq3, c0->time, c1->time, c2->time, c3->time);
+        interpolateQuaternion(s, (c1Value + i) , (c2Value + i), (dst + i));
+            
+        // Handle remaining components (if any) as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (c1Value[i] == c2Value[i])
+                dst[i] = c1Value[i];
+            else
+                dst[i] = bspline(eq0, eq1, eq2, eq3, c0Value[i], c1Value[i], c2Value[i], c3Value[i]);
+        }
+    }
+}
+
+void Curve::interpolateHermite(float s, Point* from, Point* to, float* dst) const
+{
+    // Calculate the hermite basis functions.
+    float s_2 = s * s;                   // t^2
+    float s_3 = s_2 * s;                 // t^3
+    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
+    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
+    float h10 = s_3 - 2 * s_2 + s;       // basis function 2
+    float h11 = s_3 - s_2;               // basis function 3
+
+    float* fromValue = from->value;
+    float* toValue = to->value;
+    float* outValue = from->outValue;
+    float* inValue = to->inValue;
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+
+        // Handle quaternion component.
+        float interpTime = hermite(h00, h01, h10, h11, from->time, outValue[i], to->time, inValue[i]);
+        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
+        
+        // Handle remaining components (if any) as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermite(h00, h01, h10, h11, fromValue[i], outValue[i], toValue[i], inValue[i]);
+        }
+    }
+}
+
+void Curve::interpolateHermiteFlat(float s, Point* from, Point* to, float* dst) const
+{
+    // Calculate the hermite basis functions.
+    float s_2 = s * s;                   // t^2
+    float s_3 = s_2 * s;                 // t^3
+    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
+    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
+
+    float* fromValue = from->value;
+    float* toValue = to->value;
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
+        }
+
+        // Handle quaternion component.
+        float interpTime = hermiteFlat(h00, h01, from->time, to->time);
+        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
+        
+        // Handle remaining components (if any) as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = hermiteFlat(h00, h01, fromValue[i], toValue[i]);
+        }
+    }
+}
+
+void Curve::interpolateHermiteSmooth(float s, unsigned int index, Point* from, Point* to, float* dst) const
+{
+    // Calculate the hermite basis functions.
+    float s_2 = s * s;                   // t^2
+    float s_3 = s_2 * s;                 // t^3
+    float h00 = 2 * s_3 - 3 * s_2 + 1;   // basis function 0
+    float h01 = -2 * s_3 + 3 * s_2;      // basis function 1
+    float h10 = s_3 - 2 * s_2 + s;       // basis function 2
+    float h11 = s_3 - s_2;               // basis function 3
+
+    float inValue;
+    float outValue;
+
+    float* fromValue = from->value;
+    float* toValue = to->value;
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+            {
+                dst[i] = fromValue[i];
+            }
+            else
+            {
+                if (index == 0)
+                {
+                    outValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
+                }
+
+                if (index == _pointCount - 2)
+                {
+                    inValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
+                }
+
+                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
+            }
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {   
+            if (fromValue[i] == toValue[i])
+            {
+                dst[i] = fromValue[i];
+            }
+            else
+            {    
+                if (index == 0)
+                {
+                    outValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
+                }
+
+                if (index == _pointCount - 2)
+                {
+                    inValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
+                }
+
+                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
+            }
+        }
+
+        // Handle quaternion component.
+        if (index == 0)
+        {
+            outValue = to->time - from->time;
+        }
+        else
+        {
+            outValue = (to->time - (from - 1)->time) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
+        }
+
+        if (index == _pointCount - 2)
+        {
+            inValue = to->time - from->time;
+        }
+        else
+        {
+            inValue = ((to + 1)->time - from->time) * ((to->time - from->time) / ((to + 1)->time - from->time));
+        }
+
+        float interpTime = hermiteSmooth(h00, h01, h10, h11, from->time, outValue, to->time, inValue);
+        interpolateQuaternion(interpTime, (fromValue + i), (toValue + i), (dst + i));
+        
+        // Handle remaining components (if any) as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+            {
+                dst[i] = fromValue[i];
+            }
+            else
+            {
+                // Interpolate as scalar.
+                if (index == 0)
+                {
+                    outValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    outValue = (toValue[i] - (from - 1)->value[i]) * ((from->time - (from - 1)->time) / (to->time - (from - 1)->time));
+                }
+
+                if (index == _pointCount - 2)
+                {
+                    inValue = toValue[i] - fromValue[i];
+                }
+                else
+                {
+                    inValue = ((to + 1)->value[i] - fromValue[i]) * ((to->time - from->time) / ((to + 1)->time - from->time));
+                }
+
+                dst[i] = hermiteSmooth(h00, h01, h10, h11, fromValue[i], outValue, toValue[i], inValue);
+            }
+        }
+    }
+}
+
+void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
+{
+    float* fromValue = from->value;
+    float* toValue = to->value;
+
+    if (!_quaternionOffset)
+    {
+        for (unsigned int i = 0; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
+        }
+    }
+    else
+    {
+        // Interpolate any values up to the quaternion offset as scalars.
+        unsigned int quaternionOffset = *_quaternionOffset;
+        unsigned int i = 0;
+        for (i = 0; i < quaternionOffset; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
+        }
+
+        // Handle quaternion component.
+        interpolateQuaternion(s, (fromValue + i), (toValue + i), (dst + i));
+        
+        // handle any remaining components as scalars
+        for (i += 4; i < _componentCount; i++)
+        {
+            if (fromValue[i] == toValue[i])
+                dst[i] = fromValue[i];
+            else
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
+        }
+    }
+}
+
+void Curve::interpolateQuaternion(float s, float* from, float* to, float* dst) const
+{
+    // Evaluate.
+    if (s >= 0)
+    {
+        Quaternion::slerp(from[0], from[1], from[2], from[3], to[0], to[1], to[2], to[3], s, dst, dst + 1, dst + 2, dst + 3);
+    }
+    else
+        Quaternion::slerp(to[0], to[1], to[2], to[3], from[0], from[1], from[2], from[3], s, dst, dst + 1, dst + 2, dst + 3);
+
+    //((Quaternion*) dst)->normalize();
+}
+
+int Curve::determineIndex(float time) const
+{
+    unsigned int min = 0;
+    unsigned int max = _pointCount - 1;
+    unsigned int mid = 0;
+
+    // Do a binary search to determine the index.
+    do 
+    {
+        mid = (min + max) >> 1;
+
+        if (time >= _points[mid].time && time <= _points[mid + 1].time)
+            return mid;
+        else if (time < _points[mid].time)
+            max = mid - 1;
+        else
+            min = mid + 1;
+    } while (min <= max);
+    
+    // We should never hit this!
+    return -1;
+}
+
+int Curve::getInterpolationType(const char* curveId)
+{
+    if (strcmp(curveId, "BEZIER") == 0)
+    {
+        return Curve::BEZIER;
+    }
+    else if (strcmp(curveId, "BSPLINE") == 0)
+    {
+        return Curve::BSPLINE;
+    }
+    else if (strcmp(curveId, "FLAT") == 0)
+    {
+        return Curve::FLAT;
+    }
+    else if (strcmp(curveId, "HERMITE") == 0)
+    {
+        return Curve::HERMITE;
+    }
+    else if (strcmp(curveId, "LINEAR") == 0)
+    {
+        return Curve::LINEAR;
+    }
+    else if (strcmp(curveId, "SMOOTH") == 0)
+    {
+        return Curve::SMOOTH;
+    }
+    else if (strcmp(curveId, "STEP") == 0)
+    {
+        return Curve::STEP;
+    }
+    else if (strcmp(curveId, "QUADRATIC_IN") == 0)
+    {
+        return Curve::QUADRATIC_IN;
+    }
+    else if (strcmp(curveId, "QUADRATIC_OUT") == 0)
+    {
+        return Curve::QUADRATIC_OUT;
+    }
+    else if (strcmp(curveId, "QUADRATIC_IN_OUT") == 0)
+    {
+        return Curve::QUADRATIC_IN_OUT;
+    }
+    else if (strcmp(curveId, "QUADRATIC_OUT_IN") == 0)
+    {
+        return Curve::QUADRATIC_OUT_IN;
+    }
+    else if (strcmp(curveId, "CUBIC_IN") == 0)
+    {
+        return Curve::CUBIC_IN;
+    }
+    else if (strcmp(curveId, "CUBIC_OUT") == 0)
+    {
+        return Curve::CUBIC_OUT;
+    }
+    else if (strcmp(curveId, "CUBIC_IN_OUT") == 0)
+    {
+        return Curve::CUBIC_IN_OUT;
+    }
+    else if (strcmp(curveId, "CUBIC_OUT_IN") == 0)
+    {
+        return Curve::CUBIC_OUT_IN;
+    }
+    else if (strcmp(curveId, "QUARTIC_IN") == 0)
+    {
+        return Curve::QUARTIC_IN;
+    }
+    else if (strcmp(curveId, "QUARTIC_OUT") == 0)
+    {
+        return Curve::QUARTIC_OUT;
+    }
+    else if (strcmp(curveId, "QUARTIC_IN_OUT") == 0)
+    {
+        return Curve::QUARTIC_IN_OUT;
+    }
+    else if (strcmp(curveId, "QUARTIC_OUT_IN") == 0)
+    {
+        return Curve::QUARTIC_OUT_IN;
+    }
+    else if (strcmp(curveId, "QUINTIC_IN") == 0)
+    {
+        return Curve::QUINTIC_IN;
+    }
+    else if (strcmp(curveId, "QUINTIC_OUT") == 0)
+    {
+        return Curve::QUINTIC_OUT;
+    }
+    else if (strcmp(curveId, "QUINTIC_IN_OUT") == 0)
+    {
+        return Curve::QUINTIC_IN_OUT;
+    }
+    else if (strcmp(curveId, "QUINTIC_OUT_IN") == 0)
+    {
+        return Curve::QUINTIC_OUT_IN;
+    }
+    else if (strcmp(curveId, "SINE_IN") == 0)
+    {
+        return Curve::SINE_IN;
+    }
+    else if (strcmp(curveId, "SINE_OUT") == 0)
+    {
+        return Curve::SINE_OUT;
+    }
+    else if (strcmp(curveId, "SINE_IN_OUT") == 0)
+    {
+        return Curve::SINE_IN_OUT;
+    }
+    else if (strcmp(curveId, "SINE_OUT_IN") == 0)
+    {
+        return Curve::SINE_OUT_IN;
+    }
+    else if (strcmp(curveId, "EXPONENTIAL_IN") == 0)
+    {
+        return Curve::EXPONENTIAL_IN;
+    }
+    else if (strcmp(curveId, "EXPONENTIAL_OUT") == 0)
+    {
+        return Curve::EXPONENTIAL_OUT;
+    }
+    else if (strcmp(curveId, "EXPONENTIAL_IN_OUT") == 0)
+    {
+        return Curve::EXPONENTIAL_IN_OUT;
+    }
+    else if (strcmp(curveId, "EXPONENTIAL_OUT_IN") == 0)
+    {
+        return Curve::EXPONENTIAL_OUT_IN;
+    }
+    else if (strcmp(curveId, "CIRCULAR_IN") == 0)
+    {
+        return Curve::CIRCULAR_IN;
+    }
+    else if (strcmp(curveId, "CIRCULAR_OUT") == 0)
+    {
+        return Curve::CIRCULAR_OUT;
+    }
+    else if (strcmp(curveId, "CIRCULAR_IN_OUT") == 0)
+    {
+        return Curve::CIRCULAR_IN_OUT;
+    }
+    else if (strcmp(curveId, "CIRCULAR_OUT_IN") == 0)
+    {
+        return Curve::CIRCULAR_OUT_IN;
+    }
+    else if (strcmp(curveId, "ELASTIC_IN") == 0)
+    {
+        return Curve::ELASTIC_IN;
+    }
+    else if (strcmp(curveId, "ELASTIC_OUT") == 0)
+    {
+        return Curve::ELASTIC_OUT;
+    }
+    else if (strcmp(curveId, "ELASTIC_IN_OUT") == 0)
+    {
+        return Curve::ELASTIC_IN_OUT;
+    }
+    else if (strcmp(curveId, "ELASTIC_OUT_IN") == 0)
+    {
+        return Curve::ELASTIC_OUT_IN;
+    }
+    else if (strcmp(curveId, "OVERSHOOT_IN") == 0)
+    {
+        return Curve::OVERSHOOT_IN;
+    }
+    else if (strcmp(curveId, "OVERSHOOT_OUT") == 0)
+    {
+        return Curve::OVERSHOOT_OUT;
+    }
+    else if (strcmp(curveId, "OVERSHOOT_IN_OUT") == 0)
+    {
+        return Curve::OVERSHOOT_IN_OUT;
+    }
+    else if (strcmp(curveId, "OVERSHOOT_OUT_IN") == 0)
+    {
+        return Curve::OVERSHOOT_OUT_IN;
+    }
+    else if (strcmp(curveId, "BOUNCE_IN") == 0)
+    {
+        return Curve::BOUNCE_IN;
+    }
+    else if (strcmp(curveId, "BOUNCE_OUT") == 0)
+    {
+        return Curve::BOUNCE_OUT;
+    }
+    else if (strcmp(curveId, "BOUNCE_IN_OUT") == 0)
+    {
+        return Curve::BOUNCE_IN_OUT;
+    }
+    else if (strcmp(curveId, "BOUNCE_OUT_IN") == 0)
+    {
+        return Curve::BOUNCE_OUT_IN;
+    }
+
+    return -1;
+}
+
+}

+ 483 - 483
tools/encoder/src/Curve.h

@@ -1,484 +1,484 @@
-#ifndef CURVE_H_
-#define CURVE_H_
-
-namespace gameplay
-{
-
-/**
- * Represents an n-dimensional curve.
- */
-class Curve
-{
-    friend class Animation;
-    friend class AnimationClip;
-    friend class AnimationController;
-    friend class MeshSkin;
-
-public:
-
-    /**
-     * Types of interpolation.
-     *
-     * Defines how the points in the curve are connected.
-     *
-     * Note: InterpolationType::BEZIER requires control points and InterpolationType::HERMITE requires tangents.
-     */
-    enum InterpolationType
-    {
-        /**
-         * Bezier Interpolation. 
-         *
-         * Requires that two control points are set for each segment.
-         */
-        BEZIER,
-
-        /**
-         * B-Spline Interpolation. 
-         *
-         * Uses the points as control points, and the curve is guaranteed to only pass through the
-         * first and last point.
-         */
-        BSPLINE,
-
-        /**
-         * Flat Interpolation. 
-         * 
-         * A form of Hermite interpolation that generates flat tangents for you. The tangents have a value equal to 0.
-         */
-        FLAT,
-
-        /**
-         * Hermite Interpolation. 
-         *
-         * Requires that two tangents for each segment.
-         */
-        HERMITE,
-
-        /**
-         * Linear Interpolation.
-         */
-        LINEAR,
-
-        /** 
-         * Smooth Interpolation. 
-         *
-         * A form of Hermite interpolation that generates tangents for each segment based on the points prior to and after the segment.
-         */
-        SMOOTH,
-
-        /**
-         * Discrete Interpolation.
-         */ 
-        STEP,
-
-        /**
-         * Quadratic-In Interpolation.
-         */
-        QUADRATIC_IN, 
-        
-        /**
-         * Quadratic-Out Interpolation.
-         */
-        QUADRATIC_OUT,
-
-        /**
-         * Quadratic-In-Out Interpolation.
-         */
-        QUADRATIC_IN_OUT,
-
-        /**
-         * Quadratic-Out-In Interpolation.
-         */
-        QUADRATIC_OUT_IN,
-
-        /**
-         * Cubic-In Interpolation.
-         */
-        CUBIC_IN,
-        
-        /**
-         * Cubic-Out Interpolation.
-         */
-        CUBIC_OUT,
-        
-        /**
-         * Cubic-In-Out Interpolation.
-         */
-        CUBIC_IN_OUT,
-        
-        /**
-         * Cubic-Out-In Interpolation.
-         */
-        CUBIC_OUT_IN,
-
-        /**
-         * Quartic-In Interpolation.
-         */
-        QUARTIC_IN,
-
-        /**
-         * Quartic-Out Interpolation.
-         */
-        QUARTIC_OUT,
-
-        /**
-         * Quartic-In-Out Interpolation.
-         */
-        QUARTIC_IN_OUT,
-
-        /**
-         * Quartic-Out-In Interpolation.
-         */
-        QUARTIC_OUT_IN,
-
-        /**
-         * Quintic-In Interpolation.
-         */
-        QUINTIC_IN,
-        
-        /**
-         * Quintic-Out Interpolation.
-         */
-        QUINTIC_OUT,
-        
-        /**
-         * Quintic-In-Out Interpolation.
-         */
-        QUINTIC_IN_OUT,
-        
-        /**
-         * Quintic-Out-In Interpolation.
-         */
-        QUINTIC_OUT_IN,
-        
-        /**
-         * Sine-In Interpolation.
-         */
-        SINE_IN,
-        
-        /**
-         * Sine-Out Interpolation.
-         */
-        SINE_OUT,
-        
-        /**
-         * Sine-In-Out Interpolation.
-         */
-        SINE_IN_OUT,
-        
-        /**
-         * Sine-Out-In Interpolation.
-         */
-        SINE_OUT_IN,
-
-        /**
-         * Exponential-In Interpolation.
-         */
-        EXPONENTIAL_IN,
-
-        /**
-         * Exponential-Out Interpolation.
-         */
-        EXPONENTIAL_OUT,
-
-        /**
-         * Exponential-In-Out Interpolation.
-         */
-        EXPONENTIAL_IN_OUT,
-
-        /**
-         * Exponential-Out-In Interpolation.
-         */
-        EXPONENTIAL_OUT_IN,
-
-        /**
-         * Circular-In Interpolation.
-         */
-        CIRCULAR_IN,
-
-        /**
-         * Circular-Out Interpolation.
-         */
-        CIRCULAR_OUT,
-
-        /**
-         * Circular-In-Out Interpolation.
-         */
-        CIRCULAR_IN_OUT,
-
-        /**
-         * Circular-Out-In Interpolation.
-         */
-        CIRCULAR_OUT_IN,
-
-        /**
-         * Elastic-In Interpolation.
-         */
-        ELASTIC_IN,
-
-        /**
-         * Elastic-Out Interpolation.
-         */
-        ELASTIC_OUT,
-
-        /**
-         * Elastic-In-Out Interpolation.
-         */
-        ELASTIC_IN_OUT,
-
-        /**
-         * Elastic-Out-In Interpolation.
-         */
-        ELASTIC_OUT_IN,
-
-        /**
-         * Overshoot-In Interpolation.
-         */
-        OVERSHOOT_IN,
-
-        /**
-         * Overshoot-Out Interpolation.
-         */
-        OVERSHOOT_OUT,
-
-        /**
-         * Overshoot-In-Out Interpolation.
-         */
-        OVERSHOOT_IN_OUT,
-
-        /**
-         * Overshoot-Out-In Interpolation.
-         */
-        OVERSHOOT_OUT_IN,
-
-        /**
-         * Bounce-In Interpolation.
-         */
-        BOUNCE_IN,
-
-        /**
-         * Bounce-Out Interpolation.
-         */
-        BOUNCE_OUT,
-
-        /**
-         * Bounce-In-Out Interpolation.
-         */
-        BOUNCE_IN_OUT,
-
-        /**
-         * Bounce-Out-In Interpolation.
-         */
-        BOUNCE_OUT_IN
-    };
-
-
-    /**
-     * Constructs a new curve and the specified parameters.
-     *
-     * @param pointCount The number of points in the curve.
-     * @param componentCount The number of float component values per key value.
-     */
-    Curve(unsigned int pointCount, unsigned int componentCount);
-
-    /**
-     * Destructor.
-     */
-    ~Curve();
-
-    /**
-     * Gets the number of points in the curve.
-     *
-     * @return The number of points in the curve.
-     */
-    unsigned int getPointCount() const;
-
-    /**
-     * Gets the number of float component values per points.
-     *
-     * @return The number of float component values per point.
-     */
-    unsigned int getComponentCount() const;
-
-    /**
-     * Returns the start time for the curve.
-     *
-     * @return The curve's start time.
-     */
-    float getStartTime() const;
-
-    /**
-     * Returns the end time for the curve.
-     *
-     * @return The curve's end time.
-     */
-    float getEndTime() const;
-
-    /**
-     * Sets the given point values on the curve the curve.
-     *
-     * @param index The index of the point.
-     * @param time The time for the key.
-     * @param value The point to add.
-     * @param type The curve interpolation type.
-     */
-    void setPoint(unsigned int index, float time, float* value, InterpolationType type);
-
-    /**
-     * Sets the given point on the curve for the specified index and the specified parameters.
-     *
-     * @param index The index of the point.
-     * @param time The time of the point within the curve.
-     * @param value The value of the point to copy the data from.
-     * @param type The curve interpolation type.
-     * @param inValue The tangent approaching the point.
-     * @param outValue The tangent leaving the point.
-     */
-    void setPoint(unsigned int index, float time, float* value, InterpolationType type, float* inValue, float* outValue);
-
-    /**
-     * Sets the tangents for a point on the curve specified by the index.
-     *
-     * @param index The index of the point.
-     * @param type The curve interpolation type.
-     * @param inValue The tangent approaching the point.
-     * @param outValue The tangent leaving the point.
-     */
-    void setTangent(unsigned int index, InterpolationType type, float* inValue, float* outValue);
-    
-    /**
-     * Evaluates the curve at the given position value (between 0.0 and 1.0 inclusive).
-     *
-     * @param time The position to evaluate the curve at.
-     * @param dst The evaluated value of the curve at the given time.
-     */
-    void evaluate(float time, float* dst) const;
-
-    /**
-     * Linear interpolation function.
-     */
-    static float lerp(float t, float from, float to);
-
-private:
-
-    /**
-     * Defines a single point within a curve.
-     */
-    class Point
-    {
-    public:
-
-        /** The time of the point within the curve. */
-        float time;
-        /** The value of the point. */
-        float* value;
-        /** The value of the tangent when approaching this point (from the previous point in the curve). */
-        float* inValue;
-        /** The value of the tangent when leaving this point (towards the next point in the curve). */
-        float* outValue;
-        /** The type of interpolation to use between this point and the next point. */
-        InterpolationType type;
-
-        /**
-         * Constructor.
-         */
-        Point();
-
-        /**
-         * Destructor.
-         */
-        ~Point();
-    };
-
-    /**
-     * Constructor.
-     */
-    Curve();
-
-    /**
-     * Constructor.
-     */
-    Curve(const Curve& copy);
-
-    /**
-     * Bezier interpolation function.
-     */
-    void interpolateBezier(float s, Point* from, Point* to, float* dst) const;
-
-    /**
-     * Bspline interpolation function.
-     */
-    void interpolateBSpline(float s, Point* c0, Point* c1, Point* c2, Point* c3, float* dst) const;
-
-    /**
-     * Hermite interpolation function.
-     */
-    void interpolateHermite(float s, Point* from, Point* to, float* dst) const;
-
-    /**
-     * Hermite interpolation function.
-     */
-    void interpolateHermiteFlat(float s, Point* from, Point* to, float* dst) const;
-
-    /**
-     * Hermite interpolation function.
-     */
-    void interpolateHermiteSmooth(float s, unsigned int index, Point* from, Point* to, float* dst) const;
-
-    /** 
-     * Linear interpolation function.
-     */ 
-    void interpolateLinear(float s, Point* from, Point* to, float* dst) const;
-
-    /**
-     * Quaternion interpolation function.
-     */
-    void interpolateQuaternion(float s, float* from, float* to, float* dst) const;
-    
-    /**
-     * Determines the current keyframe to interpolate from based on the specified time.
-     */ 
-    int determineIndex(float time) const;
-
-    /**
-     * Sets the offset for the beginning of a Quaternion piece of data within the curve's value span at the specified
-     * index. The next four components of data starting at the given index will be interpolated as a Quaternion.
-     * This function will assert an error if the given index is greater than the component size subtracted by the four components required
-     * to store a quaternion.
-     * 
-     * @param index The index of the Quaternion rotation data.
-     */
-    void setQuaternionOffset(unsigned int index);
-
-    /**
-     * Gets the InterpolationType value for the given string ID
-     *
-     * @param interpolationId The string representation of the InterpolationType
-     * @return the InterpolationType value; -1 if the string does not represent an InterpolationType.
-     */
-    static int getInterpolationType(const char* interpolationId);
-
-    unsigned int _pointCount;           // Number of points on the curve.
-    unsigned int _componentCount;       // Number of components on the curve.
-    unsigned int _componentSize;        // The component size (in bytes).
-    unsigned int* _quaternionOffset;    // Offset for the rotation component.
-    Point* _points;                     // The points on the curve.
-};
-
-inline static float bezier(float eq0, float eq1, float eq2, float eq3, float from, float out, float to, float in);
-
-inline static float bspline(float eq0, float eq1, float eq2, float eq3, float c0, float c1, float c2, float c3);
-
-inline static float hermite(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
-
-inline static float hermiteFlat(float h00, float h01, float from, float to);
-
-inline static float hermiteSmooth(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
-
-inline static float lerpInl(float s, float from, float to);
-
-}
-
-#include "Curve.inl"
-
+#ifndef CURVE_H_
+#define CURVE_H_
+
+namespace gameplay
+{
+
+/**
+ * Represents an n-dimensional curve.
+ */
+class Curve
+{
+    friend class Animation;
+    friend class AnimationClip;
+    friend class AnimationController;
+    friend class MeshSkin;
+
+public:
+
+    /**
+     * Types of interpolation.
+     *
+     * Defines how the points in the curve are connected.
+     *
+     * Note: InterpolationType::BEZIER requires control points and InterpolationType::HERMITE requires tangents.
+     */
+    enum InterpolationType
+    {
+        /**
+         * Bezier Interpolation. 
+         *
+         * Requires that two control points are set for each segment.
+         */
+        BEZIER,
+
+        /**
+         * B-Spline Interpolation. 
+         *
+         * Uses the points as control points, and the curve is guaranteed to only pass through the
+         * first and last point.
+         */
+        BSPLINE,
+
+        /**
+         * Flat Interpolation. 
+         * 
+         * A form of Hermite interpolation that generates flat tangents for you. The tangents have a value equal to 0.
+         */
+        FLAT,
+
+        /**
+         * Hermite Interpolation. 
+         *
+         * Requires that two tangents for each segment.
+         */
+        HERMITE,
+
+        /**
+         * Linear Interpolation.
+         */
+        LINEAR,
+
+        /** 
+         * Smooth Interpolation. 
+         *
+         * A form of Hermite interpolation that generates tangents for each segment based on the points prior to and after the segment.
+         */
+        SMOOTH,
+
+        /**
+         * Discrete Interpolation.
+         */ 
+        STEP,
+
+        /**
+         * Quadratic-In Interpolation.
+         */
+        QUADRATIC_IN, 
+        
+        /**
+         * Quadratic-Out Interpolation.
+         */
+        QUADRATIC_OUT,
+
+        /**
+         * Quadratic-In-Out Interpolation.
+         */
+        QUADRATIC_IN_OUT,
+
+        /**
+         * Quadratic-Out-In Interpolation.
+         */
+        QUADRATIC_OUT_IN,
+
+        /**
+         * Cubic-In Interpolation.
+         */
+        CUBIC_IN,
+        
+        /**
+         * Cubic-Out Interpolation.
+         */
+        CUBIC_OUT,
+        
+        /**
+         * Cubic-In-Out Interpolation.
+         */
+        CUBIC_IN_OUT,
+        
+        /**
+         * Cubic-Out-In Interpolation.
+         */
+        CUBIC_OUT_IN,
+
+        /**
+         * Quartic-In Interpolation.
+         */
+        QUARTIC_IN,
+
+        /**
+         * Quartic-Out Interpolation.
+         */
+        QUARTIC_OUT,
+
+        /**
+         * Quartic-In-Out Interpolation.
+         */
+        QUARTIC_IN_OUT,
+
+        /**
+         * Quartic-Out-In Interpolation.
+         */
+        QUARTIC_OUT_IN,
+
+        /**
+         * Quintic-In Interpolation.
+         */
+        QUINTIC_IN,
+        
+        /**
+         * Quintic-Out Interpolation.
+         */
+        QUINTIC_OUT,
+        
+        /**
+         * Quintic-In-Out Interpolation.
+         */
+        QUINTIC_IN_OUT,
+        
+        /**
+         * Quintic-Out-In Interpolation.
+         */
+        QUINTIC_OUT_IN,
+        
+        /**
+         * Sine-In Interpolation.
+         */
+        SINE_IN,
+        
+        /**
+         * Sine-Out Interpolation.
+         */
+        SINE_OUT,
+        
+        /**
+         * Sine-In-Out Interpolation.
+         */
+        SINE_IN_OUT,
+        
+        /**
+         * Sine-Out-In Interpolation.
+         */
+        SINE_OUT_IN,
+
+        /**
+         * Exponential-In Interpolation.
+         */
+        EXPONENTIAL_IN,
+
+        /**
+         * Exponential-Out Interpolation.
+         */
+        EXPONENTIAL_OUT,
+
+        /**
+         * Exponential-In-Out Interpolation.
+         */
+        EXPONENTIAL_IN_OUT,
+
+        /**
+         * Exponential-Out-In Interpolation.
+         */
+        EXPONENTIAL_OUT_IN,
+
+        /**
+         * Circular-In Interpolation.
+         */
+        CIRCULAR_IN,
+
+        /**
+         * Circular-Out Interpolation.
+         */
+        CIRCULAR_OUT,
+
+        /**
+         * Circular-In-Out Interpolation.
+         */
+        CIRCULAR_IN_OUT,
+
+        /**
+         * Circular-Out-In Interpolation.
+         */
+        CIRCULAR_OUT_IN,
+
+        /**
+         * Elastic-In Interpolation.
+         */
+        ELASTIC_IN,
+
+        /**
+         * Elastic-Out Interpolation.
+         */
+        ELASTIC_OUT,
+
+        /**
+         * Elastic-In-Out Interpolation.
+         */
+        ELASTIC_IN_OUT,
+
+        /**
+         * Elastic-Out-In Interpolation.
+         */
+        ELASTIC_OUT_IN,
+
+        /**
+         * Overshoot-In Interpolation.
+         */
+        OVERSHOOT_IN,
+
+        /**
+         * Overshoot-Out Interpolation.
+         */
+        OVERSHOOT_OUT,
+
+        /**
+         * Overshoot-In-Out Interpolation.
+         */
+        OVERSHOOT_IN_OUT,
+
+        /**
+         * Overshoot-Out-In Interpolation.
+         */
+        OVERSHOOT_OUT_IN,
+
+        /**
+         * Bounce-In Interpolation.
+         */
+        BOUNCE_IN,
+
+        /**
+         * Bounce-Out Interpolation.
+         */
+        BOUNCE_OUT,
+
+        /**
+         * Bounce-In-Out Interpolation.
+         */
+        BOUNCE_IN_OUT,
+
+        /**
+         * Bounce-Out-In Interpolation.
+         */
+        BOUNCE_OUT_IN
+    };
+
+
+    /**
+     * Constructs a new curve and the specified parameters.
+     *
+     * @param pointCount The number of points in the curve.
+     * @param componentCount The number of float component values per key value.
+     */
+    Curve(unsigned int pointCount, unsigned int componentCount);
+
+    /**
+     * Destructor.
+     */
+    ~Curve();
+
+    /**
+     * Gets the number of points in the curve.
+     *
+     * @return The number of points in the curve.
+     */
+    unsigned int getPointCount() const;
+
+    /**
+     * Gets the number of float component values per points.
+     *
+     * @return The number of float component values per point.
+     */
+    unsigned int getComponentCount() const;
+
+    /**
+     * Returns the start time for the curve.
+     *
+     * @return The curve's start time.
+     */
+    float getStartTime() const;
+
+    /**
+     * Returns the end time for the curve.
+     *
+     * @return The curve's end time.
+     */
+    float getEndTime() const;
+
+    /**
+     * Sets the given point values on the curve the curve.
+     *
+     * @param index The index of the point.
+     * @param time The time for the key.
+     * @param value The point to add.
+     * @param type The curve interpolation type.
+     */
+    void setPoint(unsigned int index, float time, float* value, InterpolationType type);
+
+    /**
+     * Sets the given point on the curve for the specified index and the specified parameters.
+     *
+     * @param index The index of the point.
+     * @param time The time of the point within the curve.
+     * @param value The value of the point to copy the data from.
+     * @param type The curve interpolation type.
+     * @param inValue The tangent approaching the point.
+     * @param outValue The tangent leaving the point.
+     */
+    void setPoint(unsigned int index, float time, float* value, InterpolationType type, float* inValue, float* outValue);
+
+    /**
+     * Sets the tangents for a point on the curve specified by the index.
+     *
+     * @param index The index of the point.
+     * @param type The curve interpolation type.
+     * @param inValue The tangent approaching the point.
+     * @param outValue The tangent leaving the point.
+     */
+    void setTangent(unsigned int index, InterpolationType type, float* inValue, float* outValue);
+    
+    /**
+     * Evaluates the curve at the given position value (between 0.0 and 1.0 inclusive).
+     *
+     * @param time The position to evaluate the curve at.
+     * @param dst The evaluated value of the curve at the given time.
+     */
+    void evaluate(float time, float* dst) const;
+
+    /**
+     * Linear interpolation function.
+     */
+    static float lerp(float t, float from, float to);
+
+private:
+
+    /**
+     * Defines a single point within a curve.
+     */
+    class Point
+    {
+    public:
+
+        /** The time of the point within the curve. */
+        float time;
+        /** The value of the point. */
+        float* value;
+        /** The value of the tangent when approaching this point (from the previous point in the curve). */
+        float* inValue;
+        /** The value of the tangent when leaving this point (towards the next point in the curve). */
+        float* outValue;
+        /** The type of interpolation to use between this point and the next point. */
+        InterpolationType type;
+
+        /**
+         * Constructor.
+         */
+        Point();
+
+        /**
+         * Destructor.
+         */
+        ~Point();
+    };
+
+    /**
+     * Constructor.
+     */
+    Curve();
+
+    /**
+     * Constructor.
+     */
+    Curve(const Curve& copy);
+
+    /**
+     * Bezier interpolation function.
+     */
+    void interpolateBezier(float s, Point* from, Point* to, float* dst) const;
+
+    /**
+     * Bspline interpolation function.
+     */
+    void interpolateBSpline(float s, Point* c0, Point* c1, Point* c2, Point* c3, float* dst) const;
+
+    /**
+     * Hermite interpolation function.
+     */
+    void interpolateHermite(float s, Point* from, Point* to, float* dst) const;
+
+    /**
+     * Hermite interpolation function.
+     */
+    void interpolateHermiteFlat(float s, Point* from, Point* to, float* dst) const;
+
+    /**
+     * Hermite interpolation function.
+     */
+    void interpolateHermiteSmooth(float s, unsigned int index, Point* from, Point* to, float* dst) const;
+
+    /** 
+     * Linear interpolation function.
+     */ 
+    void interpolateLinear(float s, Point* from, Point* to, float* dst) const;
+
+    /**
+     * Quaternion interpolation function.
+     */
+    void interpolateQuaternion(float s, float* from, float* to, float* dst) const;
+    
+    /**
+     * Determines the current keyframe to interpolate from based on the specified time.
+     */ 
+    int determineIndex(float time) const;
+
+    /**
+     * Sets the offset for the beginning of a Quaternion piece of data within the curve's value span at the specified
+     * index. The next four components of data starting at the given index will be interpolated as a Quaternion.
+     * This function will assert an error if the given index is greater than the component size subtracted by the four components required
+     * to store a quaternion.
+     * 
+     * @param index The index of the Quaternion rotation data.
+     */
+    void setQuaternionOffset(unsigned int index);
+
+    /**
+     * Gets the InterpolationType value for the given string ID
+     *
+     * @param interpolationId The string representation of the InterpolationType
+     * @return the InterpolationType value; -1 if the string does not represent an InterpolationType.
+     */
+    static int getInterpolationType(const char* interpolationId);
+
+    unsigned int _pointCount;           // Number of points on the curve.
+    unsigned int _componentCount;       // Number of components on the curve.
+    unsigned int _componentSize;        // The component size (in bytes).
+    unsigned int* _quaternionOffset;    // Offset for the rotation component.
+    Point* _points;                     // The points on the curve.
+};
+
+inline static float bezier(float eq0, float eq1, float eq2, float eq3, float from, float out, float to, float in);
+
+inline static float bspline(float eq0, float eq1, float eq2, float eq3, float c0, float c1, float c2, float c3);
+
+inline static float hermite(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
+
+inline static float hermiteFlat(float h00, float h01, float from, float to);
+
+inline static float hermiteSmooth(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
+
+inline static float lerpInl(float s, float from, float to);
+
+}
+
+#include "Curve.inl"
+
 #endif

+ 40 - 40
tools/encoder/src/Effect.cpp

@@ -1,40 +1,40 @@
-#include "Base.h"
-#include "Effect.h"
-
-namespace gameplay
-{
-
-Effect::Effect(void)
-{
-}
-
-Effect::~Effect(void)
-{
-}
-
-unsigned int Effect::getTypeId(void) const
-{
-    return EFFECT_ID;
-}
-
-const char* Effect::getElementName(void) const
-{
-    return "Effect";
-}
-
-void Effect::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    write(_vertexShader, file);
-    write(_fragmentShader, file);
-}
-
-void Effect::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    fprintfElement(file, "vertexShader", _vertexShader);
-    fprintfElement(file, "fragmentShader", _fragmentShader);
-    fprintElementEnd(file);
-}
-
-}
+#include "Base.h"
+#include "Effect.h"
+
+namespace gameplay
+{
+
+Effect::Effect(void)
+{
+}
+
+Effect::~Effect(void)
+{
+}
+
+unsigned int Effect::getTypeId(void) const
+{
+    return EFFECT_ID;
+}
+
+const char* Effect::getElementName(void) const
+{
+    return "Effect";
+}
+
+void Effect::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    write(_vertexShader, file);
+    write(_fragmentShader, file);
+}
+
+void Effect::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    fprintfElement(file, "vertexShader", _vertexShader);
+    fprintfElement(file, "fragmentShader", _fragmentShader);
+    fprintElementEnd(file);
+}
+
+}

+ 39 - 39
tools/encoder/src/Effect.h

@@ -1,39 +1,39 @@
-#ifndef EFFECT_H_
-#define EFFECT_H_
-
-#include "Object.h"
-
-namespace gameplay
-{
-
-class Effect : public Object
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    Effect(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~Effect(void);
-
-    virtual unsigned int getTypeId(void) const;
-
-    virtual const char* getElementName(void) const;
-
-    virtual void writeBinary(FILE* file);
-
-    virtual void writeText(FILE* file);
-
-private:
-    
-    std::string _vertexShader;
-    std::string _fragmentShader;
-};
-
-}
-
-#endif
+#ifndef EFFECT_H_
+#define EFFECT_H_
+
+#include "Object.h"
+
+namespace gameplay
+{
+
+class Effect : public Object
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Effect(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~Effect(void);
+
+    virtual unsigned int getTypeId(void) const;
+
+    virtual const char* getElementName(void) const;
+
+    virtual void writeBinary(FILE* file);
+
+    virtual void writeText(FILE* file);
+
+private:
+    
+    std::string _vertexShader;
+    std::string _fragmentShader;
+};
+
+}
+
+#endif

+ 225 - 225
tools/encoder/src/EncoderArguments.h

@@ -1,225 +1,225 @@
-#ifndef ENCODERARGUMENTS_H_
-#define ENCODERARGUMENTS_H_
-
-#include <set>
-#include "Vector3.h"
-#include "Font.h"
-
-namespace gameplay
-{
-
-/**
- * EncoderArguments handles parsing the command line arguments for the GamePlay Encoder.
- */
-class EncoderArguments
-{
-public:
-
-    enum FileFormat
-    {
-        FILEFORMAT_UNKNOWN,
-        FILEFORMAT_DAE,
-        FILEFORMAT_FBX,
-        FILEFORMAT_TTF,
-        FILEFORMAT_GPB,
-        FILEFORMAT_PNG,
-        FILEFORMAT_RAW
-    };
-
-    struct HeightmapOption
-    {
-        std::vector<std::string> nodeIds;
-        std::string filename;
-        bool isHighPrecision;
-        int width;
-        int height;
-    };
-
-    struct NormalMapOption
-    {
-        std::string inputFile;
-        std::string outputFile;
-        Vector3 worldSize;
-    };
-
-    enum AnimationGroupOption
-    {
-        ANIMATIONGROUP_PROMPT,
-        ANIMATIONGROUP_AUTO,
-        ANIMATIONGROUP_OFF
-    };
-    
-    /**
-     * Constructor.
-     */
-    EncoderArguments(size_t argc, const char** argv);
-
-    /**
-     * Destructor.
-     */
-    ~EncoderArguments(void);
-
-    /**
-     * Gets the EncoderArguments instance.
-     */
-    static EncoderArguments* getInstance();
-
-    /**
-     * Gets the file format from the file path based on the extension.
-     */
-    FileFormat getFileFormat() const;
-
-    /**
-     * Returns the file path.
-     */
-    const std::string& getFilePath() const;
-
-    /**
-     * Returns the char pointer to the file path string.
-     */
-    const char* getFilePathPointer() const;
-
-    /**
-     * Returns the output path/folder.
-     * Example: "C:/dir"
-     */
-    std::string getOutputDirPath() const;
-
-    /**
-     * Returns the output file path.
-     * Example: "C:/dir/scene.gpb"
-     */
-    std::string getOutputFilePath() const;
-
-    /**
-     * Returns the output file extension.
-     */
-    std::string getOutputFileExtension() const;
-
-    const std::vector<std::string>& getGroupAnimationNodeId() const;
-    const std::vector<std::string>& getGroupAnimationAnimationId() const;
-
-    bool containsGroupNodeId(const std::string& nodeId) const;
-    const std::string getAnimationId(const std::string& nodeId) const;
-
-    AnimationGroupOption getAnimationGrouping() const;
-
-    const std::vector<HeightmapOption>& getHeightmapOptions() const;
-
-    /**
-     * Returns the number of node IDs that were marked as needing to compute tangents and binormals.
-     */
-    unsigned int tangentBinormalIdCount() const;
-    
-    /**
-     * Returns true if the given node ID was marked as needing to generate tangents and binormals.
-     */
-    bool isGenerateTangentBinormalId(const std::string& id) const;
-
-    /**
-     * Returns true if normal map generation is turned on.
-     */
-    bool normalMapGeneration() const;
-    
-    /**
-     * Returns the supplied intput heightmap resolution.
-     *
-     * This option is only applicable for normal map generation.
-     */
-    void getHeightmapResolution(int* x, int* y) const;
-
-    /**
-     * Returns world size option.
-     *
-     * This option is only applicable for normal map generation.
-     */
-    const Vector3& getHeightmapWorldSize() const;
-    
-    /**
-     * Returns true if an error occurred while parsing the command line arguments.
-     */
-    bool parseErrorOccured() const;
-
-    /**
-     * Tests if a file exists on the file system.
-     * 
-     * @return True if the file exists; false otherwise.
-     */
-    bool fileExists() const;
-
-    /**
-     * Prints the usage information.
-     */
-    void printUsage() const;
-
-    std::vector<unsigned int> getFontSizes() const;
-
-    bool fontPreviewEnabled() const;
-
-    Font::FontFormat getFontFormat() const;
-
-    bool textOutputEnabled() const;
-
-    bool optimizeAnimationsEnabled() const;
-
-    bool outputMaterialEnabled() const;
-
-    const char* getNodeId() const;
-
-    static std::string getRealPath(const std::string& filepath);
-
-private:
-
-    /**
-     * Reads the command line option from the list of options starting at the given index.
-     * 
-     * @param options The list of command line options.
-     * @param index Pointer to the index within the options list. The index will be changed
-     *              if an option takes multiple arguments.
-     */
-    void readOption(const std::vector<std::string>& options, size_t *index);
-
-    void setInputfilePath(const std::string& inputPath);
-
-    /**
-     * Sets the output file path that the encoder will write to.
-     */
-    void setOutputfilePath(const std::string& outputPath);
-    
-
-    /**
-     * Replaces all instance of oldChar with newChar in str.
-     */
-    static void replace_char(char* str, char oldChar, char newChar);
-
-private:
-    
-    std::string _filePath;
-    std::string _fileOutputPath;
-    std::string _nodeId;
-
-    bool _normalMap;
-    Vector3 _heightmapWorldSize;
-    int _heightmapResolution[2];
-
-    bool _parseError;
-    std::vector<unsigned int> _fontSizes;
-    bool _fontPreview;
-    Font::FontFormat _fontFormat;
-    bool _textOutput;
-    bool _optimizeAnimations;
-    AnimationGroupOption _animationGrouping;
-    bool _outputMaterial;
-
-    std::vector<std::string> _groupAnimationNodeId;
-    std::vector<std::string> _groupAnimationAnimationId;
-    std::vector<HeightmapOption> _heightmaps;
-    std::set<std::string> _tangentBinormalId;
-
-};
-
-void unittestsEncoderArguments();
-
-}
-
-#endif
+#ifndef ENCODERARGUMENTS_H_
+#define ENCODERARGUMENTS_H_
+
+#include <set>
+#include "Vector3.h"
+#include "Font.h"
+
+namespace gameplay
+{
+
+/**
+ * EncoderArguments handles parsing the command line arguments for the GamePlay Encoder.
+ */
+class EncoderArguments
+{
+public:
+
+    enum FileFormat
+    {
+        FILEFORMAT_UNKNOWN,
+        FILEFORMAT_DAE,
+        FILEFORMAT_FBX,
+        FILEFORMAT_TTF,
+        FILEFORMAT_GPB,
+        FILEFORMAT_PNG,
+        FILEFORMAT_RAW
+    };
+
+    struct HeightmapOption
+    {
+        std::vector<std::string> nodeIds;
+        std::string filename;
+        bool isHighPrecision;
+        int width;
+        int height;
+    };
+
+    struct NormalMapOption
+    {
+        std::string inputFile;
+        std::string outputFile;
+        Vector3 worldSize;
+    };
+
+    enum AnimationGroupOption
+    {
+        ANIMATIONGROUP_PROMPT,
+        ANIMATIONGROUP_AUTO,
+        ANIMATIONGROUP_OFF
+    };
+    
+    /**
+     * Constructor.
+     */
+    EncoderArguments(size_t argc, const char** argv);
+
+    /**
+     * Destructor.
+     */
+    ~EncoderArguments(void);
+
+    /**
+     * Gets the EncoderArguments instance.
+     */
+    static EncoderArguments* getInstance();
+
+    /**
+     * Gets the file format from the file path based on the extension.
+     */
+    FileFormat getFileFormat() const;
+
+    /**
+     * Returns the file path.
+     */
+    const std::string& getFilePath() const;
+
+    /**
+     * Returns the char pointer to the file path string.
+     */
+    const char* getFilePathPointer() const;
+
+    /**
+     * Returns the output path/folder.
+     * Example: "C:/dir"
+     */
+    std::string getOutputDirPath() const;
+
+    /**
+     * Returns the output file path.
+     * Example: "C:/dir/scene.gpb"
+     */
+    std::string getOutputFilePath() const;
+
+    /**
+     * Returns the output file extension.
+     */
+    std::string getOutputFileExtension() const;
+
+    const std::vector<std::string>& getGroupAnimationNodeId() const;
+    const std::vector<std::string>& getGroupAnimationAnimationId() const;
+
+    bool containsGroupNodeId(const std::string& nodeId) const;
+    const std::string getAnimationId(const std::string& nodeId) const;
+
+    AnimationGroupOption getAnimationGrouping() const;
+
+    const std::vector<HeightmapOption>& getHeightmapOptions() const;
+
+    /**
+     * Returns the number of node IDs that were marked as needing to compute tangents and binormals.
+     */
+    unsigned int tangentBinormalIdCount() const;
+    
+    /**
+     * Returns true if the given node ID was marked as needing to generate tangents and binormals.
+     */
+    bool isGenerateTangentBinormalId(const std::string& id) const;
+
+    /**
+     * Returns true if normal map generation is turned on.
+     */
+    bool normalMapGeneration() const;
+    
+    /**
+     * Returns the supplied intput heightmap resolution.
+     *
+     * This option is only applicable for normal map generation.
+     */
+    void getHeightmapResolution(int* x, int* y) const;
+
+    /**
+     * Returns world size option.
+     *
+     * This option is only applicable for normal map generation.
+     */
+    const Vector3& getHeightmapWorldSize() const;
+    
+    /**
+     * Returns true if an error occurred while parsing the command line arguments.
+     */
+    bool parseErrorOccured() const;
+
+    /**
+     * Tests if a file exists on the file system.
+     * 
+     * @return True if the file exists; false otherwise.
+     */
+    bool fileExists() const;
+
+    /**
+     * Prints the usage information.
+     */
+    void printUsage() const;
+
+    std::vector<unsigned int> getFontSizes() const;
+
+    bool fontPreviewEnabled() const;
+
+    Font::FontFormat getFontFormat() const;
+
+    bool textOutputEnabled() const;
+
+    bool optimizeAnimationsEnabled() const;
+
+    bool outputMaterialEnabled() const;
+
+    const char* getNodeId() const;
+
+    static std::string getRealPath(const std::string& filepath);
+
+private:
+
+    /**
+     * Reads the command line option from the list of options starting at the given index.
+     * 
+     * @param options The list of command line options.
+     * @param index Pointer to the index within the options list. The index will be changed
+     *              if an option takes multiple arguments.
+     */
+    void readOption(const std::vector<std::string>& options, size_t *index);
+
+    void setInputfilePath(const std::string& inputPath);
+
+    /**
+     * Sets the output file path that the encoder will write to.
+     */
+    void setOutputfilePath(const std::string& outputPath);
+    
+
+    /**
+     * Replaces all instance of oldChar with newChar in str.
+     */
+    static void replace_char(char* str, char oldChar, char newChar);
+
+private:
+    
+    std::string _filePath;
+    std::string _fileOutputPath;
+    std::string _nodeId;
+
+    bool _normalMap;
+    Vector3 _heightmapWorldSize;
+    int _heightmapResolution[2];
+
+    bool _parseError;
+    std::vector<unsigned int> _fontSizes;
+    bool _fontPreview;
+    Font::FontFormat _fontFormat;
+    bool _textOutput;
+    bool _optimizeAnimations;
+    AnimationGroupOption _animationGrouping;
+    bool _outputMaterial;
+
+    std::vector<std::string> _groupAnimationNodeId;
+    std::vector<std::string> _groupAnimationAnimationId;
+    std::vector<HeightmapOption> _heightmaps;
+    std::set<std::string> _tangentBinormalId;
+
+};
+
+void unittestsEncoderArguments();
+
+}
+
+#endif

+ 295 - 295
tools/encoder/src/FBXSceneEncoder.h

@@ -1,295 +1,295 @@
-#ifndef FBXSCENEEENCODER_H_
-#define FBXSCENEEENCODER_H_
-
-#define FBXSDK_NEW_API
-
-#include <iostream>
-#include <list>
-#include <vector>
-#include <ctime>
-#ifdef WIN32
-    #pragma warning( disable : 4100 )
-    #pragma warning( disable : 4512 )
-#endif
-#include <fbxsdk.h>
-
-#include "Base.h"
-#include "StringUtil.h"
-#include "Object.h"
-#include "Node.h"
-#include "Camera.h"
-#include "Light.h"
-#include "Mesh.h"
-#include "MeshPart.h"
-#include "MeshSkin.h"
-#include "Model.h"
-#include "Scene.h"
-#include "Animation.h"
-#include "AnimationChannel.h"
-#include "Vertex.h"
-#include "Matrix.h"
-#include "Transform.h"
-#include "GPBFile.h"
-#include "EncoderArguments.h"
-
-using namespace gameplay;
-
-/**
- * Class for binary encoding an FBX file.
- */
-class FBXSceneEncoder
-{
-public:
-
-    static const unsigned int SCENE_SKIN_VERTEXINFLUENCES_MAX = 4;
-    
-    /**
-     * Constructor.
-     */
-    FBXSceneEncoder();
-
-    /**
-     * Destructor.
-     */
-    ~FBXSceneEncoder();
-    
-    /**
-     * Writes out encoded FBX file.
-     */
-    void write(const std::string& filepath, const EncoderArguments& arguments);
-
-    /**
-     * Writes a material file.
-     * 
-     * @param filepath 
-     * 
-     * @return True if successful; false otherwise.
-     */
-    bool writeMaterial(const std::string& filepath);
-
-private:
-
-    /**
-     * Loads the scene.
-     * 
-     * @param fbxScene The FBX scene to load.
-     */
-    void loadScene(FbxScene* fbxScene);
-
-    /**
-     * Loads all of the animatiosn from the given FBX scene.
-     * 
-     * @param fbxScene The scene to load animations from.
-     * @param arguments The command line arguments passed to the encoder.
-     */
-    void loadAnimations(FbxScene* fbxScene, const EncoderArguments& arguments);
-
-    /**
-     * Loads the animations from the given FBX animation layer recursively starting from fbxNode.
-     * 
-     * @param fbxAnimLayer The FBX animation layer to load from.
-     * @param fbxNode The node to start loading animations from.
-     * @param arguments The command line arguments passed to the encoder.
-     */
-    void loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fbxNode, const EncoderArguments& arguments);
-
-    /**
-     * Loads animation channels from the given node and adds the channels to the given animation.
-     * 
-     * @param pAnimLayer The FBX animation layer to load from.
-     * @param fbxNode The node to load animation channels from.
-     * @param animation The animation to add the channels to.
-     */
-    void loadAnimationChannels(FbxAnimLayer* pAnimLayer, FbxNode* fbxNode, Animation* animation);
-
-    /**
-     * Loads the bind shape for all mesh skins that have be loaded so far.
-     * 
-     * @param fbxScene The FBX scene to read the bind shapes from.
-     */
-    void loadBindShapes(FbxScene* fbxScene);
-
-    /**
-     * Loads the camera from the given FBX node and adds to it to the given GamePlay node.
-     * 
-     * @param fbxNode The FBX node to load from.
-     * @param node The GamePlay node to add to.
-     */
-    void loadCamera(FbxNode* fbxNode, Node* node);
-
-    /**
-     * Loads the light from the given FBX node and adds to it to the given GamePlay node.
-     * 
-     * @param fbxNode The FBX node to load from.
-     * @param node The GamePlay node to add to.
-     */
-    void loadLight(FbxNode* fbxNode, Node* node);
-    
-    /**
-     * Loads the model from the given FBX node and adds to it to the given GamePlay node.
-     *
-     * @param fbxNode The FBX node to load from.
-     * @param node The GamePlay node to add to.
-     */
-    void loadModel(FbxNode* fbxNode, Node* node);
-
-    /**
-     * Loads materials for each node in the scene.
-     */
-    void loadMaterials(FbxScene* fbxScene);
-
-    /**
-     * Loads the material from the given node.
-     */
-    void loadMaterial(FbxNode* fbxNode);
-
-    void loadMaterialTextures(FbxSurfaceMaterial* fbxMaterial, Material* material);
-
-    void loadMaterialFileTexture(FbxFileTexture* fileTexture, Material* material);
-
-    void loadMaterialUniforms(FbxSurfaceMaterial* fbxMaterial, Material* material);
-
-    /**
-     * Creates a material from an FbxSurfaceMaterial.
-     * 
-     * @param name The name of the new material.
-     * @param fbxMaterial The FBX material to copy from.
-     * @param node The node that the material is being created for.
-     * 
-     * @return The newly created material.
-     */
-    Material* createMaterial(const std::string& name, FbxSurfaceMaterial* fbxMaterial, Node* node);
-
-    /**
-     * Loads the mesh skin from the given FBX mesh and adds it to the given GamePlay model.
-     *
-     * @param fbxMesh The FBX mesh to load the skin from.
-     * @param model The model to add the skin to.
-     */
-    void loadSkin(FbxMesh* fbxMesh, Model* model);
-    
-    /**
-     * Loads the FBX Node and creates a GamePlay Node.
-     * 
-     * @param fbxNode The FBX Node to load.
-     * 
-     * @return The newly created Node or NULL if the node could not be loaded.
-     */
-    Node* loadNode(FbxNode* fbxNode);
-    
-    /**
-     * Loads the FbxMesh and returns a GamePlay mesh.
-     * If the fbxMesh has already been loaded then the same instance of mesh will be returned.
-     * 
-     * @param fbxMesh The FBX Mesh to load.
-     * 
-     * @return The GamePlay mesh that was loaded from the FBX Mesh.
-     */
-    Mesh* loadMesh(FbxMesh* fbxMesh);
-
-    /**
-     * Gets the Mesh that was saved with the given ID. Returns NULL if a match is not found.
-     * 
-     * @param meshId The ID of the FbxMesh to search for.
-     * 
-     * @return The mesh that was saved with the ID or NULL if none was found.
-     */
-    Mesh* getMesh(FbxUInt64 meshId);
-
-    /**
-     * Saves the Mesh with the given id.
-     * 
-     * @param meshId The ID of the FbxMesh to use as a key.
-     * @param mesh The mesh to save.
-     */
-    void saveMesh(FbxUInt64 meshId, Mesh* mesh);
-    
-    /**
-     * Prints a message.
-     *
-     * @param str The string to print.
-     */
-    void print(const char* str);
-
-    /**
-     * Transforms the GamePlay Node using the transform data from the FBX Node.
-     * 
-     * @param fbxNode The FBX node to get the transfrom data from
-     * @param node The GamePlay Node to copy the transform to.
-     */
-    void transformNode(FbxNode* fbxNode, Node* node);
-
-    /**
-     * Gets the base material that matches the given id. Returns NULL if not found.
-     */
-    Material* getBaseMaterial(const char* id);
-
-    /**
-     * Finds the base material for the given material.
-     * This will either return a previously loaded base material or 
-     * the base material will be created and returned. (Should never return NULL)
-     */
-    Material* findBaseMaterial(Material* material);
-
-    /**
-     * Finds the gameplay Node that was created from the given FbxNode.
-     * Returns NULL if not found.
-     */
-    Node* findNode(FbxNode* fbxNode);
-
-    /**
-     * Creates a base material with the given name from the given child material.
-     * 
-     * @param baseMaterialName The name of the base material to create.
-     * @param childMaterial The child material that the base material is being created for.
-     * 
-     * @return The newly created base material.
-     */
-    Material* createBaseMaterial(const std::string& baseMaterialName, Material* childMaterial);
-
-    /**
-     * Recursively triangules the meshes starting from the given node.
-     * 
-     * @param fbxNode The node to start triangulating from.
-     */
-    static void triangulateRecursive(FbxNode* fbxNode);
-
-private:
-
-    /**
-     * The GamePlay file that is populated while reading the FBX file.
-     */
-    GPBFile _gamePlayFile;
-
-    /**
-     * The collection of meshes for the purpose of making sure that the same model is not loaded twice. (Mesh instancing)
-     */
-    std::map<FbxUInt64, Mesh*> _meshes;
-
-    /**
-     * The list of child materials that were loaded.
-     */
-    std::map<std::string, Material*> _materials;
-
-    /**
-     * The list of base materials that the child materials are derived from.
-     */
-    std::map<std::string, Material*> _baseMaterials;
-
-    /**
-     * A map for keeping track of which gameplay Node was created from a given FbxNode.
-     */
-    std::map<FbxNode*, Node*> _nodeMap;
-
-    /**
-     * The animation that channels should be added to if the user is using the -groupAnimation command line argument. May be NULL.
-     */
-    Animation* _groupAnimation;
-
-    /**
-     * Indicates if the animations for mesh skins should be grouped before writing out the GPB file.
-     */
-    bool _autoGroupAnimations;
-};
-
-#endif
+#ifndef FBXSCENEEENCODER_H_
+#define FBXSCENEEENCODER_H_
+
+#define FBXSDK_NEW_API
+
+#include <iostream>
+#include <list>
+#include <vector>
+#include <ctime>
+#ifdef WIN32
+    #pragma warning( disable : 4100 )
+    #pragma warning( disable : 4512 )
+#endif
+#include <fbxsdk.h>
+
+#include "Base.h"
+#include "StringUtil.h"
+#include "Object.h"
+#include "Node.h"
+#include "Camera.h"
+#include "Light.h"
+#include "Mesh.h"
+#include "MeshPart.h"
+#include "MeshSkin.h"
+#include "Model.h"
+#include "Scene.h"
+#include "Animation.h"
+#include "AnimationChannel.h"
+#include "Vertex.h"
+#include "Matrix.h"
+#include "Transform.h"
+#include "GPBFile.h"
+#include "EncoderArguments.h"
+
+using namespace gameplay;
+
+/**
+ * Class for binary encoding an FBX file.
+ */
+class FBXSceneEncoder
+{
+public:
+
+    static const unsigned int SCENE_SKIN_VERTEXINFLUENCES_MAX = 4;
+    
+    /**
+     * Constructor.
+     */
+    FBXSceneEncoder();
+
+    /**
+     * Destructor.
+     */
+    ~FBXSceneEncoder();
+    
+    /**
+     * Writes out encoded FBX file.
+     */
+    void write(const std::string& filepath, const EncoderArguments& arguments);
+
+    /**
+     * Writes a material file.
+     * 
+     * @param filepath 
+     * 
+     * @return True if successful; false otherwise.
+     */
+    bool writeMaterial(const std::string& filepath);
+
+private:
+
+    /**
+     * Loads the scene.
+     * 
+     * @param fbxScene The FBX scene to load.
+     */
+    void loadScene(FbxScene* fbxScene);
+
+    /**
+     * Loads all of the animatiosn from the given FBX scene.
+     * 
+     * @param fbxScene The scene to load animations from.
+     * @param arguments The command line arguments passed to the encoder.
+     */
+    void loadAnimations(FbxScene* fbxScene, const EncoderArguments& arguments);
+
+    /**
+     * Loads the animations from the given FBX animation layer recursively starting from fbxNode.
+     * 
+     * @param fbxAnimLayer The FBX animation layer to load from.
+     * @param fbxNode The node to start loading animations from.
+     * @param arguments The command line arguments passed to the encoder.
+     */
+    void loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fbxNode, const EncoderArguments& arguments);
+
+    /**
+     * Loads animation channels from the given node and adds the channels to the given animation.
+     * 
+     * @param pAnimLayer The FBX animation layer to load from.
+     * @param fbxNode The node to load animation channels from.
+     * @param animation The animation to add the channels to.
+     */
+    void loadAnimationChannels(FbxAnimLayer* pAnimLayer, FbxNode* fbxNode, Animation* animation);
+
+    /**
+     * Loads the bind shape for all mesh skins that have be loaded so far.
+     * 
+     * @param fbxScene The FBX scene to read the bind shapes from.
+     */
+    void loadBindShapes(FbxScene* fbxScene);
+
+    /**
+     * Loads the camera from the given FBX node and adds to it to the given GamePlay node.
+     * 
+     * @param fbxNode The FBX node to load from.
+     * @param node The GamePlay node to add to.
+     */
+    void loadCamera(FbxNode* fbxNode, Node* node);
+
+    /**
+     * Loads the light from the given FBX node and adds to it to the given GamePlay node.
+     * 
+     * @param fbxNode The FBX node to load from.
+     * @param node The GamePlay node to add to.
+     */
+    void loadLight(FbxNode* fbxNode, Node* node);
+    
+    /**
+     * Loads the model from the given FBX node and adds to it to the given GamePlay node.
+     *
+     * @param fbxNode The FBX node to load from.
+     * @param node The GamePlay node to add to.
+     */
+    void loadModel(FbxNode* fbxNode, Node* node);
+
+    /**
+     * Loads materials for each node in the scene.
+     */
+    void loadMaterials(FbxScene* fbxScene);
+
+    /**
+     * Loads the material from the given node.
+     */
+    void loadMaterial(FbxNode* fbxNode);
+
+    void loadMaterialTextures(FbxSurfaceMaterial* fbxMaterial, Material* material);
+
+    void loadMaterialFileTexture(FbxFileTexture* fileTexture, Material* material);
+
+    void loadMaterialUniforms(FbxSurfaceMaterial* fbxMaterial, Material* material);
+
+    /**
+     * Creates a material from an FbxSurfaceMaterial.
+     * 
+     * @param name The name of the new material.
+     * @param fbxMaterial The FBX material to copy from.
+     * @param node The node that the material is being created for.
+     * 
+     * @return The newly created material.
+     */
+    Material* createMaterial(const std::string& name, FbxSurfaceMaterial* fbxMaterial, Node* node);
+
+    /**
+     * Loads the mesh skin from the given FBX mesh and adds it to the given GamePlay model.
+     *
+     * @param fbxMesh The FBX mesh to load the skin from.
+     * @param model The model to add the skin to.
+     */
+    void loadSkin(FbxMesh* fbxMesh, Model* model);
+    
+    /**
+     * Loads the FBX Node and creates a GamePlay Node.
+     * 
+     * @param fbxNode The FBX Node to load.
+     * 
+     * @return The newly created Node or NULL if the node could not be loaded.
+     */
+    Node* loadNode(FbxNode* fbxNode);
+    
+    /**
+     * Loads the FbxMesh and returns a GamePlay mesh.
+     * If the fbxMesh has already been loaded then the same instance of mesh will be returned.
+     * 
+     * @param fbxMesh The FBX Mesh to load.
+     * 
+     * @return The GamePlay mesh that was loaded from the FBX Mesh.
+     */
+    Mesh* loadMesh(FbxMesh* fbxMesh);
+
+    /**
+     * Gets the Mesh that was saved with the given ID. Returns NULL if a match is not found.
+     * 
+     * @param meshId The ID of the FbxMesh to search for.
+     * 
+     * @return The mesh that was saved with the ID or NULL if none was found.
+     */
+    Mesh* getMesh(FbxUInt64 meshId);
+
+    /**
+     * Saves the Mesh with the given id.
+     * 
+     * @param meshId The ID of the FbxMesh to use as a key.
+     * @param mesh The mesh to save.
+     */
+    void saveMesh(FbxUInt64 meshId, Mesh* mesh);
+    
+    /**
+     * Prints a message.
+     *
+     * @param str The string to print.
+     */
+    void print(const char* str);
+
+    /**
+     * Transforms the GamePlay Node using the transform data from the FBX Node.
+     * 
+     * @param fbxNode The FBX node to get the transfrom data from
+     * @param node The GamePlay Node to copy the transform to.
+     */
+    void transformNode(FbxNode* fbxNode, Node* node);
+
+    /**
+     * Gets the base material that matches the given id. Returns NULL if not found.
+     */
+    Material* getBaseMaterial(const char* id);
+
+    /**
+     * Finds the base material for the given material.
+     * This will either return a previously loaded base material or 
+     * the base material will be created and returned. (Should never return NULL)
+     */
+    Material* findBaseMaterial(Material* material);
+
+    /**
+     * Finds the gameplay Node that was created from the given FbxNode.
+     * Returns NULL if not found.
+     */
+    Node* findNode(FbxNode* fbxNode);
+
+    /**
+     * Creates a base material with the given name from the given child material.
+     * 
+     * @param baseMaterialName The name of the base material to create.
+     * @param childMaterial The child material that the base material is being created for.
+     * 
+     * @return The newly created base material.
+     */
+    Material* createBaseMaterial(const std::string& baseMaterialName, Material* childMaterial);
+
+    /**
+     * Recursively triangules the meshes starting from the given node.
+     * 
+     * @param fbxNode The node to start triangulating from.
+     */
+    static void triangulateRecursive(FbxNode* fbxNode);
+
+private:
+
+    /**
+     * The GamePlay file that is populated while reading the FBX file.
+     */
+    GPBFile _gamePlayFile;
+
+    /**
+     * The collection of meshes for the purpose of making sure that the same model is not loaded twice. (Mesh instancing)
+     */
+    std::map<FbxUInt64, Mesh*> _meshes;
+
+    /**
+     * The list of child materials that were loaded.
+     */
+    std::map<std::string, Material*> _materials;
+
+    /**
+     * The list of base materials that the child materials are derived from.
+     */
+    std::map<std::string, Material*> _baseMaterials;
+
+    /**
+     * A map for keeping track of which gameplay Node was created from a given FbxNode.
+     */
+    std::map<FbxNode*, Node*> _nodeMap;
+
+    /**
+     * The animation that channels should be added to if the user is using the -groupAnimation command line argument. May be NULL.
+     */
+    Animation* _groupAnimation;
+
+    /**
+     * Indicates if the animations for mesh skins should be grouped before writing out the GPB file.
+     */
+    bool _autoGroupAnimations;
+};
+
+#endif

+ 805 - 805
tools/encoder/src/FBXUtil.cpp

@@ -1,805 +1,805 @@
-#include <algorithm>
-#include <string>
-#include <sstream>
-
-#include "FBXUtil.h"
-#include "Transform.h"
-#include "Vector3.h"
-#include "Vector2.h"
-
-using namespace gameplay;
-using std::string;
-using std::vector;
-using std::map;
-using std::ostringstream;
-
-float getAspectRatio(FbxCamera* fbxCamera)
-{
-    return (float)fbxCamera->FilmAspectRatio.Get();
-    /*
-    FbxCamera::ECameraAspectRatioMode camAspectRatioMode = fbxCamera->GetAspectRatioMode();
-    double aspectX = fbxCamera->AspectWidth.Get();
-    double aspectY = fbxCamera->AspectHeight.Get();
-    double aspectRatio = 1.333333;
-    switch ( camAspectRatioMode)
-    {
-    case FbxCamera::eWINDOW_SIZE:
-        aspectRatio = aspectX / aspectY;
-        break;
-    case FbxCamera::eFIXED_RATIO:
-        aspectRatio = aspectX;
-        break;
-    case FbxCamera::eFIXED_RESOLUTION:
-        aspectRatio = aspectX / aspectY * fbxCamera->GetPixelRatio();
-        break;
-    case FbxCamera::eFIXED_WIDTH:
-        aspectRatio = fbxCamera->GetPixelRatio() / aspectY;
-        break;
-    case FbxCamera::eFIXED_HEIGHT:
-        aspectRatio = fbxCamera->GetPixelRatio() * aspectX;
-        break;
-    default:
-        break;
-    }
-    return (float)aspectRatio;
-    */
-}
-
-inline double vfov(double hfov, double aspect)
-{
-    static const double MATH_PI_180 = 0.01745329251994329576923690768489;
-    static const double MATH_180_PI = 57.295779513082320876798154814105;
-    return (2.0 * atan((aspect) * tan( (hfov * MATH_PI_180) * 0.5)) * MATH_180_PI);
-}
-
-float getFieldOfView(FbxCamera* fbxCamera)
-{
-    double fieldOfViewX = 0.0;
-    double fieldOfViewY = 0.0;
-    double filmHeight = fbxCamera->GetApertureHeight();
-    double filmWidth = fbxCamera->GetApertureWidth() * fbxCamera->GetSqueezeRatio();
-    double apertureRatio = filmHeight / filmWidth;
-    if ( fbxCamera->GetApertureMode() == FbxCamera::eVertical)
-    {
-        fieldOfViewY = fbxCamera->FieldOfView.Get();
-    }
-    else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizontal)
-    {
-        fieldOfViewX = fbxCamera->FieldOfView.Get();
-        fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
-    }
-    else if (fbxCamera->GetApertureMode() == FbxCamera::eFocalLength)
-    {
-        fieldOfViewX = fbxCamera->ComputeFieldOfView(fbxCamera->FocalLength.Get());
-        fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
-    }
-    else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizAndVert)
-    {
-        fieldOfViewY = fbxCamera->FieldOfViewY.Get();
-    }
-    else
-    {
-        fieldOfViewY = 45.0;
-    }
-    return (float)fieldOfViewY;
-}
-
-void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex)
-{
-    assert(fbxMesh && polyIndex >= 0 && posInPoly >= 0);
-
-    const bool useIndex = uvs->GetReferenceMode() != FbxGeometryElement::eDirect;
-    const int indexCount = useIndex ? uvs->GetIndexArray().GetCount() : 0;
-    int uvIndex = -1;
-
-    switch (uvs->GetMappingMode())
-    {
-    case FbxGeometryElement::eByControlPoint:
-        {
-            // Get the index of the current vertex in control points array
-            int polyVertIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
-
-            // The UV index depends on the reference mode
-            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(polyVertIndex) : polyVertIndex;
-        }
-        break;
-
-    case FbxGeometryElement::eByPolygonVertex:
-        if (meshVertexIndex < indexCount)
-        {
-            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(meshVertexIndex) : meshVertexIndex;
-        }
-        break;
-
-    default:
-        // Only support eByPolygonVertex and eByControlPoint mappings
-        break;
-    }
-
-    vertex->hasTexCoord[uvSetIndex] = true;
-
-    // Store UV information in vertex
-    if (uvIndex != -1)
-    {
-        FbxVector2 uvValue = uvs->GetDirectArray().GetAt(uvIndex);
-        vertex->texCoord[uvSetIndex].x = (float)uvValue[0];
-        vertex->texCoord[uvSetIndex].y = (float)uvValue[1];
-    }
-}
-
-void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
-{
-    if (fbxMesh->GetElementNormalCount() > 0)
-    {
-        // Get only the first
-        FbxGeometryElementNormal* normal = fbxMesh->GetElementNormal(0);
-        FbxGeometryElement::EMappingMode mappingMode = normal->GetMappingMode();
-        if (mappingMode == FbxGeometryElement::eByControlPoint)
-        {
-            switch (normal->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(controlPointIndex);
-                    vertex->hasNormal = true;
-                    vertex->normal.x = (float)vec4[0];
-                    vertex->normal.y = (float)vec4[1];
-                    vertex->normal.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = normal->GetIndexArray().GetAt(controlPointIndex);
-                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
-                    vertex->hasNormal = true;
-                    vertex->normal.x = (float)vec4[0];
-                    vertex->normal.y = (float)vec4[1];
-                    vertex->normal.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
-        {
-            switch (normal->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(vertexIndex);
-                    vertex->hasNormal = true;
-                    vertex->normal.x = (float)vec4[0];
-                    vertex->normal.y = (float)vec4[1];
-                    vertex->normal.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = normal->GetIndexArray().GetAt(vertexIndex);
-                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
-                    vertex->hasNormal = true;
-                    vertex->normal.x = (float)vec4[0];
-                    vertex->normal.y = (float)vec4[1];
-                    vertex->normal.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
-
-void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
-{
-    if (fbxMesh->GetElementTangentCount() > 0)
-    {
-        // Get only the first tangent
-        FbxGeometryElementTangent* tangent = fbxMesh->GetElementTangent(0);
-        FbxGeometryElement::EMappingMode mappingMode = tangent->GetMappingMode();
-        if (mappingMode == FbxGeometryElement::eByControlPoint)
-        {
-            switch (tangent->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(controlPointIndex);
-                    vertex->hasTangent = true;
-                    vertex->tangent.x = (float)vec4[0];
-                    vertex->tangent.y = (float)vec4[1];
-                    vertex->tangent.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = tangent->GetIndexArray().GetAt(controlPointIndex);
-                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
-                    vertex->hasTangent = true;
-                    vertex->tangent.x = (float)vec4[0];
-                    vertex->tangent.y = (float)vec4[1];
-                    vertex->tangent.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
-        {
-            switch (tangent->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(vertexIndex);
-                    vertex->hasTangent = true;
-                    vertex->tangent.x = (float)vec4[0];
-                    vertex->tangent.y = (float)vec4[1];
-                    vertex->tangent.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = tangent->GetIndexArray().GetAt(vertexIndex);
-                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
-                    vertex->hasTangent = true;
-                    vertex->tangent.x = (float)vec4[0];
-                    vertex->tangent.y = (float)vec4[1];
-                    vertex->tangent.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
-
-void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
-{
-    if (fbxMesh->GetElementBinormalCount() > 0)
-    {
-        // Get only the first binormal.
-        FbxGeometryElementBinormal* binormal = fbxMesh->GetElementBinormal(0);
-        FbxGeometryElement::EMappingMode mappingMode = binormal->GetMappingMode();
-
-        if (mappingMode == FbxGeometryElement::eByControlPoint)
-        {
-            switch (binormal->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(controlPointIndex);
-                    vertex->hasBinormal = true;
-                    vertex->binormal.x = (float)vec4[0];
-                    vertex->binormal.y = (float)vec4[1];
-                    vertex->binormal.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = binormal->GetIndexArray().GetAt(controlPointIndex);
-                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
-                    vertex->hasBinormal = true;
-                    vertex->binormal.x = (float)vec4[0];
-                    vertex->binormal.y = (float)vec4[1];
-                    vertex->binormal.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
-        {
-            switch (binormal->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(vertexIndex);
-                    vertex->hasBinormal = true;
-                    vertex->binormal.x = (float)vec4[0];
-                    vertex->binormal.y = (float)vec4[1];
-                    vertex->binormal.z = (float)vec4[2];
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = binormal->GetIndexArray().GetAt(vertexIndex);
-                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
-                    vertex->hasBinormal = true;
-                    vertex->binormal.x = (float)vec4[0];
-                    vertex->binormal.y = (float)vec4[1];
-                    vertex->binormal.z = (float)vec4[2];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
-
-void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
-{
-    if (fbxMesh->GetElementVertexColorCount() > 0)
-    {
-        // Get only the first vertex color.
-        FbxGeometryElementVertexColor* vertexColor = fbxMesh->GetElementVertexColor(0);
-        FbxGeometryElement::EMappingMode mappingMode = vertexColor->GetMappingMode();
-        if (mappingMode == FbxGeometryElement::eByControlPoint)
-        {
-            switch (vertexColor->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxColor color = vertexColor->GetDirectArray().GetAt(controlPointIndex);
-
-                    vertex->hasDiffuse = true;
-                    vertex->diffuse.x = (float)color.mRed;
-                    vertex->diffuse.y = (float)color.mGreen;
-                    vertex->diffuse.z = (float)color.mBlue;
-                    vertex->diffuse.w = (float)color.mAlpha;
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = vertexColor->GetIndexArray().GetAt(controlPointIndex);
-                    FbxColor color = vertexColor->GetDirectArray().GetAt(id);
-
-                    vertex->hasDiffuse = true;
-                    vertex->diffuse.x = (float)color.mRed;
-                    vertex->diffuse.y = (float)color.mGreen;
-                    vertex->diffuse.z = (float)color.mBlue;
-                    vertex->diffuse.w = (float)color.mAlpha;
-                }
-                break;
-            default:
-                break;
-            }
-        }
-        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
-        {
-            switch (vertexColor->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                {
-                    FbxColor color = vertexColor->GetDirectArray().GetAt(vertexIndex);
-
-                    vertex->hasDiffuse = true;
-                    vertex->diffuse.x = (float)color.mRed;
-                    vertex->diffuse.y = (float)color.mGreen;
-                    vertex->diffuse.z = (float)color.mBlue;
-                    vertex->diffuse.w = (float)color.mAlpha;
-                }
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = vertexColor->GetIndexArray().GetAt(vertexIndex);
-                    FbxColor color = vertexColor->GetDirectArray().GetAt(id);
-
-                    vertex->hasDiffuse = true;
-                    vertex->diffuse.x = (float)color.mRed;
-                    vertex->diffuse.y = (float)color.mGreen;
-                    vertex->diffuse.z = (float)color.mBlue;
-                    vertex->diffuse.w = (float)color.mAlpha;
-                }
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
-
-void loadBlendData(const vector<Vector2>& vertexWeights, Vertex* vertex)
-{
-    size_t size = vertexWeights.size();
-
-    if (size >= 1)
-    {
-        vertex->hasWeights= true;
-        vertex->blendIndices.x = vertexWeights[0].x;
-        vertex->blendWeights.x = vertexWeights[0].y;
-    }
-    if (size >= 2)
-    {
-        vertex->blendIndices.y = vertexWeights[1].x;
-        vertex->blendWeights.y = vertexWeights[1].y;
-    }
-    if (size >= 3)
-    {
-        vertex->blendIndices.z = vertexWeights[2].x;
-        vertex->blendWeights.z = vertexWeights[2].y;
-    }
-    if (size >= 4)
-    {
-        vertex->blendIndices.w = vertexWeights[3].x;
-        vertex->blendWeights.w = vertexWeights[3].y;
-    }
-    //vertex->normalizeBlendWeight();
-}
-
-bool loadBlendWeights(FbxMesh* fbxMesh, vector<vector<Vector2> >& weights)
-{
-    assert(fbxMesh);
-    const int vertexCount = fbxMesh->GetControlPointsCount();
-
-    FbxSkin* fbxSkin = NULL;
-    const int deformerCount = fbxMesh->GetDeformerCount();
-    for (int i = 0; i < deformerCount; ++i)
-    {
-        FbxDeformer* deformer = fbxMesh->GetDeformer(i);
-        if (deformer->GetDeformerType() == FbxDeformer::eSkin)
-        {
-            fbxSkin = FbxCast<FbxSkin>(deformer);
-            weights.resize(vertexCount);
-
-            const int clusterCount = fbxSkin->GetClusterCount();
-            for (int j = 0; j < clusterCount; ++j)
-            {
-                FbxCluster* cluster = fbxSkin->GetCluster(j);
-                assert(cluster);
-                const int vertexIndexCount = cluster->GetControlPointIndicesCount();
-                for (int k = 0; k < vertexIndexCount; ++k)
-                {
-                    int index = cluster->GetControlPointIndices()[k];
-                    if (index >= vertexCount)
-                    {
-                        continue;
-                    }
-
-                    double weight = cluster->GetControlPointWeights()[k];
-                    if (weight == 0.0)
-                    {
-                        continue;
-                    }
-                    weights[index].push_back(Vector2((float)j, (float)weight));
-                }
-            }
-            // Only the first skin deformer will be loaded.
-            // There probably won't be more than one.
-            break;
-        }
-    }
-    return fbxSkin != NULL;
-}
-
-void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate)
-{
-    FbxTime start, stop;
-    FbxTimeSpan timeSpan;
-    animCurve->GetTimeInterval(timeSpan);
-    start = timeSpan.GetStart();
-    stop = timeSpan.GetStop();
-    *startTime = std::min(*startTime, (float)start.GetMilliSeconds());
-    *stopTime = std::max(*stopTime, (float)stop.GetMilliSeconds());
-    *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(FbxTime::eDefaultMode));
-}
-
-void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
-{
-    // Write key time
-    channel->getKeyTimes().push_back(time);
-
-    // Write key values
-    vector<float>& keyValues = channel->getKeyValues();
-    switch (channel->getTargetAttribute())
-    {
-        case Transform::ANIMATE_SCALE:
-        {
-            keyValues.push_back(scale.x);
-            keyValues.push_back(scale.y);
-            keyValues.push_back(scale.z);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_X:
-        {
-            keyValues.push_back(scale.x);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_Y:
-        {
-            keyValues.push_back(scale.y);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_Z:
-        {
-            keyValues.push_back(scale.z);
-        }
-        break;
-
-        case Transform::ANIMATE_ROTATE:
-        {
-            keyValues.push_back(rotation.x);
-            keyValues.push_back(rotation.y);
-            keyValues.push_back(rotation.z);
-            keyValues.push_back(rotation.w);
-        }
-        break;
-
-        case Transform::ANIMATE_TRANSLATE:
-        {
-            keyValues.push_back(translation.x);
-            keyValues.push_back(translation.y);
-            keyValues.push_back(translation.z);
-        }
-        break;
-
-        case Transform::ANIMATE_TRANSLATE_X:
-        {
-            keyValues.push_back(translation.x);
-        }
-        break;
-
-        case Transform::ANIMATE_TRANSLATE_Y:
-        {
-            keyValues.push_back(translation.y);
-        }
-        break;
-
-        case Transform::ANIMATE_TRANSLATE_Z:
-        {
-            keyValues.push_back(translation.z);
-        }
-        break;
-
-        case Transform::ANIMATE_ROTATE_TRANSLATE:
-        {
-            keyValues.push_back(rotation.x);
-            keyValues.push_back(rotation.y);
-            keyValues.push_back(rotation.z);
-            keyValues.push_back(rotation.w);
-            keyValues.push_back(translation.x);
-            keyValues.push_back(translation.y);
-            keyValues.push_back(translation.z);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
-        {
-            keyValues.push_back(scale.x);
-            keyValues.push_back(scale.y);
-            keyValues.push_back(scale.z);
-            keyValues.push_back(rotation.x);
-            keyValues.push_back(rotation.y);
-            keyValues.push_back(rotation.z);
-            keyValues.push_back(rotation.w);
-            keyValues.push_back(translation.x);
-            keyValues.push_back(translation.y);
-            keyValues.push_back(translation.z);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_TRANSLATE:
-        {
-            keyValues.push_back(scale.x);
-            keyValues.push_back(scale.y);
-            keyValues.push_back(scale.z);
-            keyValues.push_back(translation.x);
-            keyValues.push_back(translation.y);
-            keyValues.push_back(translation.z);
-        }
-        break;
-
-        case Transform::ANIMATE_SCALE_ROTATE:
-        {
-            keyValues.push_back(scale.x);
-            keyValues.push_back(scale.y);
-            keyValues.push_back(scale.z);
-            keyValues.push_back(rotation.x);
-            keyValues.push_back(rotation.y);
-            keyValues.push_back(rotation.z);
-            keyValues.push_back(rotation.w);
-        }
-        break;
-
-        default:
-        {
-            LOG(1, "Warning: Invalid animatoin target (%d) attribute for node: %s.\n", channel->getTargetAttribute(), fbxNode->GetName());
-        }
-        return;
-    }
-}
-
-void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
-{
-    FbxAMatrix fbxMatrix;
-    Matrix matrix;
-    FbxTime kTime;
-    kTime.SetMilliSeconds((FbxLongLong)time);
-    fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
-    copyMatrix(fbxMatrix, matrix);
-    matrix.decompose(scale, rotation, translation);
-}
-
-AnimationChannel* createAnimationChannel(FbxNode* fbxNode, unsigned int targetAttrib, const vector<float>& keyTimes, const vector<float>& keyValues)
-{
-    AnimationChannel* channel = new AnimationChannel();
-    channel->setTargetId(fbxNode->GetName());
-    channel->setKeyTimes(keyTimes);
-    channel->setKeyValues(keyValues);
-    channel->setInterpolation(AnimationChannel::LINEAR);
-    channel->setTargetAttribute(targetAttrib);
-    return channel;
-}
-
-void addScaleChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
-{
-    vector<float> keyTimes;
-    vector<float> keyValues;
-    Vector3 scale;
-    Quaternion rotation;
-    Vector3 translation;
-
-    decompose(fbxNode, startTime, &scale, &rotation, &translation);
-    keyTimes.push_back(startTime);
-    keyValues.push_back(scale.x);
-    keyValues.push_back(scale.y);
-    keyValues.push_back(scale.z);
-
-    decompose(fbxNode, stopTime, &scale, &rotation, &translation);
-    keyTimes.push_back(stopTime);
-    keyValues.push_back(scale.x);
-    keyValues.push_back(scale.y);
-    keyValues.push_back(scale.z);
-
-    AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_SCALE, keyTimes, keyValues);
-    animation->add(channel);
-}
-
-void addTranslateChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
-{
-    vector<float> keyTimes;
-    vector<float> keyValues;
-    Vector3 scale;
-    Quaternion rotation;
-    Vector3 translation;
-
-    decompose(fbxNode, startTime, &scale, &rotation, &translation);
-    keyTimes.push_back(startTime);
-    keyValues.push_back(translation.x);
-    keyValues.push_back(translation.y);
-    keyValues.push_back(translation.z);
-
-    decompose(fbxNode, stopTime, &scale, &rotation, &translation);
-    keyTimes.push_back(stopTime);
-    keyValues.push_back(translation.x);
-    keyValues.push_back(translation.y);
-    keyValues.push_back(translation.z);
-
-    AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_TRANSLATE, keyTimes, keyValues);
-    animation->add(channel);
-}
-
-void copyMatrix(const FbxMatrix& fbxMatrix, float* matrix)
-{
-    int i = 0;
-    for (int row = 0; row < 4; ++row)
-    {
-        for (int col = 0; col < 4; ++col)
-        {
-            matrix[i++] = (float)fbxMatrix.Get(row, col);
-        }
-    }
-}
-
-void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix)
-{
-    int i = 0;
-    for (int row = 0; row < 4; ++row)
-    {
-        for (int col = 0; col < 4; ++col)
-        {
-            matrix.m[i++] = (float)fbxMatrix.Get(row, col);
-        }
-    }
-}
-
-bool isGroupAnimationPossible(FbxScene* fbxScene)
-{
-    FbxNode* rootNode = fbxScene->GetRootNode();
-    if (rootNode)
-    {
-        if (isGroupAnimationPossible(rootNode))
-            return true;
-    }
-    return false;
-}
-
-bool isGroupAnimationPossible(FbxNode* fbxNode)
-{
-    if (fbxNode)
-    {
-        FbxMesh* fbxMesh = fbxNode->GetMesh();
-        if (isGroupAnimationPossible(fbxMesh))
-            return true;
-        const int childCount = fbxNode->GetChildCount();
-        for (int i = 0; i < childCount; ++i)
-        {
-            if (isGroupAnimationPossible(fbxNode->GetChild(i)))
-                return true;
-        }
-    }
-    return false;
-}
-
-bool isGroupAnimationPossible(FbxMesh* fbxMesh)
-{
-    if (fbxMesh)
-    {
-        const int deformerCount = fbxMesh->GetDeformerCount();
-        for (int i = 0; i < deformerCount; ++i)
-        {
-            FbxDeformer* deformer = fbxMesh->GetDeformer(i);
-            if (deformer->GetDeformerType() == FbxDeformer::eSkin)
-            {
-                FbxSkin* fbxSkin = FbxCast<FbxSkin>(deformer);
-                if (fbxSkin)
-                {
-                    return true;
-                }
-            }
-        }
-    }
-    return false;
-}
-
-bool isBlack(FbxDouble3& fbxDouble)
-{
-    return fbxDouble[0] == 0.0 && fbxDouble[1] == 0.0 && fbxDouble[2] == 0.0;
-}
-
-void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments)
-{
-    if (!fbxNode)
-        return;
-    const char* name = fbxNode->GetName();
-    if (name && strlen(name) > 0)
-    {
-        FbxMesh* fbxMesh = fbxNode->GetMesh();
-        if (fbxMesh && arguments.isGenerateTangentBinormalId(string(name)))
-        {
-            fbxMesh->GenerateTangentsDataForAllUVSets();
-        }
-    }
-    // visit child nodes
-    const int childCount = fbxNode->GetChildCount();
-    for (int i = 0; i < childCount; ++i)
-    {
-        generateTangentsAndBinormals(fbxNode->GetChild(i), arguments);
-    }
-}
-
-FbxAnimCurve* getCurve(FbxPropertyT<FbxDouble3>& prop, FbxAnimLayer* animLayer, const char* pChannel)
-{
-#if FBXSDK_VERSION_MAJOR == 2013 && FBXSDK_VERSION_MINOR == 1
-    return prop.GetCurve<FbxAnimCurve>(animLayer, pChannel);
-#else
-    return prop.GetCurve(animLayer, pChannel);
-#endif
-}
-
-std::string toString(const FbxDouble3& fbxDouble)
-{
-    ostringstream stream;
-    stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2];
-    return stream.str();
-}
-
-std::string toString(const FbxDouble3& fbxDouble, double d)
-{
-    ostringstream stream;
-    stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2] << ", " << d;
-    return stream.str();
-}
-
-std::string toString(double value)
-{
-    ostringstream stream;
-    stream << value;
-    return stream.str();
-}
+#include <algorithm>
+#include <string>
+#include <sstream>
+
+#include "FBXUtil.h"
+#include "Transform.h"
+#include "Vector3.h"
+#include "Vector2.h"
+
+using namespace gameplay;
+using std::string;
+using std::vector;
+using std::map;
+using std::ostringstream;
+
+float getAspectRatio(FbxCamera* fbxCamera)
+{
+    return (float)fbxCamera->FilmAspectRatio.Get();
+    /*
+    FbxCamera::ECameraAspectRatioMode camAspectRatioMode = fbxCamera->GetAspectRatioMode();
+    double aspectX = fbxCamera->AspectWidth.Get();
+    double aspectY = fbxCamera->AspectHeight.Get();
+    double aspectRatio = 1.333333;
+    switch ( camAspectRatioMode)
+    {
+    case FbxCamera::eWINDOW_SIZE:
+        aspectRatio = aspectX / aspectY;
+        break;
+    case FbxCamera::eFIXED_RATIO:
+        aspectRatio = aspectX;
+        break;
+    case FbxCamera::eFIXED_RESOLUTION:
+        aspectRatio = aspectX / aspectY * fbxCamera->GetPixelRatio();
+        break;
+    case FbxCamera::eFIXED_WIDTH:
+        aspectRatio = fbxCamera->GetPixelRatio() / aspectY;
+        break;
+    case FbxCamera::eFIXED_HEIGHT:
+        aspectRatio = fbxCamera->GetPixelRatio() * aspectX;
+        break;
+    default:
+        break;
+    }
+    return (float)aspectRatio;
+    */
+}
+
+inline double vfov(double hfov, double aspect)
+{
+    static const double MATH_PI_180 = 0.01745329251994329576923690768489;
+    static const double MATH_180_PI = 57.295779513082320876798154814105;
+    return (2.0 * atan((aspect) * tan( (hfov * MATH_PI_180) * 0.5)) * MATH_180_PI);
+}
+
+float getFieldOfView(FbxCamera* fbxCamera)
+{
+    double fieldOfViewX = 0.0;
+    double fieldOfViewY = 0.0;
+    double filmHeight = fbxCamera->GetApertureHeight();
+    double filmWidth = fbxCamera->GetApertureWidth() * fbxCamera->GetSqueezeRatio();
+    double apertureRatio = filmHeight / filmWidth;
+    if ( fbxCamera->GetApertureMode() == FbxCamera::eVertical)
+    {
+        fieldOfViewY = fbxCamera->FieldOfView.Get();
+    }
+    else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizontal)
+    {
+        fieldOfViewX = fbxCamera->FieldOfView.Get();
+        fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
+    }
+    else if (fbxCamera->GetApertureMode() == FbxCamera::eFocalLength)
+    {
+        fieldOfViewX = fbxCamera->ComputeFieldOfView(fbxCamera->FocalLength.Get());
+        fieldOfViewY = vfov( fieldOfViewX, apertureRatio);
+    }
+    else if (fbxCamera->GetApertureMode() == FbxCamera::eHorizAndVert)
+    {
+        fieldOfViewY = fbxCamera->FieldOfViewY.Get();
+    }
+    else
+    {
+        fieldOfViewY = 45.0;
+    }
+    return (float)fieldOfViewY;
+}
+
+void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex)
+{
+    assert(fbxMesh && polyIndex >= 0 && posInPoly >= 0);
+
+    const bool useIndex = uvs->GetReferenceMode() != FbxGeometryElement::eDirect;
+    const int indexCount = useIndex ? uvs->GetIndexArray().GetCount() : 0;
+    int uvIndex = -1;
+
+    switch (uvs->GetMappingMode())
+    {
+    case FbxGeometryElement::eByControlPoint:
+        {
+            // Get the index of the current vertex in control points array
+            int polyVertIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
+
+            // The UV index depends on the reference mode
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(polyVertIndex) : polyVertIndex;
+        }
+        break;
+
+    case FbxGeometryElement::eByPolygonVertex:
+        if (meshVertexIndex < indexCount)
+        {
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(meshVertexIndex) : meshVertexIndex;
+        }
+        break;
+
+    default:
+        // Only support eByPolygonVertex and eByControlPoint mappings
+        break;
+    }
+
+    vertex->hasTexCoord[uvSetIndex] = true;
+
+    // Store UV information in vertex
+    if (uvIndex != -1)
+    {
+        FbxVector2 uvValue = uvs->GetDirectArray().GetAt(uvIndex);
+        vertex->texCoord[uvSetIndex].x = (float)uvValue[0];
+        vertex->texCoord[uvSetIndex].y = (float)uvValue[1];
+    }
+}
+
+void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
+{
+    if (fbxMesh->GetElementNormalCount() > 0)
+    {
+        // Get only the first
+        FbxGeometryElementNormal* normal = fbxMesh->GetElementNormal(0);
+        FbxGeometryElement::EMappingMode mappingMode = normal->GetMappingMode();
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (normal->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(controlPointIndex);
+                    vertex->hasNormal = true;
+                    vertex->normal.x = (float)vec4[0];
+                    vertex->normal.y = (float)vec4[1];
+                    vertex->normal.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = normal->GetIndexArray().GetAt(controlPointIndex);
+                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
+                    vertex->hasNormal = true;
+                    vertex->normal.x = (float)vec4[0];
+                    vertex->normal.y = (float)vec4[1];
+                    vertex->normal.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
+        {
+            switch (normal->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(vertexIndex);
+                    vertex->hasNormal = true;
+                    vertex->normal.x = (float)vec4[0];
+                    vertex->normal.y = (float)vec4[1];
+                    vertex->normal.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = normal->GetIndexArray().GetAt(vertexIndex);
+                    FbxVector4 vec4 = normal->GetDirectArray().GetAt(id);
+                    vertex->hasNormal = true;
+                    vertex->normal.x = (float)vec4[0];
+                    vertex->normal.y = (float)vec4[1];
+                    vertex->normal.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
+
+void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
+{
+    if (fbxMesh->GetElementTangentCount() > 0)
+    {
+        // Get only the first tangent
+        FbxGeometryElementTangent* tangent = fbxMesh->GetElementTangent(0);
+        FbxGeometryElement::EMappingMode mappingMode = tangent->GetMappingMode();
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (tangent->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(controlPointIndex);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = tangent->GetIndexArray().GetAt(controlPointIndex);
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
+        {
+            switch (tangent->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(vertexIndex);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = tangent->GetIndexArray().GetAt(vertexIndex);
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
+
+void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
+{
+    if (fbxMesh->GetElementBinormalCount() > 0)
+    {
+        // Get only the first binormal.
+        FbxGeometryElementBinormal* binormal = fbxMesh->GetElementBinormal(0);
+        FbxGeometryElement::EMappingMode mappingMode = binormal->GetMappingMode();
+
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (binormal->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(controlPointIndex);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = binormal->GetIndexArray().GetAt(controlPointIndex);
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
+        {
+            switch (binormal->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(vertexIndex);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = binormal->GetIndexArray().GetAt(vertexIndex);
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
+
+void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
+{
+    if (fbxMesh->GetElementVertexColorCount() > 0)
+    {
+        // Get only the first vertex color.
+        FbxGeometryElementVertexColor* vertexColor = fbxMesh->GetElementVertexColor(0);
+        FbxGeometryElement::EMappingMode mappingMode = vertexColor->GetMappingMode();
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (vertexColor->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(controlPointIndex);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = vertexColor->GetIndexArray().GetAt(controlPointIndex);
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(id);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
+        {
+            switch (vertexColor->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(vertexIndex);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = vertexColor->GetIndexArray().GetAt(vertexIndex);
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(id);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+}
+
+void loadBlendData(const vector<Vector2>& vertexWeights, Vertex* vertex)
+{
+    size_t size = vertexWeights.size();
+
+    if (size >= 1)
+    {
+        vertex->hasWeights= true;
+        vertex->blendIndices.x = vertexWeights[0].x;
+        vertex->blendWeights.x = vertexWeights[0].y;
+    }
+    if (size >= 2)
+    {
+        vertex->blendIndices.y = vertexWeights[1].x;
+        vertex->blendWeights.y = vertexWeights[1].y;
+    }
+    if (size >= 3)
+    {
+        vertex->blendIndices.z = vertexWeights[2].x;
+        vertex->blendWeights.z = vertexWeights[2].y;
+    }
+    if (size >= 4)
+    {
+        vertex->blendIndices.w = vertexWeights[3].x;
+        vertex->blendWeights.w = vertexWeights[3].y;
+    }
+    //vertex->normalizeBlendWeight();
+}
+
+bool loadBlendWeights(FbxMesh* fbxMesh, vector<vector<Vector2> >& weights)
+{
+    assert(fbxMesh);
+    const int vertexCount = fbxMesh->GetControlPointsCount();
+
+    FbxSkin* fbxSkin = NULL;
+    const int deformerCount = fbxMesh->GetDeformerCount();
+    for (int i = 0; i < deformerCount; ++i)
+    {
+        FbxDeformer* deformer = fbxMesh->GetDeformer(i);
+        if (deformer->GetDeformerType() == FbxDeformer::eSkin)
+        {
+            fbxSkin = FbxCast<FbxSkin>(deformer);
+            weights.resize(vertexCount);
+
+            const int clusterCount = fbxSkin->GetClusterCount();
+            for (int j = 0; j < clusterCount; ++j)
+            {
+                FbxCluster* cluster = fbxSkin->GetCluster(j);
+                assert(cluster);
+                const int vertexIndexCount = cluster->GetControlPointIndicesCount();
+                for (int k = 0; k < vertexIndexCount; ++k)
+                {
+                    int index = cluster->GetControlPointIndices()[k];
+                    if (index >= vertexCount)
+                    {
+                        continue;
+                    }
+
+                    double weight = cluster->GetControlPointWeights()[k];
+                    if (weight == 0.0)
+                    {
+                        continue;
+                    }
+                    weights[index].push_back(Vector2((float)j, (float)weight));
+                }
+            }
+            // Only the first skin deformer will be loaded.
+            // There probably won't be more than one.
+            break;
+        }
+    }
+    return fbxSkin != NULL;
+}
+
+void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate)
+{
+    FbxTime start, stop;
+    FbxTimeSpan timeSpan;
+    animCurve->GetTimeInterval(timeSpan);
+    start = timeSpan.GetStart();
+    stop = timeSpan.GetStop();
+    *startTime = std::min(*startTime, (float)start.GetMilliSeconds());
+    *stopTime = std::max(*stopTime, (float)stop.GetMilliSeconds());
+    *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(FbxTime::eDefaultMode));
+}
+
+void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
+{
+    // Write key time
+    channel->getKeyTimes().push_back(time);
+
+    // Write key values
+    vector<float>& keyValues = channel->getKeyValues();
+    switch (channel->getTargetAttribute())
+    {
+        case Transform::ANIMATE_SCALE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_X:
+        {
+            keyValues.push_back(scale.x);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_Y:
+        {
+            keyValues.push_back(scale.y);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_Z:
+        {
+            keyValues.push_back(scale.z);
+        }
+        break;
+
+        case Transform::ANIMATE_ROTATE:
+        {
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE:
+        {
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_X:
+        {
+            keyValues.push_back(translation.x);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_Y:
+        {
+            keyValues.push_back(translation.y);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_Z:
+        {
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_ROTATE_TRANSLATE:
+        {
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_TRANSLATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_ROTATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+        }
+        break;
+
+        default:
+        {
+            LOG(1, "Warning: Invalid animatoin target (%d) attribute for node: %s.\n", channel->getTargetAttribute(), fbxNode->GetName());
+        }
+        return;
+    }
+}
+
+void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
+{
+    FbxAMatrix fbxMatrix;
+    Matrix matrix;
+    FbxTime kTime;
+    kTime.SetMilliSeconds((FbxLongLong)time);
+    fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
+    copyMatrix(fbxMatrix, matrix);
+    matrix.decompose(scale, rotation, translation);
+}
+
+AnimationChannel* createAnimationChannel(FbxNode* fbxNode, unsigned int targetAttrib, const vector<float>& keyTimes, const vector<float>& keyValues)
+{
+    AnimationChannel* channel = new AnimationChannel();
+    channel->setTargetId(fbxNode->GetName());
+    channel->setKeyTimes(keyTimes);
+    channel->setKeyValues(keyValues);
+    channel->setInterpolation(AnimationChannel::LINEAR);
+    channel->setTargetAttribute(targetAttrib);
+    return channel;
+}
+
+void addScaleChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
+{
+    vector<float> keyTimes;
+    vector<float> keyValues;
+    Vector3 scale;
+    Quaternion rotation;
+    Vector3 translation;
+
+    decompose(fbxNode, startTime, &scale, &rotation, &translation);
+    keyTimes.push_back(startTime);
+    keyValues.push_back(scale.x);
+    keyValues.push_back(scale.y);
+    keyValues.push_back(scale.z);
+
+    decompose(fbxNode, stopTime, &scale, &rotation, &translation);
+    keyTimes.push_back(stopTime);
+    keyValues.push_back(scale.x);
+    keyValues.push_back(scale.y);
+    keyValues.push_back(scale.z);
+
+    AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_SCALE, keyTimes, keyValues);
+    animation->add(channel);
+}
+
+void addTranslateChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime)
+{
+    vector<float> keyTimes;
+    vector<float> keyValues;
+    Vector3 scale;
+    Quaternion rotation;
+    Vector3 translation;
+
+    decompose(fbxNode, startTime, &scale, &rotation, &translation);
+    keyTimes.push_back(startTime);
+    keyValues.push_back(translation.x);
+    keyValues.push_back(translation.y);
+    keyValues.push_back(translation.z);
+
+    decompose(fbxNode, stopTime, &scale, &rotation, &translation);
+    keyTimes.push_back(stopTime);
+    keyValues.push_back(translation.x);
+    keyValues.push_back(translation.y);
+    keyValues.push_back(translation.z);
+
+    AnimationChannel* channel = createAnimationChannel(fbxNode, Transform::ANIMATE_TRANSLATE, keyTimes, keyValues);
+    animation->add(channel);
+}
+
+void copyMatrix(const FbxMatrix& fbxMatrix, float* matrix)
+{
+    int i = 0;
+    for (int row = 0; row < 4; ++row)
+    {
+        for (int col = 0; col < 4; ++col)
+        {
+            matrix[i++] = (float)fbxMatrix.Get(row, col);
+        }
+    }
+}
+
+void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix)
+{
+    int i = 0;
+    for (int row = 0; row < 4; ++row)
+    {
+        for (int col = 0; col < 4; ++col)
+        {
+            matrix.m[i++] = (float)fbxMatrix.Get(row, col);
+        }
+    }
+}
+
+bool isGroupAnimationPossible(FbxScene* fbxScene)
+{
+    FbxNode* rootNode = fbxScene->GetRootNode();
+    if (rootNode)
+    {
+        if (isGroupAnimationPossible(rootNode))
+            return true;
+    }
+    return false;
+}
+
+bool isGroupAnimationPossible(FbxNode* fbxNode)
+{
+    if (fbxNode)
+    {
+        FbxMesh* fbxMesh = fbxNode->GetMesh();
+        if (isGroupAnimationPossible(fbxMesh))
+            return true;
+        const int childCount = fbxNode->GetChildCount();
+        for (int i = 0; i < childCount; ++i)
+        {
+            if (isGroupAnimationPossible(fbxNode->GetChild(i)))
+                return true;
+        }
+    }
+    return false;
+}
+
+bool isGroupAnimationPossible(FbxMesh* fbxMesh)
+{
+    if (fbxMesh)
+    {
+        const int deformerCount = fbxMesh->GetDeformerCount();
+        for (int i = 0; i < deformerCount; ++i)
+        {
+            FbxDeformer* deformer = fbxMesh->GetDeformer(i);
+            if (deformer->GetDeformerType() == FbxDeformer::eSkin)
+            {
+                FbxSkin* fbxSkin = FbxCast<FbxSkin>(deformer);
+                if (fbxSkin)
+                {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool isBlack(FbxDouble3& fbxDouble)
+{
+    return fbxDouble[0] == 0.0 && fbxDouble[1] == 0.0 && fbxDouble[2] == 0.0;
+}
+
+void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments)
+{
+    if (!fbxNode)
+        return;
+    const char* name = fbxNode->GetName();
+    if (name && strlen(name) > 0)
+    {
+        FbxMesh* fbxMesh = fbxNode->GetMesh();
+        if (fbxMesh && arguments.isGenerateTangentBinormalId(string(name)))
+        {
+            fbxMesh->GenerateTangentsDataForAllUVSets();
+        }
+    }
+    // visit child nodes
+    const int childCount = fbxNode->GetChildCount();
+    for (int i = 0; i < childCount; ++i)
+    {
+        generateTangentsAndBinormals(fbxNode->GetChild(i), arguments);
+    }
+}
+
+FbxAnimCurve* getCurve(FbxPropertyT<FbxDouble3>& prop, FbxAnimLayer* animLayer, const char* pChannel)
+{
+#if FBXSDK_VERSION_MAJOR == 2013 && FBXSDK_VERSION_MINOR == 1
+    return prop.GetCurve<FbxAnimCurve>(animLayer, pChannel);
+#else
+    return prop.GetCurve(animLayer, pChannel);
+#endif
+}
+
+std::string toString(const FbxDouble3& fbxDouble)
+{
+    ostringstream stream;
+    stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2];
+    return stream.str();
+}
+
+std::string toString(const FbxDouble3& fbxDouble, double d)
+{
+    ostringstream stream;
+    stream << fbxDouble[0] << ", " << fbxDouble[1] << ", " << fbxDouble[2] << ", " << d;
+    return stream.str();
+}
+
+std::string toString(double value)
+{
+    ostringstream stream;
+    stream << value;
+    return stream.str();
+}

+ 203 - 203
tools/encoder/src/FBXUtil.h

@@ -1,203 +1,203 @@
-#ifndef FBXUTIL_H_
-#define FBXUTIL_H_
-
-#define FBXSDK_NEW_API
-
-#include <iostream>
-#include <list>
-#include <vector>
-#include <ctime>
-#ifdef WIN32
-    #pragma warning( disable : 4100 )
-    #pragma warning( disable : 4512 )
-#endif
-#include <fbxsdk.h>
-
-#include "Base.h"
-#include "Vertex.h"
-#include "Animation.h"
-#include "AnimationChannel.h"
-#include "EncoderArguments.h"
-
-using namespace gameplay;
-
-/**
- * Returns the aspect ratio from the given camera.
- * 
- * @param fbxCamera The FBX camera to get the aspect ratio from.
- * 
- * @return The aspect ratio from the camera.
- */
-float getAspectRatio(FbxCamera* fbxCamera);
-
-/**
- * Returns the field of view Y from the given camera.
- * 
- * @param fbxCamera The camera to get the fiew of view from.
- * 
- * @return The field of view Y.
- */
-float getFieldOfView(FbxCamera* fbxCamera);
-
-/**
- * Loads the texture coordinates from given mesh's polygon part into the vertex.
- * 
- * @param fbxMesh The mesh to get the polygon from.
- * @param uvs The UV list to load tex coords from.
- * @param uvSetIndex The UV set index of the uvs.
- * @param polyIndex The index of the polygon in the mesh.
- * @param posInPoly The position of the vertex in the polygon.
- * @param meshVertexIndex The index of the vertex in the mesh.
- * @param vertex The vertex to copy the texture coordinates to.
- */
-void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex);
-
-/**
- * Loads the normal from the mesh and adds it to the given vertex.
- * 
- * @param fbxMesh The mesh to get the polygon from.
- * @param vertexIndex The vertex index in the mesh.
- * @param controlPointIndex The control point index.
- * @param vertex The vertex to copy to.
- */
-void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
-
-/**
- * Loads the tangent from the mesh and adds it to the given vertex.
- * 
- * @param fbxMesh The mesh to load from.
- * @param vertexIndex The index of the vertex within fbxMesh.
- * @param controlPointIndex The control point index.
- * @param vertex The vertex to copy to.
- */
-void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
-
-/**
- * Loads the binormal from the mesh and adds it to the given vertex.
- * 
- * @param fbxMesh The mesh to load from.
- * @param vertexIndex The index of the vertex within fbxMesh.
- * @param controlPointIndex The control point index.
- * @param vertex The vertex to copy to.
- */
-void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
-
-/**
- * Loads the vertex diffuse color from the mesh and adds it to the given vertex.
- * 
- * @param fbxMesh The mesh to load from.
- * @param vertexIndex The index of the vertex within fbxMesh.
- * @param controlPointIndex The control point index.
- * @param vertex The vertex to copy to.
- */
-void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
-
-/**
- * Loads the blend weight and blend indices data into the vertex.
- * 
- * @param vertexWeights List of vertex weights. The x member contains the blendIndices. The y member contains the blendWeights.
- * @param vertex The vertex to copy the blend data to.
- */
-void loadBlendData(const std::vector<Vector2>& vertexWeights, Vertex* vertex);
-
-/**
- * Loads the blend weights and blend indices from the given mesh.
- * 
- * Each element of weights is a list of Vector2s where "x" is the blend index and "y" is the blend weight.
- * 
- * @param fbxMesh The mesh to load from.
- * @param weights List of blend weights and blend indices for each vertex.
- * 
- * @return True if this mesh has a mesh skin, false otherwise.
- */
-bool loadBlendWeights(FbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weights);
-
-/**
- * Copies from an FBX matrix to a float[16] array.
- */
-void copyMatrix(const FbxMatrix& fbxMatrix, float* matrix);
-
-/**
- * Copies from an FBX matrix to a gameplay matrix.
- */
-void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix);
-
-/**
- * Finds the min and max start time and stop time of the given animation curve.
- * 
- * startTime is updated if the animation curve contains a start time that is less than startTime.
- * stopTime is updated if the animation curve contains a stop time that is greater than stopTime.
- * frameRate is updated if the animation curve contains a frame rate that is greater than frameRate.
- * 
- * @param animCurve The animation curve to read from.
- * @param startTime The min start time. (in/out)
- * @param stopTime The max stop time. (in/out)
- * @param frameRate The frame rate. (in/out)
- */
-void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate);
-
-/**
- * Appends key frame data to the given node for the specified animation target attribute.
- * 
- * @param fbxNode The node to get the matrix transform from.
- * @param channel The aniamtion channel to write values into.
- * @param time The time of the keyframe.
- * @param scale The evaluated scale for the keyframe.
- * @param rotation The evalulated rotation for the keyframe.
- * @param translation The evalulated translation for the keyframe.
-
- */
-void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation);
-
-/**
- * Decomposes the given node's matrix transform at the given time and copies to scale, rotation and translation.
- * 
- * @param fbxNode The node to get the matrix transform from.
- * @param time The time to get the matrix transform from.
- * @param scale The scale to copy to.
- * @param rotation The rotation to copy to.
- * @param translation The translation to copy to.
- */
-void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation);
-
-/**
- * Creates an animation channel that targets the given node and target attribute using the given key times and key values.
- * 
- * @param fbxNode The node to target.
- * @param targetAttrib The attribute type to target.
- * @param keyTimes The key times for the animation channel.
- * @param keyValues The key values for the animation channel.
- * 
- * @return The newly created animation channel.
- */
-AnimationChannel* createAnimationChannel(FbxNode* fbxNode, unsigned int targetAttrib, const std::vector<float>& keyTimes, const std::vector<float>& keyValues);
-
-void addScaleChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime);
-
-void addTranslateChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime);
-
-/**
- * Determines if it is possible to automatically group animations for mesh skins.
- * 
- * @param fbxScene The FBX scene to search.
- * 
- * @return True if there is at least one mesh skin that has animations that can be grouped.
- */
-bool isGroupAnimationPossible(FbxScene* fbxScene);
-bool isGroupAnimationPossible(FbxNode* fbxNode);
-bool isGroupAnimationPossible(FbxMesh* fbxMesh);
-
-bool isBlack(FbxDouble3& fbxDouble);
-
-/**
- * Recursively generates the tangents and binormals for all nodes that were specified in the command line arguments.
- */
-void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments);
-
-FbxAnimCurve* getCurve(FbxPropertyT<FbxDouble3>& prop, FbxAnimLayer* animLayer, const char* pChannel);
-
-std::string toString(const FbxDouble3& fbxDouble);
-std::string toString(const FbxDouble3& fbxDouble, double d);
-std::string toString(double value);
-
-#endif
+#ifndef FBXUTIL_H_
+#define FBXUTIL_H_
+
+#define FBXSDK_NEW_API
+
+#include <iostream>
+#include <list>
+#include <vector>
+#include <ctime>
+#ifdef WIN32
+    #pragma warning( disable : 4100 )
+    #pragma warning( disable : 4512 )
+#endif
+#include <fbxsdk.h>
+
+#include "Base.h"
+#include "Vertex.h"
+#include "Animation.h"
+#include "AnimationChannel.h"
+#include "EncoderArguments.h"
+
+using namespace gameplay;
+
+/**
+ * Returns the aspect ratio from the given camera.
+ * 
+ * @param fbxCamera The FBX camera to get the aspect ratio from.
+ * 
+ * @return The aspect ratio from the camera.
+ */
+float getAspectRatio(FbxCamera* fbxCamera);
+
+/**
+ * Returns the field of view Y from the given camera.
+ * 
+ * @param fbxCamera The camera to get the fiew of view from.
+ * 
+ * @return The field of view Y.
+ */
+float getFieldOfView(FbxCamera* fbxCamera);
+
+/**
+ * Loads the texture coordinates from given mesh's polygon part into the vertex.
+ * 
+ * @param fbxMesh The mesh to get the polygon from.
+ * @param uvs The UV list to load tex coords from.
+ * @param uvSetIndex The UV set index of the uvs.
+ * @param polyIndex The index of the polygon in the mesh.
+ * @param posInPoly The position of the vertex in the polygon.
+ * @param meshVertexIndex The index of the vertex in the mesh.
+ * @param vertex The vertex to copy the texture coordinates to.
+ */
+void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex);
+
+/**
+ * Loads the normal from the mesh and adds it to the given vertex.
+ * 
+ * @param fbxMesh The mesh to get the polygon from.
+ * @param vertexIndex The vertex index in the mesh.
+ * @param controlPointIndex The control point index.
+ * @param vertex The vertex to copy to.
+ */
+void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
+
+/**
+ * Loads the tangent from the mesh and adds it to the given vertex.
+ * 
+ * @param fbxMesh The mesh to load from.
+ * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
+ * @param vertex The vertex to copy to.
+ */
+void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
+
+/**
+ * Loads the binormal from the mesh and adds it to the given vertex.
+ * 
+ * @param fbxMesh The mesh to load from.
+ * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
+ * @param vertex The vertex to copy to.
+ */
+void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
+
+/**
+ * Loads the vertex diffuse color from the mesh and adds it to the given vertex.
+ * 
+ * @param fbxMesh The mesh to load from.
+ * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
+ * @param vertex The vertex to copy to.
+ */
+void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
+
+/**
+ * Loads the blend weight and blend indices data into the vertex.
+ * 
+ * @param vertexWeights List of vertex weights. The x member contains the blendIndices. The y member contains the blendWeights.
+ * @param vertex The vertex to copy the blend data to.
+ */
+void loadBlendData(const std::vector<Vector2>& vertexWeights, Vertex* vertex);
+
+/**
+ * Loads the blend weights and blend indices from the given mesh.
+ * 
+ * Each element of weights is a list of Vector2s where "x" is the blend index and "y" is the blend weight.
+ * 
+ * @param fbxMesh The mesh to load from.
+ * @param weights List of blend weights and blend indices for each vertex.
+ * 
+ * @return True if this mesh has a mesh skin, false otherwise.
+ */
+bool loadBlendWeights(FbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weights);
+
+/**
+ * Copies from an FBX matrix to a float[16] array.
+ */
+void copyMatrix(const FbxMatrix& fbxMatrix, float* matrix);
+
+/**
+ * Copies from an FBX matrix to a gameplay matrix.
+ */
+void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix);
+
+/**
+ * Finds the min and max start time and stop time of the given animation curve.
+ * 
+ * startTime is updated if the animation curve contains a start time that is less than startTime.
+ * stopTime is updated if the animation curve contains a stop time that is greater than stopTime.
+ * frameRate is updated if the animation curve contains a frame rate that is greater than frameRate.
+ * 
+ * @param animCurve The animation curve to read from.
+ * @param startTime The min start time. (in/out)
+ * @param stopTime The max stop time. (in/out)
+ * @param frameRate The frame rate. (in/out)
+ */
+void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate);
+
+/**
+ * Appends key frame data to the given node for the specified animation target attribute.
+ * 
+ * @param fbxNode The node to get the matrix transform from.
+ * @param channel The aniamtion channel to write values into.
+ * @param time The time of the keyframe.
+ * @param scale The evaluated scale for the keyframe.
+ * @param rotation The evalulated rotation for the keyframe.
+ * @param translation The evalulated translation for the keyframe.
+
+ */
+void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation);
+
+/**
+ * Decomposes the given node's matrix transform at the given time and copies to scale, rotation and translation.
+ * 
+ * @param fbxNode The node to get the matrix transform from.
+ * @param time The time to get the matrix transform from.
+ * @param scale The scale to copy to.
+ * @param rotation The rotation to copy to.
+ * @param translation The translation to copy to.
+ */
+void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation);
+
+/**
+ * Creates an animation channel that targets the given node and target attribute using the given key times and key values.
+ * 
+ * @param fbxNode The node to target.
+ * @param targetAttrib The attribute type to target.
+ * @param keyTimes The key times for the animation channel.
+ * @param keyValues The key values for the animation channel.
+ * 
+ * @return The newly created animation channel.
+ */
+AnimationChannel* createAnimationChannel(FbxNode* fbxNode, unsigned int targetAttrib, const std::vector<float>& keyTimes, const std::vector<float>& keyValues);
+
+void addScaleChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime);
+
+void addTranslateChannel(Animation* animation, FbxNode* fbxNode, float startTime, float stopTime);
+
+/**
+ * Determines if it is possible to automatically group animations for mesh skins.
+ * 
+ * @param fbxScene The FBX scene to search.
+ * 
+ * @return True if there is at least one mesh skin that has animations that can be grouped.
+ */
+bool isGroupAnimationPossible(FbxScene* fbxScene);
+bool isGroupAnimationPossible(FbxNode* fbxNode);
+bool isGroupAnimationPossible(FbxMesh* fbxMesh);
+
+bool isBlack(FbxDouble3& fbxDouble);
+
+/**
+ * Recursively generates the tangents and binormals for all nodes that were specified in the command line arguments.
+ */
+void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments);
+
+FbxAnimCurve* getCurve(FbxPropertyT<FbxDouble3>& prop, FbxAnimLayer* animLayer, const char* pChannel);
+
+std::string toString(const FbxDouble3& fbxDouble);
+std::string toString(const FbxDouble3& fbxDouble, double d);
+std::string toString(double value);
+
+#endif

+ 208 - 208
tools/encoder/src/FileIO.cpp

@@ -1,208 +1,208 @@
-#include "Base.h"
-#include "FileIO.h"
-
-namespace gameplay
-{
-
-// Writing out a binary file //
-
-void write(unsigned char value, FILE* file)
-{
-    size_t r = fwrite(&value, sizeof(unsigned char), 1, file);
-    assert(r == 1);
-}
-
-void write(char value, FILE* file)
-{
-    size_t r = fwrite(&value, sizeof(char), 1, file);
-    assert(r == 1);
-}
-
-void write(const char* str, FILE* file)
-{
-    size_t length = strlen(str);
-    size_t r = fwrite(str, 1, length, file);
-    assert(r == length);
-}
-
-void write(unsigned int value, FILE* file)
-{
-    size_t r = fwrite(&value, sizeof(unsigned int), 1, file);
-    assert(r == 1);
-}
-
-void write(unsigned short value, FILE* file)
-{
-    size_t r = fwrite(&value, sizeof(unsigned short), 1, file);
-    assert(r == 1);
-}
-
-void write(bool value, FILE* file)
-{
-    // write booleans as a unsigned char
-    unsigned char b = value;
-    write(b, file);
-}
-void write(float value, FILE* file)
-{
-    fwrite(&value, sizeof(float), 1, file);
-}
-void write(const float* values, int length, FILE* file)
-{
-    for (int i = 0; i < length; ++i)
-    {
-        write(values[i], file);
-    }
-}
-void write(const std::string& str, FILE* file)
-{
-    // Write the length of the string
-    write((unsigned int)str.size(), file);
-    
-    if (str.size() > 0)
-    {
-        // Write the array of characters of the string
-        write(str.c_str(), file);
-    }
-}
-
-void writeZero(FILE* file)
-{
-    write((unsigned int)0, file);
-}
-
-// Writing to a text file //
-
-void fprintfElement(FILE* file, const char* elementName, const float values[], int length)
-{
-    fprintf(file, "<%s count=\"%d\">", elementName, length);
-    for (int i = 0; i < length; ++i)
-    {
-        fprintf(file, "%f ", values[i]);
-    }
-    fprintf(file, "</%s>\n", elementName);
-}
-void fprintfElement(FILE* file, const char* elementName, const char* value)
-{
-    fprintf(file, "<%s>%s</%s>\n", elementName, value, elementName);
-}
-void fprintfElement(FILE* file, const char* elementName, const std::string& value)
-{
-    fprintf(file, "<%s>%s</%s>\n", elementName, value.c_str(), elementName);
-}
-void fprintfElement(FILE* file, const char* elementName, float value)
-{
-    fprintf(file, "<%s>%f</%s>\n", elementName, value, elementName);
-}
-void fprintfElement(FILE* file, const char* elementName, unsigned int value)
-{
-    fprintf(file, "<%s>%u</%s>\n", elementName, value, elementName);
-}
-void fprintfElement(FILE* file, const char* elementName, unsigned char value)
-{
-    fprintf(file, "<%s>%u</%s>\n", elementName, value, elementName);
-}
-
-void fprintfMatrix4f(FILE* file, const float* m)
-{
-    for (size_t i = 0; i < 16; i ++)
-    {
-        float v = m[i];
-        if (v == 1.0f)
-        {
-            fprintf(file, "1.0 ");
-        }
-        else if (v == 0.0)
-        {
-            fprintf(file, "0.0 ");
-        }
-        else
-        {
-            fprintf(file, "%f ",v);
-        }
-    }
-}
-void skipString(FILE* file)
-{
-    // get the size of the char array
-    unsigned int length = 0;
-    fread(&length, sizeof(unsigned int), 1, file);
-    // skip over the unsigned int length
-    fseek(file, sizeof(unsigned int), SEEK_CUR);
-    if (length > 0)
-    {
-        // Skip over the array of chars
-        long seek = (long)(length * sizeof(char));
-        fseek(file, seek, SEEK_CUR);
-    }
-}
-
-void skipUint(FILE* file)
-{
-    fseek(file, sizeof(unsigned int), SEEK_CUR);
-}
-
-void writeVectorBinary(const Vector2& v, FILE* file)
-{
-    write(v.x, file);
-    write(v.y, file);
-}
-
-void writeVectorText(const Vector2& v, FILE* file)
-{
-    fprintf(file, "%f %f\n", v.x, v.y);
-}
-
-void writeVectorBinary(const Vector3& v, FILE* file)
-{
-    write(v.x, file);
-    write(v.y, file);
-    write(v.z, file);
-}
-
-void writeVectorText(const Vector3& v, FILE* file)
-{
-    fprintf(file, "%f %f %f\n", v.x, v.y, v.z);
-}
-
-void writeVectorBinary(const Vector4& v, FILE* file)
-{
-    write(v.x, file);
-    write(v.y, file);
-    write(v.z, file);
-    write(v.w, file);
-}
-
-void writeVectorText(const Vector4& v, FILE* file)
-{
-    fprintf(file, "%f %f %f %f\n", v.x, v.y, v.z, v.w);
-}
-
-void writeIndent(unsigned int indentLevel, FILE* file)
-{
-    for (unsigned int i = 0; i < indentLevel; ++i)
-    {
-        fprintf(file, "    ");
-    }
-}
-
-bool promptUserGroupAnimations()
-{
-    char buffer[80];
-    for (;;)
-    {
-        printf("Do you want to group animations? (y/n)\n");
-        std::cin.getline(buffer, 80);
-        
-        if (buffer[0] == 'y' || buffer[0] == 'Y' || buffer[0] == '\0')
-        {
-            return true;
-        }
-        else if (buffer[0] == 'n' || buffer[0] == 'N')
-        {
-            return false;
-        }
-    }
-}
-
-}
+#include "Base.h"
+#include "FileIO.h"
+
+namespace gameplay
+{
+
+// Writing out a binary file //
+
+void write(unsigned char value, FILE* file)
+{
+    size_t r = fwrite(&value, sizeof(unsigned char), 1, file);
+    assert(r == 1);
+}
+
+void write(char value, FILE* file)
+{
+    size_t r = fwrite(&value, sizeof(char), 1, file);
+    assert(r == 1);
+}
+
+void write(const char* str, FILE* file)
+{
+    size_t length = strlen(str);
+    size_t r = fwrite(str, 1, length, file);
+    assert(r == length);
+}
+
+void write(unsigned int value, FILE* file)
+{
+    size_t r = fwrite(&value, sizeof(unsigned int), 1, file);
+    assert(r == 1);
+}
+
+void write(unsigned short value, FILE* file)
+{
+    size_t r = fwrite(&value, sizeof(unsigned short), 1, file);
+    assert(r == 1);
+}
+
+void write(bool value, FILE* file)
+{
+    // write booleans as a unsigned char
+    unsigned char b = value;
+    write(b, file);
+}
+void write(float value, FILE* file)
+{
+    fwrite(&value, sizeof(float), 1, file);
+}
+void write(const float* values, int length, FILE* file)
+{
+    for (int i = 0; i < length; ++i)
+    {
+        write(values[i], file);
+    }
+}
+void write(const std::string& str, FILE* file)
+{
+    // Write the length of the string
+    write((unsigned int)str.size(), file);
+    
+    if (str.size() > 0)
+    {
+        // Write the array of characters of the string
+        write(str.c_str(), file);
+    }
+}
+
+void writeZero(FILE* file)
+{
+    write((unsigned int)0, file);
+}
+
+// Writing to a text file //
+
+void fprintfElement(FILE* file, const char* elementName, const float values[], int length)
+{
+    fprintf(file, "<%s count=\"%d\">", elementName, length);
+    for (int i = 0; i < length; ++i)
+    {
+        fprintf(file, "%f ", values[i]);
+    }
+    fprintf(file, "</%s>\n", elementName);
+}
+void fprintfElement(FILE* file, const char* elementName, const char* value)
+{
+    fprintf(file, "<%s>%s</%s>\n", elementName, value, elementName);
+}
+void fprintfElement(FILE* file, const char* elementName, const std::string& value)
+{
+    fprintf(file, "<%s>%s</%s>\n", elementName, value.c_str(), elementName);
+}
+void fprintfElement(FILE* file, const char* elementName, float value)
+{
+    fprintf(file, "<%s>%f</%s>\n", elementName, value, elementName);
+}
+void fprintfElement(FILE* file, const char* elementName, unsigned int value)
+{
+    fprintf(file, "<%s>%u</%s>\n", elementName, value, elementName);
+}
+void fprintfElement(FILE* file, const char* elementName, unsigned char value)
+{
+    fprintf(file, "<%s>%u</%s>\n", elementName, value, elementName);
+}
+
+void fprintfMatrix4f(FILE* file, const float* m)
+{
+    for (size_t i = 0; i < 16; i ++)
+    {
+        float v = m[i];
+        if (v == 1.0f)
+        {
+            fprintf(file, "1.0 ");
+        }
+        else if (v == 0.0)
+        {
+            fprintf(file, "0.0 ");
+        }
+        else
+        {
+            fprintf(file, "%f ",v);
+        }
+    }
+}
+void skipString(FILE* file)
+{
+    // get the size of the char array
+    unsigned int length = 0;
+    fread(&length, sizeof(unsigned int), 1, file);
+    // skip over the unsigned int length
+    fseek(file, sizeof(unsigned int), SEEK_CUR);
+    if (length > 0)
+    {
+        // Skip over the array of chars
+        long seek = (long)(length * sizeof(char));
+        fseek(file, seek, SEEK_CUR);
+    }
+}
+
+void skipUint(FILE* file)
+{
+    fseek(file, sizeof(unsigned int), SEEK_CUR);
+}
+
+void writeVectorBinary(const Vector2& v, FILE* file)
+{
+    write(v.x, file);
+    write(v.y, file);
+}
+
+void writeVectorText(const Vector2& v, FILE* file)
+{
+    fprintf(file, "%f %f\n", v.x, v.y);
+}
+
+void writeVectorBinary(const Vector3& v, FILE* file)
+{
+    write(v.x, file);
+    write(v.y, file);
+    write(v.z, file);
+}
+
+void writeVectorText(const Vector3& v, FILE* file)
+{
+    fprintf(file, "%f %f %f\n", v.x, v.y, v.z);
+}
+
+void writeVectorBinary(const Vector4& v, FILE* file)
+{
+    write(v.x, file);
+    write(v.y, file);
+    write(v.z, file);
+    write(v.w, file);
+}
+
+void writeVectorText(const Vector4& v, FILE* file)
+{
+    fprintf(file, "%f %f %f %f\n", v.x, v.y, v.z, v.w);
+}
+
+void writeIndent(unsigned int indentLevel, FILE* file)
+{
+    for (unsigned int i = 0; i < indentLevel; ++i)
+    {
+        fprintf(file, "    ");
+    }
+}
+
+bool promptUserGroupAnimations()
+{
+    char buffer[80];
+    for (;;)
+    {
+        printf("Do you want to group animations? (y/n)\n");
+        std::cin.getline(buffer, 80);
+        
+        if (buffer[0] == 'y' || buffer[0] == 'Y' || buffer[0] == '\0')
+        {
+            return true;
+        }
+        else if (buffer[0] == 'n' || buffer[0] == 'N')
+        {
+            return false;
+        }
+    }
+}
+
+}

+ 155 - 155
tools/encoder/src/FileIO.h

@@ -1,155 +1,155 @@
-#ifndef FILEIO_H_
-#define FILEIO_H_
-
-#include <cstdio>
-#include <list>
-#include <vector>
-#include <cstring>
-#include <string>
-
-#include "Vector2.h"
-#include "Vector3.h"
-#include "Vector4.h"
-
-namespace gameplay
-{
-
-/**
- * Writes an XML element to the specified file stream.
- * 
- * @param file Pointer to a FILE object that identifies the stream.
- * @param elementName Name of the XML element to write.
- * @param value Value to write.
- */
-void fprintfElement(FILE* file, const char* elementName, float value);
-void fprintfElement(FILE* file, const char* elementName, unsigned int value);
-void fprintfElement(FILE* file, const char* elementName, unsigned char value);
-void fprintfElement(FILE* file, const char* elementName, const char* value);
-void fprintfElement(FILE* file, const char* elementName, const std::string& value);
-void fprintfElement(FILE* file, const char* elementName, const float values[], int length);
-
-template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T>& list)
-{
-    fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
-    typename std::vector<T>::const_iterator i;
-    for (i = list.begin(); i != list.end(); ++i)
-    {
-        fprintf(file, format, *i);
-    }
-    fprintf(file, "</%s>\n", elementName);
-}
-
-template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T>& list)
-{
-    fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
-    typename std::list<T>::const_iterator i;
-    for (i = list.begin(); i != list.end(); ++i)
-    {
-        fprintf(file, format, *i);
-    }
-    fprintf(file, "</%s>\n", elementName);
-}
-
-void fprintfMatrix4f(FILE* file, const float* m);
-
-/**
- * Writes binary data to the given file stream.
- * 
- * @param value The value to be written
- * @param file The binary file stream.
- */
-void write(unsigned char value, FILE* file);
-void write(char value, FILE* file);
-void write(const char* str, FILE* file);
-void write(unsigned int value, FILE* file);
-void write(unsigned short value, FILE* file);
-void write(bool value, FILE* file);
-void write(float value, FILE* file);
-void write(const float* values, int length, FILE* file);
-
-/**
- * Writes the length of the string and the string bytes to the binary file stream.
- */
-void write(const std::string& str, FILE* file);
-
-void writeZero(FILE* file);
-
-/**
- * Writes the length of the list and writes each element value to the binary file stream.
- * 
- * @param list The list to write.
- * @param file The binary file stream.
- */
-template <class T>
-void write(std::list<T> list, FILE* file)
-{
-    // First write the size of the list
-    write((unsigned int)list.size(), file);
-    // Then write each element
-    typename std::list<T>::const_iterator i;
-    for (i = list.begin(); i != list.end(); ++i)
-    {
-        write(*i, file);
-    }
-}
-
-/**
- * Writes the length of the vector and writes each element value to the binary file stream.
- * 
- * @param vector The vector to write.
- * @param file The binary file stream.
- */
-template <class T>
-void write(std::vector<T> vector, FILE* file)
-{
-    // First write the size of the vector
-    write((unsigned int)vector.size(), file);
-    // Then write each element
-    typename std::vector<T>::const_iterator i;
-    for (i = vector.begin(); i != vector.end(); ++i)
-    {
-        write(*i, file);
-    }
-}
-
-/**
- * Skips over the string at the current file stream offset by moving the file position.
- * Assumes the current position points to the unsigned int length of the string.
- * The string is assumed to be a char array.
- * 
- * @param file The file stream.
- */
-void skipString(FILE* file);
-
-void skipUint(FILE* file);
-
-void writeVectorBinary(const Vector2& v, FILE* file);
-
-void writeVectorText(const Vector2& v, FILE* file);
-
-void writeVectorBinary(const Vector3& v, FILE* file);
-
-void writeVectorText(const Vector3& v, FILE* file);
-
-void writeVectorBinary(const Vector4& v, FILE* file);
-
-void writeVectorText(const Vector4& v, FILE* file);
-
-/**
- * Writes a number of white space indentations to the file.
- */
-void writeIndent(unsigned int indentLevel, FILE* file);
-
-/**
- * Prompts the user if they want to group animations automatically.
- * If the user enters an invalid response, the question is asked again.
- * 
- * @return True if the user wants to group animations, false otherwise.
- */
-bool promptUserGroupAnimations();
-
-}
-
-#endif
+#ifndef FILEIO_H_
+#define FILEIO_H_
+
+#include <cstdio>
+#include <list>
+#include <vector>
+#include <cstring>
+#include <string>
+
+#include "Vector2.h"
+#include "Vector3.h"
+#include "Vector4.h"
+
+namespace gameplay
+{
+
+/**
+ * Writes an XML element to the specified file stream.
+ * 
+ * @param file Pointer to a FILE object that identifies the stream.
+ * @param elementName Name of the XML element to write.
+ * @param value Value to write.
+ */
+void fprintfElement(FILE* file, const char* elementName, float value);
+void fprintfElement(FILE* file, const char* elementName, unsigned int value);
+void fprintfElement(FILE* file, const char* elementName, unsigned char value);
+void fprintfElement(FILE* file, const char* elementName, const char* value);
+void fprintfElement(FILE* file, const char* elementName, const std::string& value);
+void fprintfElement(FILE* file, const char* elementName, const float values[], int length);
+
+template <class T>
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T>& list)
+{
+    fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
+    typename std::vector<T>::const_iterator i;
+    for (i = list.begin(); i != list.end(); ++i)
+    {
+        fprintf(file, format, *i);
+    }
+    fprintf(file, "</%s>\n", elementName);
+}
+
+template <class T>
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T>& list)
+{
+    fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
+    typename std::list<T>::const_iterator i;
+    for (i = list.begin(); i != list.end(); ++i)
+    {
+        fprintf(file, format, *i);
+    }
+    fprintf(file, "</%s>\n", elementName);
+}
+
+void fprintfMatrix4f(FILE* file, const float* m);
+
+/**
+ * Writes binary data to the given file stream.
+ * 
+ * @param value The value to be written
+ * @param file The binary file stream.
+ */
+void write(unsigned char value, FILE* file);
+void write(char value, FILE* file);
+void write(const char* str, FILE* file);
+void write(unsigned int value, FILE* file);
+void write(unsigned short value, FILE* file);
+void write(bool value, FILE* file);
+void write(float value, FILE* file);
+void write(const float* values, int length, FILE* file);
+
+/**
+ * Writes the length of the string and the string bytes to the binary file stream.
+ */
+void write(const std::string& str, FILE* file);
+
+void writeZero(FILE* file);
+
+/**
+ * Writes the length of the list and writes each element value to the binary file stream.
+ * 
+ * @param list The list to write.
+ * @param file The binary file stream.
+ */
+template <class T>
+void write(std::list<T> list, FILE* file)
+{
+    // First write the size of the list
+    write((unsigned int)list.size(), file);
+    // Then write each element
+    typename std::list<T>::const_iterator i;
+    for (i = list.begin(); i != list.end(); ++i)
+    {
+        write(*i, file);
+    }
+}
+
+/**
+ * Writes the length of the vector and writes each element value to the binary file stream.
+ * 
+ * @param vector The vector to write.
+ * @param file The binary file stream.
+ */
+template <class T>
+void write(std::vector<T> vector, FILE* file)
+{
+    // First write the size of the vector
+    write((unsigned int)vector.size(), file);
+    // Then write each element
+    typename std::vector<T>::const_iterator i;
+    for (i = vector.begin(); i != vector.end(); ++i)
+    {
+        write(*i, file);
+    }
+}
+
+/**
+ * Skips over the string at the current file stream offset by moving the file position.
+ * Assumes the current position points to the unsigned int length of the string.
+ * The string is assumed to be a char array.
+ * 
+ * @param file The file stream.
+ */
+void skipString(FILE* file);
+
+void skipUint(FILE* file);
+
+void writeVectorBinary(const Vector2& v, FILE* file);
+
+void writeVectorText(const Vector2& v, FILE* file);
+
+void writeVectorBinary(const Vector3& v, FILE* file);
+
+void writeVectorText(const Vector3& v, FILE* file);
+
+void writeVectorBinary(const Vector4& v, FILE* file);
+
+void writeVectorText(const Vector4& v, FILE* file);
+
+/**
+ * Writes a number of white space indentations to the file.
+ */
+void writeIndent(unsigned int indentLevel, FILE* file);
+
+/**
+ * Prompts the user if they want to group animations automatically.
+ * If the user enters an invalid response, the question is asked again.
+ * 
+ * @return True if the user wants to group animations, false otherwise.
+ */
+bool promptUserGroupAnimations();
+
+}
+
+#endif

+ 52 - 52
tools/encoder/src/Font.cpp

@@ -1,52 +1,52 @@
-#include "Base.h"
-#include "Font.h"
-
-namespace gameplay
-{
-
-Font::Font(void) :
-    style(0),
-    size(0),
-    texMapWidth(0),
-    texMapHeight(0)
-{
-}
-
-Font::~Font(void)
-{
-}
-
-unsigned int Font::getTypeId(void) const
-{
-    return FONT_ID;
-}
-const char* Font::getElementName(void) const
-{
-    return "Font";
-}
-
-void Font::writeBinary(FILE* file)
-{
-    Object::writeBinary(file);
-    write(family, file);
-    write(style, file);
-    write(size, file);
-    write(charset, file);
-    writeBinaryObjects(glyphs, file);
-    write(texMapWidth, file);
-    write(texMapHeight, file);
-    write(texMap, file);
-}
-void Font::writeText(FILE* file)
-{
-    fprintElementStart(file);
-    fprintfElement(file, "family", family);
-    fprintfElement(file, "style", style);
-    fprintfElement(file, "size", size);
-    fprintfElement(file, "alphabet", charset);
-    fprintfElement(file, "texMapWidth", texMapWidth);
-    fprintfElement(file, "texMapHeight", texMapHeight);
-    fprintElementEnd(file);
-}
-
-}
+#include "Base.h"
+#include "Font.h"
+
+namespace gameplay
+{
+
+Font::Font(void) :
+    style(0),
+    size(0),
+    texMapWidth(0),
+    texMapHeight(0)
+{
+}
+
+Font::~Font(void)
+{
+}
+
+unsigned int Font::getTypeId(void) const
+{
+    return FONT_ID;
+}
+const char* Font::getElementName(void) const
+{
+    return "Font";
+}
+
+void Font::writeBinary(FILE* file)
+{
+    Object::writeBinary(file);
+    write(family, file);
+    write(style, file);
+    write(size, file);
+    write(charset, file);
+    writeBinaryObjects(glyphs, file);
+    write(texMapWidth, file);
+    write(texMapHeight, file);
+    write(texMap, file);
+}
+void Font::writeText(FILE* file)
+{
+    fprintElementStart(file);
+    fprintfElement(file, "family", family);
+    fprintfElement(file, "style", style);
+    fprintfElement(file, "size", size);
+    fprintfElement(file, "alphabet", charset);
+    fprintfElement(file, "texMapWidth", texMapWidth);
+    fprintfElement(file, "texMapHeight", texMapHeight);
+    fprintElementEnd(file);
+}
+
+}

+ 56 - 56
tools/encoder/src/Font.h

@@ -1,56 +1,56 @@
-#ifndef FONT_H_
-#define FONT_H_
-
-#include "Object.h"
-#include "Glyph.h"
-
-namespace gameplay
-{
-
-class Font : public Object
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    Font(void);
-
-    /**
-     * Destructor.
-     */
-    virtual ~Font(void);
-
-    virtual unsigned int getTypeId(void) const;
-    virtual const char* getElementName(void) const;
-    virtual void writeBinary(FILE* file);
-    virtual void writeText(FILE* file);
-
-    std::string family;
-    unsigned int style;
-    unsigned int size;
-    std::string  charset;
-    std::list<Glyph*> glyphs;
-    unsigned int texMapWidth;
-    unsigned int texMapHeight;
-    std::list<unsigned char> texMap;
-
-    enum FontStyle
-    {
-        PLAIN = 0,
-        BOLD = 1,
-        ITALIC = 2,
-        BOLD_ITALIC = 4
-    };
-
-
-    enum FontFormat
-    {
-        BITMAP = 0,
-        DISTANCE_FIELD = 1
-    };
-};
-
-}
-
-#endif
+#ifndef FONT_H_
+#define FONT_H_
+
+#include "Object.h"
+#include "Glyph.h"
+
+namespace gameplay
+{
+
+class Font : public Object
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Font(void);
+
+    /**
+     * Destructor.
+     */
+    virtual ~Font(void);
+
+    virtual unsigned int getTypeId(void) const;
+    virtual const char* getElementName(void) const;
+    virtual void writeBinary(FILE* file);
+    virtual void writeText(FILE* file);
+
+    std::string family;
+    unsigned int style;
+    unsigned int size;
+    std::string  charset;
+    std::list<Glyph*> glyphs;
+    unsigned int texMapWidth;
+    unsigned int texMapHeight;
+    std::list<unsigned char> texMap;
+
+    enum FontStyle
+    {
+        PLAIN = 0,
+        BOLD = 1,
+        ITALIC = 2,
+        BOLD_ITALIC = 4
+    };
+
+
+    enum FontFormat
+    {
+        BITMAP = 0,
+        DISTANCE_FIELD = 1
+    };
+};
+
+}
+
+#endif

+ 118 - 118
tools/encoder/src/GPBDecoder.cpp

@@ -1,118 +1,118 @@
-#include "Base.h"
-#include "GPBDecoder.h"
-
-namespace gameplay
-{
-
-GPBDecoder::GPBDecoder(void) : _file(NULL), _outFile(NULL)
-{
-}
-
-
-GPBDecoder::~GPBDecoder(void)
-{
-}
-
-void GPBDecoder::readBinary(const std::string& filepath)
-{
-    // open files
-    _file = fopen(filepath.c_str(), "rb");
-    std::string outfilePath = filepath;
-    outfilePath += ".xml";
-    _outFile = fopen(outfilePath.c_str(), "w");
-
-    // read and write files
-    assert(validateHeading());
-
-    fprintf(_outFile, "<root>\n");
-    readRefs();
-    fprintf(_outFile, "</root>\n");
-
-
-    // close files
-    fclose(_outFile);
-    _outFile = NULL;
-
-    fclose(_file);
-    _file = NULL;
-}
-
-bool GPBDecoder::validateHeading()
-{
-    const size_t HEADING_SIZE = 9;
-    const char identifier[] = "\xABGPB\xBB\r\n\x1A\n";
-
-    char heading[HEADING_SIZE];
-    fread(heading, sizeof(unsigned char), HEADING_SIZE, _file);
-    for (size_t i = 0; i < HEADING_SIZE; ++i)
-    {
-        if (heading[i] != identifier[i])
-        {
-            return false;
-        }
-    }
-    // read version
-    unsigned char version[2];
-    fread(version, sizeof(unsigned char), 2, _file);
-    // don't care about version
-
-    return true;
-}
-
-void GPBDecoder::readRefs()
-{
-    fprintf(_outFile, "<RefTable>\n");
-    // read number of refs
-    unsigned int refCount = 0;
-    assert(read(&refCount));
-    for (size_t i = 0; i < refCount; ++i)
-    {
-        readRef();
-    }
-    fprintf(_outFile, "</RefTable>\n");
-}
-
-void GPBDecoder::readRef()
-{
-    std::string xref = readString(_file);
-    unsigned int type = 0, offset = 0;
-    assert(read(&type));
-    assert(read(&offset));
-    
-    fprintf(_outFile, "<Reference>\n");
-    fprintfElement(_outFile, "xref", xref);
-    fprintfElement(_outFile, "type", type);
-    fprintfElement(_outFile, "offset", offset);
-    fprintf(_outFile, "</Reference>\n");
-}
-
-bool GPBDecoder::read(unsigned int* ptr)
-{
-    return fread(ptr, sizeof(unsigned int), 1, _file) == 1;
-}
-
-std::string GPBDecoder::readString(FILE* fp)
-{
-    unsigned int length;
-    if (fread(&length, 4, 1, fp) != 1)
-    {
-        return std::string();
-    }
-
-    char* str = new char[length + 1];
-    if (length > 0)
-    {
-        if (fread(str, 1, length, fp) != length)
-        {
-            delete[] str;
-            return std::string();
-        }
-    }
-
-    str[length] = '\0';
-    std::string result(str);
-    delete[] str;
-    return result;
-}
-
-}
+#include "Base.h"
+#include "GPBDecoder.h"
+
+namespace gameplay
+{
+
+GPBDecoder::GPBDecoder(void) : _file(NULL), _outFile(NULL)
+{
+}
+
+
+GPBDecoder::~GPBDecoder(void)
+{
+}
+
+void GPBDecoder::readBinary(const std::string& filepath)
+{
+    // open files
+    _file = fopen(filepath.c_str(), "rb");
+    std::string outfilePath = filepath;
+    outfilePath += ".xml";
+    _outFile = fopen(outfilePath.c_str(), "w");
+
+    // read and write files
+    assert(validateHeading());
+
+    fprintf(_outFile, "<root>\n");
+    readRefs();
+    fprintf(_outFile, "</root>\n");
+
+
+    // close files
+    fclose(_outFile);
+    _outFile = NULL;
+
+    fclose(_file);
+    _file = NULL;
+}
+
+bool GPBDecoder::validateHeading()
+{
+    const size_t HEADING_SIZE = 9;
+    const char identifier[] = "\xABGPB\xBB\r\n\x1A\n";
+
+    char heading[HEADING_SIZE];
+    fread(heading, sizeof(unsigned char), HEADING_SIZE, _file);
+    for (size_t i = 0; i < HEADING_SIZE; ++i)
+    {
+        if (heading[i] != identifier[i])
+        {
+            return false;
+        }
+    }
+    // read version
+    unsigned char version[2];
+    fread(version, sizeof(unsigned char), 2, _file);
+    // don't care about version
+
+    return true;
+}
+
+void GPBDecoder::readRefs()
+{
+    fprintf(_outFile, "<RefTable>\n");
+    // read number of refs
+    unsigned int refCount = 0;
+    assert(read(&refCount));
+    for (size_t i = 0; i < refCount; ++i)
+    {
+        readRef();
+    }
+    fprintf(_outFile, "</RefTable>\n");
+}
+
+void GPBDecoder::readRef()
+{
+    std::string xref = readString(_file);
+    unsigned int type = 0, offset = 0;
+    assert(read(&type));
+    assert(read(&offset));
+    
+    fprintf(_outFile, "<Reference>\n");
+    fprintfElement(_outFile, "xref", xref);
+    fprintfElement(_outFile, "type", type);
+    fprintfElement(_outFile, "offset", offset);
+    fprintf(_outFile, "</Reference>\n");
+}
+
+bool GPBDecoder::read(unsigned int* ptr)
+{
+    return fread(ptr, sizeof(unsigned int), 1, _file) == 1;
+}
+
+std::string GPBDecoder::readString(FILE* fp)
+{
+    unsigned int length;
+    if (fread(&length, 4, 1, fp) != 1)
+    {
+        return std::string();
+    }
+
+    char* str = new char[length + 1];
+    if (length > 0)
+    {
+        if (fread(str, 1, length, fp) != length)
+        {
+            delete[] str;
+            return std::string();
+        }
+    }
+
+    str[length] = '\0';
+    std::string result(str);
+    delete[] str;
+    return result;
+}
+
+}

+ 42 - 42
tools/encoder/src/GPBDecoder.h

@@ -1,42 +1,42 @@
-#ifndef GPBDECODER_H_
-#define GPBDECODER_H_
-
-#include "FileIO.h"
-
-namespace gameplay
-{
-/**
- * This class is used for decoding a GPB file for the purpose of debugging.
- */
-class GPBDecoder
-{
-public:
-
-    /**
-     * Constructor.
-     */
-    GPBDecoder(void);
-
-    /**
-     * Destructor.
-     */
-    ~GPBDecoder(void);
-
-    void readBinary(const std::string& filepath);
-    bool validateHeading();
-
-    void readRefs();
-    void readRef();
-
-    bool read(unsigned int* ptr);
-    std::string readString(FILE* fp);
-
-private:
-
-    FILE* _file;
-    FILE* _outFile;
-};
-
-}
-
-#endif
+#ifndef GPBDECODER_H_
+#define GPBDECODER_H_
+
+#include "FileIO.h"
+
+namespace gameplay
+{
+/**
+ * This class is used for decoding a GPB file for the purpose of debugging.
+ */
+class GPBDecoder
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    GPBDecoder(void);
+
+    /**
+     * Destructor.
+     */
+    ~GPBDecoder(void);
+
+    void readBinary(const std::string& filepath);
+    bool validateHeading();
+
+    void readRefs();
+    void readRef();
+
+    bool read(unsigned int* ptr);
+    std::string readString(FILE* fp);
+
+private:
+
+    FILE* _file;
+    FILE* _outFile;
+};
+
+}
+
+#endif