2
0
Эх сурвалжийг харах

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-cculy

Conflicts:
	gameplay-samples/sample00-mesh/.cproject
	gameplay-samples/sample00-mesh/sample00-mesh.vcxproj
	gameplay-samples/sample01-longboard/.cproject
	gameplay-samples/sample01-longboard/sample01-longboard.vcxproj
	gameplay-samples/sample02-spaceship/.cproject
	gameplay-samples/sample02-spaceship/sample02-spaceship.vcxproj
	gameplay-samples/sample03-character/.cproject
	gameplay-samples/sample03-character/sample03-character.vcxproj
	gameplay/gameplay.vcxproj
	gameplay/gameplay.vcxproj.filters
	gameplay/src/AudioController.cpp
	gameplay/src/Base.h
	gameplay/src/Game.cpp
	gameplay/src/Game.h
	gameplay/src/MeshSkin.cpp
	gameplay/src/Model.cpp
	gameplay/src/Node.cpp
Chris Culy 14 жил өмнө
parent
commit
f81631ed7c
100 өөрчлөгдсөн 4151 нэмэгдсэн , 714 устгасан
  1. 6 0
      .gitignore
  2. 4 4
      gameplay-encoder/gameplay-encoder.vcxproj
  3. 546 0
      gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj
  4. 32 18
      gameplay-encoder/src/Base.h
  5. 1 1
      gameplay-encoder/src/DAEOptimizer.cpp
  6. 17 4
      gameplay-encoder/src/DAESceneEncoder.cpp
  7. 1 1
      gameplay-encoder/src/DAEUtil.cpp
  8. 2 8
      gameplay-encoder/src/EncoderArguments.h
  9. 3 3
      gameplay-encoder/src/FileIO.cpp
  10. 4 8
      gameplay-encoder/src/FileIO.h
  11. 2 2
      gameplay-encoder/src/Light.cpp
  12. 2 3
      gameplay-encoder/src/Mesh.cpp
  13. 1 0
      gameplay-encoder/src/Mesh.h
  14. 1 1
      gameplay-encoder/src/MeshSkin.cpp
  15. 2 1
      gameplay-encoder/src/MeshSubSet.cpp
  16. 10 7
      gameplay-encoder/src/MeshSubSet.h
  17. 2 7
      gameplay-encoder/src/Object.h
  18. 15 0
      gameplay.sln
  19. 22 0
      gameplay.xcworkspace/contents.xcworkspacedata
  20. 53 5
      gameplay/gameplay.vcxproj
  21. 42 9
      gameplay/gameplay.vcxproj.filters
  22. 717 0
      gameplay/gameplay.xcodeproj/project.pbxproj
  23. 18 15
      gameplay/res/shaders/bumped-specular.fsh
  24. 180 37
      gameplay/res/shaders/bumped-specular.vsh
  25. 21 17
      gameplay/res/shaders/bumped.fsh
  26. 154 17
      gameplay/res/shaders/bumped.vsh
  27. 12 7
      gameplay/res/shaders/colored-specular.fsh
  28. 14 4
      gameplay/res/shaders/colored-specular.vsh
  29. 20 15
      gameplay/res/shaders/colored.fsh
  30. 10 5
      gameplay/res/shaders/colored.vsh
  31. 12 7
      gameplay/res/shaders/diffuse-specular.fsh
  32. 21 12
      gameplay/res/shaders/diffuse-specular.vsh
  33. 21 17
      gameplay/res/shaders/diffuse.fsh
  34. 10 3
      gameplay/res/shaders/diffuse.vsh
  35. 140 28
      gameplay/res/shaders/parallax-specular.fsh
  36. 100 25
      gameplay/res/shaders/parallax-specular.vsh
  37. 132 21
      gameplay/res/shaders/parallax.fsh
  38. 98 23
      gameplay/res/shaders/parallax.vsh
  39. 4 2
      gameplay/res/shaders/solid.fsh
  40. 1 1
      gameplay/res/shaders/solid.vsh
  41. 2 0
      gameplay/res/shaders/textured.fsh
  42. 0 2
      gameplay/src/Animation.cpp
  43. 10 25
      gameplay/src/AnimationClip.cpp
  44. 3 2
      gameplay/src/AnimationController.cpp
  45. 144 10
      gameplay/src/AudioBuffer.cpp
  46. 4 0
      gameplay/src/AudioBuffer.h
  47. 34 8
      gameplay/src/AudioController.cpp
  48. 2 1
      gameplay/src/AudioController.h
  49. 1 2
      gameplay/src/AudioSource.cpp
  50. 56 16
      gameplay/src/Base.h
  51. 19 0
      gameplay/src/BoundingBox.h
  52. 23 0
      gameplay/src/BoundingBox.inl
  53. 19 0
      gameplay/src/BoundingSphere.h
  54. 23 0
      gameplay/src/BoundingSphere.inl
  55. 1 6
      gameplay/src/Camera.cpp
  56. 2 1
      gameplay/src/Curve.cpp
  57. 162 0
      gameplay/src/DebugNew.cpp
  58. 42 0
      gameplay/src/DebugNew.h
  59. 17 3
      gameplay/src/Effect.cpp
  60. 3 2
      gameplay/src/FileSystem.cpp
  61. 22 20
      gameplay/src/Font.cpp
  62. 40 19
      gameplay/src/Game.cpp
  63. 5 9
      gameplay/src/Game.h
  64. 2 2
      gameplay/src/Joint.cpp
  65. 22 13
      gameplay/src/Light.cpp
  66. 9 0
      gameplay/src/Light.h
  67. 2 0
      gameplay/src/MaterialParameter.h
  68. 25 18
      gameplay/src/Matrix.cpp
  69. 136 19
      gameplay/src/Matrix.h
  70. 82 0
      gameplay/src/Matrix.inl
  71. 0 12
      gameplay/src/MeshSkin.cpp
  72. 3 6
      gameplay/src/Model.cpp
  73. 25 37
      gameplay/src/Node.cpp
  74. 0 21
      gameplay/src/Node.h
  75. 6 0
      gameplay/src/Package.cpp
  76. 10 23
      gameplay/src/ParticleEmitter.cpp
  77. 2 2
      gameplay/src/PhysicsController.cpp
  78. 3 3
      gameplay/src/PhysicsRigidBody.cpp
  79. 1 2
      gameplay/src/PhysicsRigidBody.h
  80. 1 1
      gameplay/src/Plane.cpp
  81. 20 1
      gameplay/src/Plane.h
  82. 23 0
      gameplay/src/Plane.inl
  83. 5 5
      gameplay/src/Platform.h
  84. 335 0
      gameplay/src/PlatformMacOSX.mm
  85. 1 1
      gameplay/src/PlatformQNX.cpp
  86. 2 3
      gameplay/src/Properties.cpp
  87. 1 0
      gameplay/src/Properties.h
  88. 19 11
      gameplay/src/Quaternion.cpp
  89. 42 0
      gameplay/src/Quaternion.h
  90. 23 0
      gameplay/src/Quaternion.inl
  91. 19 0
      gameplay/src/Ray.h
  92. 23 0
      gameplay/src/Ray.inl
  93. 86 0
      gameplay/src/Ref.cpp
  94. 14 0
      gameplay/src/Ref.h
  95. 44 31
      gameplay/src/RenderState.cpp
  96. 12 3
      gameplay/src/RenderState.h
  97. 34 4
      gameplay/src/Scene.cpp
  98. 24 22
      gameplay/src/SpriteBatch.cpp
  99. 0 2
      gameplay/src/Texture.h
  100. 8 8
      gameplay/src/Vector2.cpp

+ 6 - 0
.gitignore

@@ -14,6 +14,7 @@
 /Device-Profile
 /Device-Release
 /gameplay/Debug
+/gameplay/DebugMem
 /gameplay/Release
 /gameplay/Simulator
 /gameplay/Simulator-Coverage
@@ -25,6 +26,7 @@
 /gameplay-encoder/Debug
 /gameplay-encoder/Release
 /gameplay-samples/sample00-mesh/Debug
+/gameplay-samples/sample00-mesh/DebugMem
 /gameplay-samples/sample00-mesh/Release
 /gameplay-samples/sample00-mesh/Simulator
 /gameplay-samples/sample00-mesh/Simulator-Coverage
@@ -34,6 +36,7 @@
 /gameplay-samples/sample00-mesh/Device-Profile
 /gameplay-samples/sample00-mesh/Device-Release
 /gameplay-samples/sample01-longboard/Debug
+/gameplay-samples/sample01-longboard/DebugMem
 /gameplay-samples/sample01-longboard/Release
 /gameplay-samples/sample01-longboard/Simulator
 /gameplay-samples/sample01-longboard/Simulator-Coverage
@@ -43,6 +46,7 @@
 /gameplay-samples/sample01-longboard/Device-Profile
 /gameplay-samples/sample01-longboard/Device-Release
 /gameplay-samples/sample02-spaceship/Debug
+/gameplay-samples/sample02-spaceship/DebugMem
 /gameplay-samples/sample02-spaceship/Release
 /gameplay-samples/sample02-spaceship/Simulator
 /gameplay-samples/sample02-spaceship/Simulator-Coverage
@@ -52,6 +56,7 @@
 /gameplay-samples/sample02-spaceship/Device-Profile
 /gameplay-samples/sample02-spaceship/Device-Release
 /gameplay-samples/sample03-character/Debug
+/gameplay-samples/sample03-character/DebugMem
 /gameplay-samples/sample03-character/Release
 /gameplay-samples/sample03-character/Simulator
 /gameplay-samples/sample03-character/Simulator-Coverage
@@ -61,6 +66,7 @@
 /gameplay-samples/sample03-character/Device-Profile
 /gameplay-samples/sample03-character/Device-Release
 /gameplay-samples/sample04-sandbox/Debug
+/gameplay-samples/sample04-sandbox/DebugMem
 /gameplay-samples/sample04-sandbox/Release
 /gameplay-samples/sample04-sandbox/Simulator
 /gameplay-samples/sample04-sandbox/Simulator-Coverage

+ 4 - 4
gameplay-encoder/gameplay-encoder.vcxproj

@@ -144,11 +144,11 @@
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>;../external-deps/freetype2/lib;../external-deps/collada-dom/lib</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <PostBuildEvent>
-      <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\*.dll" "$(TargetDir)"</Command>
+      <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\win32\*.dll" "$(TargetDir)"</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -168,10 +168,10 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>;../external-deps/freetype2/lib;../external-deps/collada-dom/lib</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
-      <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\*.dll" "$(TargetDir)"</Command>
+      <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\win32\*.dll" "$(TargetDir)"</Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 546 - 0
gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj

@@ -0,0 +1,546 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		42475D7C14720ECE00610A6A /* libdom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42475D7B14720ECE00610A6A /* libdom.a */; };
+		42C8EE0A14724CD700E43619 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDB714724CD700E43619 /* Animation.cpp */; };
+		42C8EE0B14724CD700E43619 /* AnimationChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDB914724CD700E43619 /* AnimationChannel.cpp */; };
+		42C8EE0C14724CD700E43619 /* Animations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDBB14724CD700E43619 /* Animations.cpp */; };
+		42C8EE0D14724CD700E43619 /* Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDBD14724CD700E43619 /* Base.cpp */; };
+		42C8EE0E14724CD700E43619 /* Camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDBF14724CD700E43619 /* Camera.cpp */; };
+		42C8EE0F14724CD700E43619 /* CameraInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDC114724CD700E43619 /* CameraInstance.cpp */; };
+		42C8EE1014724CD700E43619 /* DAEChannelTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDC314724CD700E43619 /* DAEChannelTarget.cpp */; };
+		42C8EE1114724CD700E43619 /* DAEOptimizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDC514724CD700E43619 /* DAEOptimizer.cpp */; };
+		42C8EE1214724CD700E43619 /* DAESceneEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDC714724CD700E43619 /* DAESceneEncoder.cpp */; };
+		42C8EE1314724CD700E43619 /* DAEUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDC914724CD700E43619 /* DAEUtil.cpp */; };
+		42C8EE1414724CD700E43619 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDCB14724CD700E43619 /* Effect.cpp */; };
+		42C8EE1514724CD700E43619 /* EncoderArguments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDCD14724CD700E43619 /* EncoderArguments.cpp */; };
+		42C8EE1614724CD700E43619 /* FileIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDCF14724CD700E43619 /* FileIO.cpp */; };
+		42C8EE1714724CD700E43619 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDD114724CD700E43619 /* Font.cpp */; };
+		42C8EE1814724CD700E43619 /* Glyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDD314724CD700E43619 /* Glyph.cpp */; };
+		42C8EE1914724CD700E43619 /* GPBDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDD514724CD700E43619 /* GPBDecoder.cpp */; };
+		42C8EE1A14724CD700E43619 /* GPBFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDD714724CD700E43619 /* GPBFile.cpp */; };
+		42C8EE1B14724CD700E43619 /* Light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDD914724CD700E43619 /* Light.cpp */; };
+		42C8EE1C14724CD700E43619 /* LightInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDDB14724CD700E43619 /* LightInstance.cpp */; };
+		42C8EE1D14724CD700E43619 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDDD14724CD700E43619 /* main.cpp */; };
+		42C8EE1E14724CD700E43619 /* Material.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDDE14724CD700E43619 /* Material.cpp */; };
+		42C8EE1F14724CD700E43619 /* MaterialParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDE014724CD700E43619 /* MaterialParameter.cpp */; };
+		42C8EE2014724CD700E43619 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDE214724CD700E43619 /* Matrix.cpp */; };
+		42C8EE2114724CD700E43619 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDE414724CD700E43619 /* Mesh.cpp */; };
+		42C8EE2214724CD700E43619 /* MeshPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDE614724CD700E43619 /* MeshPart.cpp */; };
+		42C8EE2314724CD700E43619 /* MeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDE814724CD700E43619 /* MeshSkin.cpp */; };
+		42C8EE2414724CD700E43619 /* MeshSubSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDEA14724CD700E43619 /* MeshSubSet.cpp */; };
+		42C8EE2514724CD700E43619 /* Model.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDEC14724CD700E43619 /* Model.cpp */; };
+		42C8EE2614724CD700E43619 /* Node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDEE14724CD700E43619 /* Node.cpp */; };
+		42C8EE2714724CD700E43619 /* Object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDF014724CD700E43619 /* Object.cpp */; };
+		42C8EE2814724CD700E43619 /* Quaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDF214724CD700E43619 /* Quaternion.cpp */; };
+		42C8EE2914724CD700E43619 /* Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDF414724CD700E43619 /* Reference.cpp */; };
+		42C8EE2A14724CD700E43619 /* ReferenceTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDF614724CD700E43619 /* ReferenceTable.cpp */; };
+		42C8EE2B14724CD700E43619 /* Scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDF814724CD700E43619 /* Scene.cpp */; };
+		42C8EE2C14724CD700E43619 /* StringUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDFA14724CD700E43619 /* StringUtil.cpp */; };
+		42C8EE2D14724CD700E43619 /* Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDFC14724CD700E43619 /* Transform.cpp */; };
+		42C8EE2E14724CD700E43619 /* TTFFontEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDFE14724CD700E43619 /* TTFFontEncoder.cpp */; };
+		42C8EE2F14724CD700E43619 /* Vector2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EE0014724CD700E43619 /* Vector2.cpp */; };
+		42C8EE3014724CD700E43619 /* Vector3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EE0214724CD700E43619 /* Vector3.cpp */; };
+		42C8EE3114724CD700E43619 /* Vector4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EE0414724CD700E43619 /* Vector4.cpp */; };
+		42C8EE3214724CD700E43619 /* Vertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EE0614724CD700E43619 /* Vertex.cpp */; };
+		42C8EE3314724CD700E43619 /* VertexElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EE0814724CD700E43619 /* VertexElement.cpp */; };
+		42C8EE351472B60100E43619 /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C8EE341472B60100E43619 /* libfreetype.a */; };
+		42C8EE371472D7E700E43619 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C8EE361472D7E700E43619 /* libxml2.dylib */; };
+		42C8EE391472DAA300E43619 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C8EE381472DAA300E43619 /* libz.dylib */; };
+		42C8EE3B1472DAAE00E43619 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C8EE3A1472DAAE00E43619 /* libbz2.dylib */; };
+		42D277591472EFA700D867A4 /* libpcre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277571472EFA700D867A4 /* libpcre.a */; };
+		42D2775A1472EFA700D867A4 /* libpcrecpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277581472EFA700D867A4 /* libpcrecpp.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		42475CE4147208A000610A6A /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		42475CE6147208A000610A6A /* gameplay-encoder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gameplay-encoder"; sourceTree = BUILT_PRODUCTS_DIR; };
+		42475D7B14720ECE00610A6A /* libdom.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdom.a; path = "../external-deps/collada-dom/lib/macosx/libdom.a"; sourceTree = "<group>"; };
+		42C8EDB714724CD700E43619 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animation.cpp; path = src/Animation.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDB814724CD700E43619 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = src/Animation.h; sourceTree = SOURCE_ROOT; };
+		42C8EDB914724CD700E43619 /* AnimationChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationChannel.cpp; path = src/AnimationChannel.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDBA14724CD700E43619 /* AnimationChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationChannel.h; path = src/AnimationChannel.h; sourceTree = SOURCE_ROOT; };
+		42C8EDBB14724CD700E43619 /* Animations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animations.cpp; path = src/Animations.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDBC14724CD700E43619 /* Animations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animations.h; path = src/Animations.h; sourceTree = SOURCE_ROOT; };
+		42C8EDBD14724CD700E43619 /* Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Base.cpp; path = src/Base.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDBE14724CD700E43619 /* Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Base.h; path = src/Base.h; sourceTree = SOURCE_ROOT; };
+		42C8EDBF14724CD700E43619 /* Camera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Camera.cpp; path = src/Camera.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDC014724CD700E43619 /* Camera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Camera.h; path = src/Camera.h; sourceTree = SOURCE_ROOT; };
+		42C8EDC114724CD700E43619 /* CameraInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CameraInstance.cpp; path = src/CameraInstance.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDC214724CD700E43619 /* CameraInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CameraInstance.h; path = src/CameraInstance.h; sourceTree = SOURCE_ROOT; };
+		42C8EDC314724CD700E43619 /* DAEChannelTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DAEChannelTarget.cpp; path = src/DAEChannelTarget.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDC414724CD700E43619 /* DAEChannelTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DAEChannelTarget.h; path = src/DAEChannelTarget.h; sourceTree = SOURCE_ROOT; };
+		42C8EDC514724CD700E43619 /* DAEOptimizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DAEOptimizer.cpp; path = src/DAEOptimizer.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDC614724CD700E43619 /* DAEOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DAEOptimizer.h; path = src/DAEOptimizer.h; sourceTree = SOURCE_ROOT; };
+		42C8EDC714724CD700E43619 /* DAESceneEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DAESceneEncoder.cpp; path = src/DAESceneEncoder.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDC814724CD700E43619 /* DAESceneEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DAESceneEncoder.h; path = src/DAESceneEncoder.h; sourceTree = SOURCE_ROOT; };
+		42C8EDC914724CD700E43619 /* DAEUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DAEUtil.cpp; path = src/DAEUtil.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDCA14724CD700E43619 /* DAEUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DAEUtil.h; path = src/DAEUtil.h; sourceTree = SOURCE_ROOT; };
+		42C8EDCB14724CD700E43619 /* Effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Effect.cpp; path = src/Effect.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDCC14724CD700E43619 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Effect.h; path = src/Effect.h; sourceTree = SOURCE_ROOT; };
+		42C8EDCD14724CD700E43619 /* EncoderArguments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EncoderArguments.cpp; path = src/EncoderArguments.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDCE14724CD700E43619 /* EncoderArguments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EncoderArguments.h; path = src/EncoderArguments.h; sourceTree = SOURCE_ROOT; };
+		42C8EDCF14724CD700E43619 /* FileIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileIO.cpp; path = src/FileIO.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDD014724CD700E43619 /* FileIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileIO.h; path = src/FileIO.h; sourceTree = SOURCE_ROOT; };
+		42C8EDD114724CD700E43619 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Font.cpp; path = src/Font.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDD214724CD700E43619 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Font.h; path = src/Font.h; sourceTree = SOURCE_ROOT; };
+		42C8EDD314724CD700E43619 /* Glyph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Glyph.cpp; path = src/Glyph.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDD414724CD700E43619 /* Glyph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Glyph.h; path = src/Glyph.h; sourceTree = SOURCE_ROOT; };
+		42C8EDD514724CD700E43619 /* GPBDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GPBDecoder.cpp; path = src/GPBDecoder.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDD614724CD700E43619 /* GPBDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPBDecoder.h; path = src/GPBDecoder.h; sourceTree = SOURCE_ROOT; };
+		42C8EDD714724CD700E43619 /* GPBFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GPBFile.cpp; path = src/GPBFile.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDD814724CD700E43619 /* GPBFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPBFile.h; path = src/GPBFile.h; sourceTree = SOURCE_ROOT; };
+		42C8EDD914724CD700E43619 /* Light.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Light.cpp; path = src/Light.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDDA14724CD700E43619 /* Light.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Light.h; path = src/Light.h; sourceTree = SOURCE_ROOT; };
+		42C8EDDB14724CD700E43619 /* LightInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LightInstance.cpp; path = src/LightInstance.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDDC14724CD700E43619 /* LightInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LightInstance.h; path = src/LightInstance.h; sourceTree = SOURCE_ROOT; };
+		42C8EDDD14724CD700E43619 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = src/main.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDDE14724CD700E43619 /* Material.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Material.cpp; path = src/Material.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDDF14724CD700E43619 /* Material.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Material.h; path = src/Material.h; sourceTree = SOURCE_ROOT; };
+		42C8EDE014724CD700E43619 /* MaterialParameter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MaterialParameter.cpp; path = src/MaterialParameter.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDE114724CD700E43619 /* MaterialParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MaterialParameter.h; path = src/MaterialParameter.h; sourceTree = SOURCE_ROOT; };
+		42C8EDE214724CD700E43619 /* Matrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Matrix.cpp; path = src/Matrix.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDE314724CD700E43619 /* Matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Matrix.h; path = src/Matrix.h; sourceTree = SOURCE_ROOT; };
+		42C8EDE414724CD700E43619 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Mesh.cpp; path = src/Mesh.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDE514724CD700E43619 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mesh.h; path = src/Mesh.h; sourceTree = SOURCE_ROOT; };
+		42C8EDE614724CD700E43619 /* MeshPart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeshPart.cpp; path = src/MeshPart.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDE714724CD700E43619 /* MeshPart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshPart.h; path = src/MeshPart.h; sourceTree = SOURCE_ROOT; };
+		42C8EDE814724CD700E43619 /* MeshSkin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeshSkin.cpp; path = src/MeshSkin.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDE914724CD700E43619 /* MeshSkin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshSkin.h; path = src/MeshSkin.h; sourceTree = SOURCE_ROOT; };
+		42C8EDEA14724CD700E43619 /* MeshSubSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeshSubSet.cpp; path = src/MeshSubSet.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDEB14724CD700E43619 /* MeshSubSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshSubSet.h; path = src/MeshSubSet.h; sourceTree = SOURCE_ROOT; };
+		42C8EDEC14724CD700E43619 /* Model.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Model.cpp; path = src/Model.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDED14724CD700E43619 /* Model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Model.h; path = src/Model.h; sourceTree = SOURCE_ROOT; };
+		42C8EDEE14724CD700E43619 /* Node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Node.cpp; path = src/Node.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDEF14724CD700E43619 /* Node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Node.h; path = src/Node.h; sourceTree = SOURCE_ROOT; };
+		42C8EDF014724CD700E43619 /* Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Object.cpp; path = src/Object.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDF114724CD700E43619 /* Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Object.h; path = src/Object.h; sourceTree = SOURCE_ROOT; };
+		42C8EDF214724CD700E43619 /* Quaternion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Quaternion.cpp; path = src/Quaternion.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDF314724CD700E43619 /* Quaternion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Quaternion.h; path = src/Quaternion.h; sourceTree = SOURCE_ROOT; };
+		42C8EDF414724CD700E43619 /* Reference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Reference.cpp; path = src/Reference.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDF514724CD700E43619 /* Reference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Reference.h; path = src/Reference.h; sourceTree = SOURCE_ROOT; };
+		42C8EDF614724CD700E43619 /* ReferenceTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ReferenceTable.cpp; path = src/ReferenceTable.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDF714724CD700E43619 /* ReferenceTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ReferenceTable.h; path = src/ReferenceTable.h; sourceTree = SOURCE_ROOT; };
+		42C8EDF814724CD700E43619 /* Scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Scene.cpp; path = src/Scene.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDF914724CD700E43619 /* Scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scene.h; path = src/Scene.h; sourceTree = SOURCE_ROOT; };
+		42C8EDFA14724CD700E43619 /* StringUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringUtil.cpp; path = src/StringUtil.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDFB14724CD700E43619 /* StringUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringUtil.h; path = src/StringUtil.h; sourceTree = SOURCE_ROOT; };
+		42C8EDFC14724CD700E43619 /* Transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Transform.cpp; path = src/Transform.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDFD14724CD700E43619 /* Transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Transform.h; path = src/Transform.h; sourceTree = SOURCE_ROOT; };
+		42C8EDFE14724CD700E43619 /* TTFFontEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TTFFontEncoder.cpp; path = src/TTFFontEncoder.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EDFF14724CD700E43619 /* TTFFontEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTFFontEncoder.h; path = src/TTFFontEncoder.h; sourceTree = SOURCE_ROOT; };
+		42C8EE0014724CD700E43619 /* Vector2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector2.cpp; path = src/Vector2.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EE0114724CD700E43619 /* Vector2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector2.h; path = src/Vector2.h; sourceTree = SOURCE_ROOT; };
+		42C8EE0214724CD700E43619 /* Vector3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector3.cpp; path = src/Vector3.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EE0314724CD700E43619 /* Vector3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector3.h; path = src/Vector3.h; sourceTree = SOURCE_ROOT; };
+		42C8EE0414724CD700E43619 /* Vector4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector4.cpp; path = src/Vector4.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EE0514724CD700E43619 /* Vector4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector4.h; path = src/Vector4.h; sourceTree = SOURCE_ROOT; };
+		42C8EE0614724CD700E43619 /* Vertex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vertex.cpp; path = src/Vertex.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EE0714724CD700E43619 /* Vertex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vertex.h; path = src/Vertex.h; sourceTree = SOURCE_ROOT; };
+		42C8EE0814724CD700E43619 /* VertexElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexElement.cpp; path = src/VertexElement.cpp; sourceTree = SOURCE_ROOT; };
+		42C8EE0914724CD700E43619 /* VertexElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexElement.h; path = src/VertexElement.h; sourceTree = SOURCE_ROOT; };
+		42C8EE341472B60100E43619 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = "../external-deps/freetype2/lib/macosx/libfreetype.a"; sourceTree = "<group>"; };
+		42C8EE361472D7E700E43619 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
+		42C8EE381472DAA300E43619 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+		42C8EE3A1472DAAE00E43619 /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; };
+		42D277571472EFA700D867A4 /* libpcre.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcre.a; path = "../external-deps/pcre/lib/macosx/libpcre.a"; sourceTree = "<group>"; };
+		42D277581472EFA700D867A4 /* libpcrecpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcrecpp.a; path = "../external-deps/pcre/lib/macosx/libpcrecpp.a"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		42475CE3147208A000610A6A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				42D277591472EFA700D867A4 /* libpcre.a in Frameworks */,
+				42D2775A1472EFA700D867A4 /* libpcrecpp.a in Frameworks */,
+				42C8EE351472B60100E43619 /* libfreetype.a in Frameworks */,
+				42475D7C14720ECE00610A6A /* libdom.a in Frameworks */,
+				42C8EE3B1472DAAE00E43619 /* libbz2.dylib in Frameworks */,
+				42C8EE391472DAA300E43619 /* libz.dylib in Frameworks */,
+				42C8EE371472D7E700E43619 /* libxml2.dylib in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		42475CDB147208A000610A6A = {
+			isa = PBXGroup;
+			children = (
+				42D277571472EFA700D867A4 /* libpcre.a */,
+				42D277581472EFA700D867A4 /* libpcrecpp.a */,
+				42C8EE3A1472DAAE00E43619 /* libbz2.dylib */,
+				42C8EE381472DAA300E43619 /* libz.dylib */,
+				42C8EE361472D7E700E43619 /* libxml2.dylib */,
+				42C8EE341472B60100E43619 /* libfreetype.a */,
+				42475D7B14720ECE00610A6A /* libdom.a */,
+				42475CE9147208A000610A6A /* gameplay-encoder */,
+				42475CE7147208A000610A6A /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		42475CE7147208A000610A6A /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				42475CE6147208A000610A6A /* gameplay-encoder */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		42475CE9147208A000610A6A /* gameplay-encoder */ = {
+			isa = PBXGroup;
+			children = (
+				42C8EDB714724CD700E43619 /* Animation.cpp */,
+				42C8EDB814724CD700E43619 /* Animation.h */,
+				42C8EDB914724CD700E43619 /* AnimationChannel.cpp */,
+				42C8EDBA14724CD700E43619 /* AnimationChannel.h */,
+				42C8EDBB14724CD700E43619 /* Animations.cpp */,
+				42C8EDBC14724CD700E43619 /* Animations.h */,
+				42C8EDBD14724CD700E43619 /* Base.cpp */,
+				42C8EDBE14724CD700E43619 /* Base.h */,
+				42C8EDBF14724CD700E43619 /* Camera.cpp */,
+				42C8EDC014724CD700E43619 /* Camera.h */,
+				42C8EDC114724CD700E43619 /* CameraInstance.cpp */,
+				42C8EDC214724CD700E43619 /* CameraInstance.h */,
+				42C8EDC314724CD700E43619 /* DAEChannelTarget.cpp */,
+				42C8EDC414724CD700E43619 /* DAEChannelTarget.h */,
+				42C8EDC514724CD700E43619 /* DAEOptimizer.cpp */,
+				42C8EDC614724CD700E43619 /* DAEOptimizer.h */,
+				42C8EDC714724CD700E43619 /* DAESceneEncoder.cpp */,
+				42C8EDC814724CD700E43619 /* DAESceneEncoder.h */,
+				42C8EDC914724CD700E43619 /* DAEUtil.cpp */,
+				42C8EDCA14724CD700E43619 /* DAEUtil.h */,
+				42C8EDCB14724CD700E43619 /* Effect.cpp */,
+				42C8EDCC14724CD700E43619 /* Effect.h */,
+				42C8EDCD14724CD700E43619 /* EncoderArguments.cpp */,
+				42C8EDCE14724CD700E43619 /* EncoderArguments.h */,
+				42C8EDCF14724CD700E43619 /* FileIO.cpp */,
+				42C8EDD014724CD700E43619 /* FileIO.h */,
+				42C8EDD114724CD700E43619 /* Font.cpp */,
+				42C8EDD214724CD700E43619 /* Font.h */,
+				42C8EDD314724CD700E43619 /* Glyph.cpp */,
+				42C8EDD414724CD700E43619 /* Glyph.h */,
+				42C8EDD514724CD700E43619 /* GPBDecoder.cpp */,
+				42C8EDD614724CD700E43619 /* GPBDecoder.h */,
+				42C8EDD714724CD700E43619 /* GPBFile.cpp */,
+				42C8EDD814724CD700E43619 /* GPBFile.h */,
+				42C8EDD914724CD700E43619 /* Light.cpp */,
+				42C8EDDA14724CD700E43619 /* Light.h */,
+				42C8EDDB14724CD700E43619 /* LightInstance.cpp */,
+				42C8EDDC14724CD700E43619 /* LightInstance.h */,
+				42C8EDDD14724CD700E43619 /* main.cpp */,
+				42C8EDDE14724CD700E43619 /* Material.cpp */,
+				42C8EDDF14724CD700E43619 /* Material.h */,
+				42C8EDE014724CD700E43619 /* MaterialParameter.cpp */,
+				42C8EDE114724CD700E43619 /* MaterialParameter.h */,
+				42C8EDE214724CD700E43619 /* Matrix.cpp */,
+				42C8EDE314724CD700E43619 /* Matrix.h */,
+				42C8EDE414724CD700E43619 /* Mesh.cpp */,
+				42C8EDE514724CD700E43619 /* Mesh.h */,
+				42C8EDE614724CD700E43619 /* MeshPart.cpp */,
+				42C8EDE714724CD700E43619 /* MeshPart.h */,
+				42C8EDE814724CD700E43619 /* MeshSkin.cpp */,
+				42C8EDE914724CD700E43619 /* MeshSkin.h */,
+				42C8EDEA14724CD700E43619 /* MeshSubSet.cpp */,
+				42C8EDEB14724CD700E43619 /* MeshSubSet.h */,
+				42C8EDEC14724CD700E43619 /* Model.cpp */,
+				42C8EDED14724CD700E43619 /* Model.h */,
+				42C8EDEE14724CD700E43619 /* Node.cpp */,
+				42C8EDEF14724CD700E43619 /* Node.h */,
+				42C8EDF014724CD700E43619 /* Object.cpp */,
+				42C8EDF114724CD700E43619 /* Object.h */,
+				42C8EDF214724CD700E43619 /* Quaternion.cpp */,
+				42C8EDF314724CD700E43619 /* Quaternion.h */,
+				42C8EDF414724CD700E43619 /* Reference.cpp */,
+				42C8EDF514724CD700E43619 /* Reference.h */,
+				42C8EDF614724CD700E43619 /* ReferenceTable.cpp */,
+				42C8EDF714724CD700E43619 /* ReferenceTable.h */,
+				42C8EDF814724CD700E43619 /* Scene.cpp */,
+				42C8EDF914724CD700E43619 /* Scene.h */,
+				42C8EDFA14724CD700E43619 /* StringUtil.cpp */,
+				42C8EDFB14724CD700E43619 /* StringUtil.h */,
+				42C8EDFC14724CD700E43619 /* Transform.cpp */,
+				42C8EDFD14724CD700E43619 /* Transform.h */,
+				42C8EDFE14724CD700E43619 /* TTFFontEncoder.cpp */,
+				42C8EDFF14724CD700E43619 /* TTFFontEncoder.h */,
+				42C8EE0014724CD700E43619 /* Vector2.cpp */,
+				42C8EE0114724CD700E43619 /* Vector2.h */,
+				42C8EE0214724CD700E43619 /* Vector3.cpp */,
+				42C8EE0314724CD700E43619 /* Vector3.h */,
+				42C8EE0414724CD700E43619 /* Vector4.cpp */,
+				42C8EE0514724CD700E43619 /* Vector4.h */,
+				42C8EE0614724CD700E43619 /* Vertex.cpp */,
+				42C8EE0714724CD700E43619 /* Vertex.h */,
+				42C8EE0814724CD700E43619 /* VertexElement.cpp */,
+				42C8EE0914724CD700E43619 /* VertexElement.h */,
+			);
+			path = "gameplay-encoder";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		42475CE5147208A000610A6A /* gameplay-encoder */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 42475CF0147208A100610A6A /* Build configuration list for PBXNativeTarget "gameplay-encoder" */;
+			buildPhases = (
+				42475CE2147208A000610A6A /* Sources */,
+				42475CE3147208A000610A6A /* Frameworks */,
+				42475CE4147208A000610A6A /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "gameplay-encoder";
+			productName = "gameplay-encoder";
+			productReference = 42475CE6147208A000610A6A /* gameplay-encoder */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		42475CDD147208A000610A6A /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0420;
+			};
+			buildConfigurationList = 42475CE0147208A000610A6A /* Build configuration list for PBXProject "gameplay-encoder" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 42475CDB147208A000610A6A;
+			productRefGroup = 42475CE7147208A000610A6A /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				42475CE5147208A000610A6A /* gameplay-encoder */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		42475CE2147208A000610A6A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				42C8EE0A14724CD700E43619 /* Animation.cpp in Sources */,
+				42C8EE0B14724CD700E43619 /* AnimationChannel.cpp in Sources */,
+				42C8EE0C14724CD700E43619 /* Animations.cpp in Sources */,
+				42C8EE0D14724CD700E43619 /* Base.cpp in Sources */,
+				42C8EE0E14724CD700E43619 /* Camera.cpp in Sources */,
+				42C8EE0F14724CD700E43619 /* CameraInstance.cpp in Sources */,
+				42C8EE1014724CD700E43619 /* DAEChannelTarget.cpp in Sources */,
+				42C8EE1114724CD700E43619 /* DAEOptimizer.cpp in Sources */,
+				42C8EE1214724CD700E43619 /* DAESceneEncoder.cpp in Sources */,
+				42C8EE1314724CD700E43619 /* DAEUtil.cpp in Sources */,
+				42C8EE1414724CD700E43619 /* Effect.cpp in Sources */,
+				42C8EE1514724CD700E43619 /* EncoderArguments.cpp in Sources */,
+				42C8EE1614724CD700E43619 /* FileIO.cpp in Sources */,
+				42C8EE1714724CD700E43619 /* Font.cpp in Sources */,
+				42C8EE1814724CD700E43619 /* Glyph.cpp in Sources */,
+				42C8EE1914724CD700E43619 /* GPBDecoder.cpp in Sources */,
+				42C8EE1A14724CD700E43619 /* GPBFile.cpp in Sources */,
+				42C8EE1B14724CD700E43619 /* Light.cpp in Sources */,
+				42C8EE1C14724CD700E43619 /* LightInstance.cpp in Sources */,
+				42C8EE1D14724CD700E43619 /* main.cpp in Sources */,
+				42C8EE1E14724CD700E43619 /* Material.cpp in Sources */,
+				42C8EE1F14724CD700E43619 /* MaterialParameter.cpp in Sources */,
+				42C8EE2014724CD700E43619 /* Matrix.cpp in Sources */,
+				42C8EE2114724CD700E43619 /* Mesh.cpp in Sources */,
+				42C8EE2214724CD700E43619 /* MeshPart.cpp in Sources */,
+				42C8EE2314724CD700E43619 /* MeshSkin.cpp in Sources */,
+				42C8EE2414724CD700E43619 /* MeshSubSet.cpp in Sources */,
+				42C8EE2514724CD700E43619 /* Model.cpp in Sources */,
+				42C8EE2614724CD700E43619 /* Node.cpp in Sources */,
+				42C8EE2714724CD700E43619 /* Object.cpp in Sources */,
+				42C8EE2814724CD700E43619 /* Quaternion.cpp in Sources */,
+				42C8EE2914724CD700E43619 /* Reference.cpp in Sources */,
+				42C8EE2A14724CD700E43619 /* ReferenceTable.cpp in Sources */,
+				42C8EE2B14724CD700E43619 /* Scene.cpp in Sources */,
+				42C8EE2C14724CD700E43619 /* StringUtil.cpp in Sources */,
+				42C8EE2D14724CD700E43619 /* Transform.cpp in Sources */,
+				42C8EE2E14724CD700E43619 /* TTFFontEncoder.cpp in Sources */,
+				42C8EE2F14724CD700E43619 /* Vector2.cpp in Sources */,
+				42C8EE3014724CD700E43619 /* Vector3.cpp in Sources */,
+				42C8EE3114724CD700E43619 /* Vector4.cpp in Sources */,
+				42C8EE3214724CD700E43619 /* Vertex.cpp in Sources */,
+				42C8EE3314724CD700E43619 /* VertexElement.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		42475CEE147208A100610A6A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					DOM_INCLUDE_LIBXML,
+					NO_BOOST,
+					NO_ZAE,
+					"DEBUG=1",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"../external-deps/freetype/include",
+					"../external-deps/collada-dom/include",
+					"../external-deps/collada-dom/include/1.4",
+				);
+				INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_TEST_FLAGS = "";
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				SDKROOT = macosx;
+				WARNING_CFLAGS = "";
+			};
+			name = Debug;
+		};
+		42475CEF147208A100610A6A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					DOM_INCLUDE_LIBXML,
+					NO_BOOST,
+					NO_ZAE,
+				);
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"../external-deps/freetype/include",
+					"../external-deps/collada-dom/include",
+					"../external-deps/collada-dom/include/1.4",
+				);
+				INFOPLIST_PREPROCESSOR_DEFINITIONS = "";
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				OTHER_TEST_FLAGS = "";
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				SDKROOT = macosx;
+				WARNING_CFLAGS = "";
+			};
+			name = Release;
+		};
+		42475CF1147208A100610A6A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
+				CLANG_CXX_LIBRARY = "compiler-default";
+				GCC_C_LANGUAGE_STANDARD = "compiler-default";
+				GCC_ENABLE_CPP_EXCEPTIONS = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				HEADER_SEARCH_PATHS = (
+					"../external-deps/freetype2/include",
+					"../external-deps/collada-dom/include",
+					"../external-deps/collada-dom/include/1.4",
+				);
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../external-deps/freetype2/lib/macosx\"",
+					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macosx\"",
+					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/minizip/mac\"",
+					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/pcre/lib/mac\"",
+					"\"$(SRCROOT)/../external-deps/pcre/lib/macosx\"",
+				);
+				MACH_O_TYPE = mh_execute;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		42475CF2147208A100610A6A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
+				CLANG_CXX_LIBRARY = "compiler-default";
+				GCC_C_LANGUAGE_STANDARD = "compiler-default";
+				GCC_ENABLE_CPP_EXCEPTIONS = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				HEADER_SEARCH_PATHS = (
+					"../external-deps/freetype2/include",
+					"../external-deps/collada-dom/include",
+					"../external-deps/collada-dom/include/1.4",
+				);
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../external-deps/freetype2/lib/macosx\"",
+					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macosx\"",
+					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/minizip/mac\"",
+					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/pcre/lib/mac\"",
+					"\"$(SRCROOT)/../external-deps/pcre/lib/macosx\"",
+				);
+				MACH_O_TYPE = mh_execute;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		42475CE0147208A000610A6A /* Build configuration list for PBXProject "gameplay-encoder" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				42475CEE147208A100610A6A /* Debug */,
+				42475CEF147208A100610A6A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		42475CF0147208A100610A6A /* Build configuration list for PBXNativeTarget "gameplay-encoder" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				42475CF1147208A100610A6A /* Debug */,
+				42475CF2147208A100610A6A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 42475CDD147208A000610A6A /* Project object */;
+}

+ 32 - 18
gameplay-encoder/src/Base.h

@@ -1,26 +1,40 @@
-#ifndef COMMON_H_
-#define COMMON_H_
+#ifndef BASE_H_
+#define BASE_H_
 
-#include <assert.h>
+#include <cmath>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <list>
 #include <map>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <string>
+#include <sys/stat.h>
+#include <vector>
+#include <assert.h>
+#include <math.h>
+#include <float.h>
+
 
 #ifndef M_1_PI        
-#define M_1_PI                    0.31830988618379067154
+#define M_1_PI                      0.31830988618379067154
 #endif
-#define MATH_FLOAT_SMALL        1.0e-37f
-#define MATH_TOLERANCE            2e-37f
-#define MATH_E                     2.71828182845904523536f
-#define MATH_LOG10E                0.4342944819032518f
-#define MATH_LOG2E                1.442695040888963387f
-#define MATH_PI                    3.14159265358979323846f
-#define MATH_PIOOVER2            1.57079632679489661923f
-#define MATH_PIOOVER4             M_PI_4
-#define MATH_PIX2                 6.28318530717958647693f
-#define MATH_EPSILON            0.000001f
-#define MATH_DEG_TO_RAD(x)         ((x) * 0.0174532925f)
-#define MATH_RAD_TO_DEG(x)        ((x)* 57.29577951f)
-#define MATH_RANDOM_MINUS1_1()  ((2.0f*((float)rand()/RAND_MAX))-1.0f) // Returns a random float between -1 and 1.
-#define MATH_RANDOM_0_1()       ((float)rand()/RAND_MAX) // Returns a random float between 0 and 1.
+#define MATH_FLOAT_SMALL            1.0e-37f
+#define MATH_TOLERANCE              2e-37f
+#define MATH_E                      2.71828182845904523536f
+#define MATH_LOG10E                 0.4342944819032518f
+#define MATH_LOG2E                  1.442695040888963387f
+#define MATH_PI                     3.14159265358979323846f
+#define MATH_PIOOVER2               1.57079632679489661923f
+#define MATH_PIOOVER4               M_PI_4
+#define MATH_PIX2                   6.28318530717958647693f
+#define MATH_EPSILON                0.000001f
+#define MATH_DEG_TO_RAD(x)          ((x) * 0.0174532925f)
+#define MATH_RAD_TO_DEG(x)          ((x)* 57.29577951f)
+#define MATH_RANDOM_MINUS1_1()      ((2.0f*((float)rand()/RAND_MAX))-1.0f) // Returns a random float between -1 and 1.
+#define MATH_RANDOM_0_1()           ((float)rand()/RAND_MAX) // Returns a random float between 0 and 1.
 
 namespace gameplay
 {

+ 1 - 1
gameplay-encoder/src/DAEOptimizer.cpp

@@ -81,7 +81,7 @@ void DAEOptimizer::getAnimationChannels(const domNodeRef& node, std::list<domCha
     }
 
     // Recursively do the same for all nodes
-    daeTArray<daeSmartRef<daeElement>> children;
+    daeTArray< daeSmartRef<daeElement> > children;
     node->getChildren(children);
     size_t childCount = children.getCount();
     for (size_t i = 0; i < childCount; i++)

+ 17 - 4
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -656,6 +656,7 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
     }
     animationChannel->setTargetAttribute(targetProperty);
     animationChannel->setTargetId(channelTarget.getTargetId());
+    //animationChannel->removeDuplicates();
     return true;
 }
 
@@ -830,7 +831,7 @@ void DAESceneEncoder::transformNode(domNode* domNode, Node* node)
 
 void DAESceneEncoder::calcTransform(domNode* domNode, Matrix& dstTransform)
 {
-    daeTArray<daeSmartRef<daeElement>> children;
+    daeTArray<daeSmartRef<daeElement> > children;
     domNode->getChildren(children);
     size_t childCount = children.getCount();
     for (size_t i = 0; i < childCount; i++)
@@ -1652,7 +1653,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                     delete polygonInputs[j];
                 }
                 warning(std::string("Triangles do not all have the same number of input sources for geometry mesh: ") + geometryId);
-                return false;
+                return NULL;
             }
             else
             {
@@ -1685,8 +1686,8 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
 
         // Go through the polygon indices for each input source retrieve the values
         // and iterate by its offset.
-        Vertex vertex;
 
+        Vertex vertex;
         for (unsigned int k = 0; k < inputSourceCount && poly < polyIntsCount;)
         {
             const domListOfFloats& source = polygonInputs[k]->sourceValues;
@@ -1701,7 +1702,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
             switch (type)
             {
             case POSITION:
-                vertex.reset();
+                vertex = Vertex(); // TODO
                 if (_vertexBlendWeights && _vertexBlendIndices)
                 {
                     vertex.hasWeights = true;
@@ -1769,6 +1770,8 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                     vertex.texCoord.y = (float)source.get(polyIndex * 2 + 1);
                 }
                 break;
+            default:
+                break;
             }
 
             // On the last input source attempt to add the vertex or index an existing one.
@@ -1891,6 +1894,16 @@ int DAESceneEncoder::getVertexUsageType(const std::string& semantic)
             {
                 type = TEXCOORD0;
             }
+            else if (equals(semantic, "TEXTANGENT"))
+            {
+                // Treat TEXTANGENT as TANGENT
+                type = TANGENT;
+            }
+            else if (equals(semantic, "TEXBINORMAL"))
+            {
+                // Treat TEXBINORMAL as BINORMAL
+                type = BINORMAL;
+            }
         case 'B':
             if (equals(semantic, "BINORMAL"))
             {

+ 1 - 1
gameplay-encoder/src/DAEUtil.cpp

@@ -148,7 +148,7 @@ const domName_arrayRef getSourceNameArray(const domSourceRef& source)
     {
         return nameArray;
     }
-    daeTArray<daeSmartRef<daeElement>> children;
+    daeTArray<daeSmartRef<daeElement> > children;
     source->getChildren(children);
     size_t childCount = children.getCount();
     for (size_t i = 0; i < childCount; i++)

+ 2 - 8
gameplay-encoder/src/EncoderArguments.h

@@ -1,12 +1,6 @@
 #ifndef ENCODERARGUMENTS_H_
 #define ENCODERARGUMENTS_H_
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <iostream>
-#include <string>
-#include <sys/stat.h>
-#include <vector>
 
 #include "Base.h"
 
@@ -48,12 +42,12 @@ public:
     /**
      * Returns the char pointer to the file path string.
      */
-    const char* EncoderArguments::getFilePathPointer() const;
+    const char* getFilePathPointer() const;
 
     /**
      * Returns the path to where the DAE output should be written to.
      */
-    const std::string& EncoderArguments::getDAEOutputPath() const;
+    const std::string& getDAEOutputPath() const;
 
     const std::vector<std::string>& getGroupAnimationNodeId() const;
     const std::vector<std::string>& getGroupAnimationAnimationId() const;

+ 3 - 3
gameplay-encoder/src/FileIO.cpp

@@ -1,10 +1,10 @@
 #include "FileIO.h"
-#include <assert.h>
 
 namespace gameplay
 {
 
-// Writing ot a binary file //
+
+// Writing out a binary file //
 
 void write(unsigned char value, FILE* file)
 {
@@ -102,7 +102,7 @@ void fprintfElement(FILE* file, const char* elementName, unsigned int value)
 }
 void fprintfElement(FILE* file, const char* elementName, unsigned char value)
 {
-    fprintf(file, "<%s>%u</%s>\n", elementName, value, (unsigned int)elementName);
+    fprintf(file, "<%s>%u</%s>\n", elementName, value, elementName);
 }
 
 void fprintfMatrix4f(FILE* file, const float* m)

+ 4 - 8
gameplay-encoder/src/FileIO.h

@@ -1,10 +1,6 @@
 #ifndef FILEIO_H_
 #define FILEIO_H_
 
-#include <iostream>
-#include <list>
-#include <vector>
-
 #include "Base.h"
 
 namespace gameplay
@@ -27,7 +23,7 @@ template <class T>
 void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T> list)
 {
     fprintf(file, "<%s>", elementName);
-    std::vector<T>::const_iterator i;
+    typename std::vector<T>::const_iterator i;
     for (i = list.begin(); i != list.end(); i++)
     {
         fprintf(file, format, *i);
@@ -39,7 +35,7 @@ template <class T>
 void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T> list)
 {
     fprintf(file, "<%s>", elementName);
-    std::list<T>::const_iterator i;
+    typename std::list<T>::const_iterator i;
     for (i = list.begin(); i != list.end(); i++)
     {
         fprintf(file, format, *i);
@@ -81,7 +77,7 @@ void write(std::list<T> list, FILE* file)
     // First write the size of the list
     write(list.size(), file);
     // Then write each element
-    std::list<T>::const_iterator i;
+    typename std::list<T>::const_iterator i;
     for (i = list.begin(); i != list.end(); i++)
     {
         write(*i, file);
@@ -99,7 +95,7 @@ void write(std::vector<T> vector, FILE* file)
     // First write the size of the vector
     write(vector.size(), file);
     // Then write each element
-    std::vector<T>::const_iterator i;
+    typename std::vector<T>::const_iterator i;
     for (i = vector.begin(); i != vector.end(); i++)
     {
         write(*i, file);

+ 2 - 2
gameplay-encoder/src/Light.cpp

@@ -47,7 +47,7 @@ float Light::computeRange(float constantAttenuation, float linearAttenuation, fl
     const float step = 0.01f;
     float range = 0.01f;
     float att = 1.0f;
-    while (att < 0.1f)
+    while (att > 0.01f)
     {
         att = 1 / (constantAttenuation + (range * linearAttenuation) + (range * range * quadraticAttenuation));
         range += step;
@@ -111,7 +111,7 @@ void Light::writeBinary(FILE* file)
         // Compute an approximate inner angle of the spot light using Collada's outer angle.
         _outerAngle = _falloffAngle / 2.0f;
         
-        if (_range == -1.0f)
+        if (_innerAngle == -1.0f)
         {
             _innerAngle = computeInnerAngle(_outerAngle);
         }

+ 2 - 3
gameplay-encoder/src/Mesh.cpp

@@ -1,5 +1,4 @@
 #include "Mesh.h"
-#include <cmath>
 
 namespace gameplay
 {
@@ -81,7 +80,7 @@ void Mesh::writeText(FILE* file)
     }
 
     // for each Vertex
-    fprintf(file, "<vertices count=\"%u\">\n", vertices.size());
+    fprintf(file, "<vertices count=\"%lu\">\n", vertices.size());
     for (std::vector<Vertex>::iterator i = vertices.begin(); i != vertices.end(); i++)
     {
         i->writeText(file);
@@ -200,7 +199,7 @@ void Mesh::computeBounds()
     }
 
     // Convert squared distance to distance for radius
-    bounds.radius = std::sqrtf(bounds.radius);
+    bounds.radius = sqrtf(bounds.radius);
 }
 
 }

+ 1 - 0
gameplay-encoder/src/Mesh.h

@@ -1,6 +1,7 @@
 #ifndef MESH_H_
 #define MESH_H_
 
+#include "Base.h"
 #include "Object.h"
 #include "MeshPart.h"
 #include "VertexElement.h"

+ 1 - 1
gameplay-encoder/src/MeshSkin.cpp

@@ -49,7 +49,7 @@ void MeshSkin::writeText(FILE* file)
         fprintf(file, "%s ", i->c_str());
     }
     fprintf(file, "</joints>\n");
-    fprintf(file, "<bindPoses count=\"%u\">", _bindPoses.size());
+    fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size());
     for (std::list<float>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
     {
         fprintf(file, "%f ", *i);

+ 2 - 1
gameplay-encoder/src/MeshSubSet.cpp

@@ -13,10 +13,11 @@ MeshSubSet::~MeshSubSet(void)
 {
 }
 
-byte MeshSubSet::getTypeId(void)
+unsigned int MeshSubSet::getTypeId(void)
 {
     return MESHPART_ID;
 }
+    
 const char* MeshSubSet::getElementName(void)
 {
     return "MeshSubSet";

+ 10 - 7
gameplay-encoder/src/MeshSubSet.h

@@ -1,19 +1,20 @@
-#ifndef MESHSUBSET_H_

+#ifndef MESHSUBSET_H_
 #define MESHSUBSET_H_
 
-#include <vector>
-
-#include "Common.h"
+#include "Base.h"
 #include "Object.h"
 #include "Vertex.h"
 
+namespace gameplay 
+{
+
 class MeshSubSet : public Object
 {
 public:
     MeshSubSet(void);
     virtual ~MeshSubSet(void);
 
-    virtual byte getTypeId(void);
+    virtual unsigned int getTypeId(void);
     virtual const char* getElementName(void);
     virtual void writeBinary(FILE* file);
     virtual void writeText(FILE* file);
@@ -24,5 +25,7 @@ public:
     std::map<Vertex, int> vertexLookupTable;
 };
 
-

-#endif

+}
+
+#endif
+

+ 2 - 7
gameplay-encoder/src/Object.h

@@ -1,11 +1,6 @@
 #ifndef OBJ_H_
 #define OBJ_H_
 
-#include <iostream>
-#include <string>
-#include <list>
-#include <vector>
-
 #include "Base.h"
 #include "FileIO.h"
 
@@ -118,7 +113,7 @@ public:
         // First write the size of the list
         write(list.size(), file);
         // Then write each element
-        std::list<T>::const_iterator i;
+        typename std::list<T>::const_iterator i;
         for (i = list.begin(); i != list.end(); i++)
         {
             (*i)->writeBinary(file);
@@ -134,7 +129,7 @@ public:
         // First write the size of the vector
         write(vector.size(), file);
         // Then write each element
-        std::vector<T>::const_iterator i;
+        typename std::vector<T>::const_iterator i;
         for (i = vector.begin(); i != vector.end(); i++)
         {
             (*i)->writeBinary(file);

+ 15 - 0
gameplay.sln

@@ -35,35 +35,50 @@ EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
+		DebugMem|Win32 = DebugMem|Win32
 		Release|Win32 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.Build.0 = Debug|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.ActiveCfg = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.Build.0 = Release|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.Build.0 = Debug|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.ActiveCfg = Release|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.Build.0 = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.Build.0 = Debug|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.Build.0 = Debug|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.ActiveCfg = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.Build.0 = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.ActiveCfg = Debug|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.Build.0 = Debug|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.ActiveCfg = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.Build.0 = Release|Win32
 		{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}.DebugMem|Win32.ActiveCfg = Debug|Win32
+		{9D69B743-4872-4DD1-8E30-0087C64298D7}.DebugMem|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
 		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Debug|Win32.Build.0 = Debug|Win32
+		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Release|Win32.ActiveCfg = Release|Win32
 		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection

+ 22 - 0
gameplay.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:gameplay/gameplay.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:gameplay-encoder/gameplay-encoder.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:gameplay-samples/sample00-mesh/sample00-mesh.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:gameplay-samples/sample01-longboard/sample01-longboard.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:gameplay-samples/sample02-spaceship/sample02-spaceship.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:gameplay-samples/sample03-character/sample03-character.xcodeproj">
+   </FileRef>
+</Workspace>

+ 53 - 5
gameplay/gameplay.vcxproj

@@ -1,6 +1,10 @@
 <?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="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
@@ -24,11 +28,14 @@
     <ClCompile Include="src\BoundingSphere.cpp" />
     <ClCompile Include="src\Camera.cpp" />
     <ClCompile Include="src\Curve.cpp" />
+    <ClCompile Include="src\DebugNew.cpp" />
     <ClCompile Include="src\Effect.cpp" />
     <ClCompile Include="src\FileSystem.cpp" />
     <ClCompile Include="src\Font.cpp" />
     <ClCompile Include="src\Frustum.cpp" />
     <ClCompile Include="src\Game.cpp" />
+    <ClCompile Include="src\gameplay-main-qnx.cpp" />
+    <ClCompile Include="src\gameplay-main-win32.cpp" />
     <ClCompile Include="src\Input.cpp" />
     <ClCompile Include="src\Joint.cpp" />
     <ClCompile Include="src\Light.cpp" />
@@ -88,16 +95,12 @@
     <ClInclude Include="src\BoundingSphere.h" />
     <ClInclude Include="src\Camera.h" />
     <ClInclude Include="src\Curve.h" />
+    <ClInclude Include="src\DebugNew.h" />
     <ClInclude Include="src\Effect.h" />
     <ClInclude Include="src\FileSystem.h" />
     <ClInclude Include="src\Font.h" />
     <ClInclude Include="src\Frustum.h" />
     <ClInclude Include="src\Game.h" />
-    <ClInclude Include="src\gameplay-main-qnx.h" />
-    <ClInclude Include="src\gameplay-main-win32.h">
-      <FileType>CppHeader</FileType>
-    </ClInclude>
-    <ClInclude Include="src\gameplay-main.h" />
     <ClInclude Include="src\gameplay.h" />
     <ClInclude Include="src\Input.h" />
     <ClInclude Include="src\Joint.h" />
@@ -163,6 +166,16 @@
     <None Include="res\shaders\solid.vsh" />
     <None Include="res\shaders\textured.fsh" />
     <None Include="res\shaders\textured.vsh" />
+    <None Include="src\gameplay-main-macosx.mm" />
+    <None Include="src\BoundingBox.inl" />
+    <None Include="src\BoundingSphere.inl" />
+    <None Include="src\Matrix.inl" />
+    <None Include="src\Plane.inl" />
+    <None Include="src\Quaternion.inl" />
+    <None Include="src\Ray.inl" />
+    <None Include="src\Vector2.inl" />
+    <None Include="src\Vector3.inl" />
+    <None Include="src\Vector4.inl" />
   </ItemGroup>
   <ItemGroup>
     <None Include="src\PhysicsConstraint.inl" />
@@ -182,6 +195,11 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
@@ -194,6 +212,9 @@
   <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)'=='DebugMem|Win32'" 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>
@@ -201,9 +222,15 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <OutDir>$(Configuration)\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
@@ -218,11 +245,32 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
     </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>

+ 42 - 9
gameplay/gameplay.vcxproj.filters

@@ -168,6 +168,15 @@
     <ClCompile Include="src\RenderState.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\gameplay-main-qnx.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\gameplay-main-win32.cpp">
+		<Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\DebugNew.cpp">
+		<Filter>src</Filter>
+    </ClCompile>
     <ClCompile Include="src\PhysicsController.cpp">
       <Filter>src</Filter>
     </ClCompile>
@@ -245,15 +254,6 @@
     <ClInclude Include="src\gameplay.h">
       <Filter>src</Filter>
     </ClInclude>
-    <ClInclude Include="src\gameplay-main.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\gameplay-main-qnx.h">
-      <Filter>src</Filter>
-    </ClInclude>
-    <ClInclude Include="src\gameplay-main-win32.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="src\Input.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -365,6 +365,9 @@
     <ClInclude Include="src\RenderState.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\DebugNew.h">
+      <Filter>src</Filter>
+    </ClInclude>
     <ClInclude Include="src\PhysicsController.h">
       <Filter>src</Filter>
     </ClInclude>
@@ -456,18 +459,48 @@
     </None>
   </ItemGroup>
   <ItemGroup>
+    <None Include="src\gameplay-main-macosx.mm">
+      <Filter>src</Filter>
+    </None>
     <None Include="src\PhysicsFixedConstraint.inl">
       <Filter>src</Filter>
     </None>
+    <None Include="src\BoundingBox.inl">
+      <Filter>src</Filter>
+    </None>
     <None Include="src\PhysicsGenericConstraint.inl">
       <Filter>src</Filter>
     </None>
+    <None Include="src\BoundingSphere.inl">
+      <Filter>src</Filter>
+    </None>
     <None Include="src\PhysicsSpringConstraint.inl">
       <Filter>src</Filter>
     </None>
+    <None Include="src\Matrix.inl">
+      <Filter>src</Filter>
+    </None>
     <None Include="src\PhysicsRigidBody.inl">
       <Filter>src</Filter>
     </None>
+    <None Include="src\Plane.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Quaternion.inl">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\Ray.inl">
+      <Filter>src</Filter>
+    </None>
+    <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\PhysicsConstraint.inl">
       <Filter>src</Filter>
     </None>

+ 717 - 0
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -0,0 +1,717 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		4220A6E8146B122B00CAEB3A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4220A6E7146B122B00CAEB3A /* QuartzCore.framework */; };
+		4234D99E14686C52003031B3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4234D99D14686C52003031B3 /* Cocoa.framework */; };
+		4299EFA9146AC94300FF4A73 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4299EFA8146AC94300FF4A73 /* OpenGL.framework */; };
+		4299EFAB146AC94B00FF4A73 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4299EFAA146AC94B00FF4A73 /* OpenAL.framework */; };
+		42BBCCBE146C89DF00D2A5F8 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC4B146C89DF00D2A5F8 /* Animation.cpp */; };
+		42BBCCBF146C89DF00D2A5F8 /* Animation.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC4C146C89DF00D2A5F8 /* Animation.h */; };
+		42BBCCC0146C89DF00D2A5F8 /* AnimationClip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC4D146C89DF00D2A5F8 /* AnimationClip.cpp */; };
+		42BBCCC1146C89DF00D2A5F8 /* AnimationClip.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC4E146C89DF00D2A5F8 /* AnimationClip.h */; };
+		42BBCCC2146C89DF00D2A5F8 /* AnimationController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC4F146C89DF00D2A5F8 /* AnimationController.cpp */; };
+		42BBCCC3146C89DF00D2A5F8 /* AnimationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC50146C89DF00D2A5F8 /* AnimationController.h */; };
+		42BBCCC4146C89DF00D2A5F8 /* AnimationTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC51146C89DF00D2A5F8 /* AnimationTarget.cpp */; };
+		42BBCCC5146C89DF00D2A5F8 /* AnimationTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC52146C89DF00D2A5F8 /* AnimationTarget.h */; };
+		42BBCCC6146C89DF00D2A5F8 /* AnimationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC53146C89DF00D2A5F8 /* AnimationValue.cpp */; };
+		42BBCCC7146C89DF00D2A5F8 /* AnimationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC54146C89DF00D2A5F8 /* AnimationValue.h */; };
+		42BBCCC8146C89DF00D2A5F8 /* AudioBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC55146C89DF00D2A5F8 /* AudioBuffer.cpp */; };
+		42BBCCC9146C89DF00D2A5F8 /* AudioBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC56146C89DF00D2A5F8 /* AudioBuffer.h */; };
+		42BBCCCA146C89DF00D2A5F8 /* AudioController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC57146C89DF00D2A5F8 /* AudioController.cpp */; };
+		42BBCCCB146C89DF00D2A5F8 /* AudioController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC58146C89DF00D2A5F8 /* AudioController.h */; };
+		42BBCCCC146C89DF00D2A5F8 /* AudioListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC59146C89DF00D2A5F8 /* AudioListener.cpp */; };
+		42BBCCCD146C89DF00D2A5F8 /* AudioListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC5A146C89DF00D2A5F8 /* AudioListener.h */; };
+		42BBCCCE146C89DF00D2A5F8 /* AudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC5B146C89DF00D2A5F8 /* AudioSource.cpp */; };
+		42BBCCCF146C89DF00D2A5F8 /* AudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC5C146C89DF00D2A5F8 /* AudioSource.h */; };
+		42BBCCD0146C89DF00D2A5F8 /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC5D146C89DF00D2A5F8 /* Base.h */; };
+		42BBCCD1146C89DF00D2A5F8 /* BoundingBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC5E146C89DF00D2A5F8 /* BoundingBox.cpp */; };
+		42BBCCD2146C89DF00D2A5F8 /* BoundingBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC5F146C89DF00D2A5F8 /* BoundingBox.h */; };
+		42BBCCD3146C89DF00D2A5F8 /* BoundingSphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC60146C89DF00D2A5F8 /* BoundingSphere.cpp */; };
+		42BBCCD4146C89DF00D2A5F8 /* BoundingSphere.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC61146C89DF00D2A5F8 /* BoundingSphere.h */; };
+		42BBCCD5146C89DF00D2A5F8 /* Camera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC62146C89DF00D2A5F8 /* Camera.cpp */; };
+		42BBCCD6146C89DF00D2A5F8 /* Camera.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC63146C89DF00D2A5F8 /* Camera.h */; };
+		42BBCCD7146C89DF00D2A5F8 /* Curve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC64146C89DF00D2A5F8 /* Curve.cpp */; };
+		42BBCCD8146C89DF00D2A5F8 /* Curve.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC65146C89DF00D2A5F8 /* Curve.h */; };
+		42BBCCD9146C89DF00D2A5F8 /* DepthStencilTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC66146C89DF00D2A5F8 /* DepthStencilTarget.cpp */; };
+		42BBCCDA146C89DF00D2A5F8 /* DepthStencilTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC67146C89DF00D2A5F8 /* DepthStencilTarget.h */; };
+		42BBCCDB146C89DF00D2A5F8 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC68146C89DF00D2A5F8 /* Effect.cpp */; };
+		42BBCCDC146C89DF00D2A5F8 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC69146C89DF00D2A5F8 /* Effect.h */; };
+		42BBCCDD146C89DF00D2A5F8 /* FileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC6A146C89DF00D2A5F8 /* FileSystem.cpp */; };
+		42BBCCDE146C89DF00D2A5F8 /* FileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC6B146C89DF00D2A5F8 /* FileSystem.h */; };
+		42BBCCDF146C89DF00D2A5F8 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC6C146C89DF00D2A5F8 /* Font.cpp */; };
+		42BBCCE0146C89DF00D2A5F8 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC6D146C89DF00D2A5F8 /* Font.h */; };
+		42BBCCE1146C89DF00D2A5F8 /* FrameBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC6E146C89DF00D2A5F8 /* FrameBuffer.cpp */; };
+		42BBCCE2146C89DF00D2A5F8 /* FrameBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC6F146C89DF00D2A5F8 /* FrameBuffer.h */; };
+		42BBCCE3146C89DF00D2A5F8 /* Frustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC70146C89DF00D2A5F8 /* Frustum.cpp */; };
+		42BBCCE4146C89DF00D2A5F8 /* Frustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC71146C89DF00D2A5F8 /* Frustum.h */; };
+		42BBCCE5146C89DF00D2A5F8 /* Game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC72146C89DF00D2A5F8 /* Game.cpp */; };
+		42BBCCE6146C89DF00D2A5F8 /* Game.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC73146C89DF00D2A5F8 /* Game.h */; };
+		42BBCCE7146C89DF00D2A5F8 /* gameplay-main-macosx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC74146C89DF00D2A5F8 /* gameplay-main-macosx.mm */; };
+		42BBCCE8146C89DF00D2A5F8 /* gameplay-main-qnx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC75146C89DF00D2A5F8 /* gameplay-main-qnx.cpp */; };
+		42BBCCE9146C89DF00D2A5F8 /* gameplay-main-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC76146C89DF00D2A5F8 /* gameplay-main-win32.cpp */; };
+		42BBCCEA146C89DF00D2A5F8 /* gameplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC77146C89DF00D2A5F8 /* gameplay.h */; };
+		42BBCCEB146C89DF00D2A5F8 /* Input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC78146C89DF00D2A5F8 /* Input.cpp */; };
+		42BBCCEC146C89DF00D2A5F8 /* Input.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC79146C89DF00D2A5F8 /* Input.h */; };
+		42BBCCED146C89DF00D2A5F8 /* Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC7A146C89DF00D2A5F8 /* Joint.cpp */; };
+		42BBCCEE146C89DF00D2A5F8 /* Joint.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC7B146C89DF00D2A5F8 /* Joint.h */; };
+		42BBCCEF146C89DF00D2A5F8 /* Light.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC7C146C89DF00D2A5F8 /* Light.cpp */; };
+		42BBCCF0146C89DF00D2A5F8 /* Light.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC7D146C89DF00D2A5F8 /* Light.h */; };
+		42BBCCF1146C89DF00D2A5F8 /* Material.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC7E146C89DF00D2A5F8 /* Material.cpp */; };
+		42BBCCF2146C89DF00D2A5F8 /* Material.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC7F146C89DF00D2A5F8 /* Material.h */; };
+		42BBCCF3146C89DF00D2A5F8 /* MaterialParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC80146C89DF00D2A5F8 /* MaterialParameter.cpp */; };
+		42BBCCF4146C89DF00D2A5F8 /* MaterialParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC81146C89DF00D2A5F8 /* MaterialParameter.h */; };
+		42BBCCF5146C89DF00D2A5F8 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC82146C89DF00D2A5F8 /* Matrix.cpp */; };
+		42BBCCF6146C89DF00D2A5F8 /* Matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC83146C89DF00D2A5F8 /* Matrix.h */; };
+		42BBCCF7146C89DF00D2A5F8 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC84146C89DF00D2A5F8 /* Mesh.cpp */; };
+		42BBCCF8146C89DF00D2A5F8 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC85146C89DF00D2A5F8 /* Mesh.h */; };
+		42BBCCF9146C89DF00D2A5F8 /* MeshPart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC86146C89DF00D2A5F8 /* MeshPart.cpp */; };
+		42BBCCFA146C89DF00D2A5F8 /* MeshPart.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC87146C89DF00D2A5F8 /* MeshPart.h */; };
+		42BBCCFB146C89DF00D2A5F8 /* MeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC88146C89DF00D2A5F8 /* MeshSkin.cpp */; };
+		42BBCCFC146C89DF00D2A5F8 /* MeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC89146C89DF00D2A5F8 /* MeshSkin.h */; };
+		42BBCCFD146C89DF00D2A5F8 /* Model.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC8A146C89DF00D2A5F8 /* Model.cpp */; };
+		42BBCCFE146C89DF00D2A5F8 /* Model.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC8B146C89DF00D2A5F8 /* Model.h */; };
+		42BBCCFF146C89DF00D2A5F8 /* Node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC8C146C89DF00D2A5F8 /* Node.cpp */; };
+		42BBCD00146C89DF00D2A5F8 /* Node.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC8D146C89DF00D2A5F8 /* Node.h */; };
+		42BBCD01146C89DF00D2A5F8 /* Package.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC8E146C89DF00D2A5F8 /* Package.cpp */; };
+		42BBCD02146C89DF00D2A5F8 /* Package.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC8F146C89DF00D2A5F8 /* Package.h */; };
+		42BBCD03146C89DF00D2A5F8 /* ParticleEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC90146C89DF00D2A5F8 /* ParticleEmitter.cpp */; };
+		42BBCD04146C89DF00D2A5F8 /* ParticleEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC91146C89DF00D2A5F8 /* ParticleEmitter.h */; };
+		42BBCD05146C89DF00D2A5F8 /* Pass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC92146C89DF00D2A5F8 /* Pass.cpp */; };
+		42BBCD06146C89DF00D2A5F8 /* Pass.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC93146C89DF00D2A5F8 /* Pass.h */; };
+		42BBCD07146C89DF00D2A5F8 /* Plane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC94146C89DF00D2A5F8 /* Plane.cpp */; };
+		42BBCD08146C89DF00D2A5F8 /* Plane.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC95146C89DF00D2A5F8 /* Plane.h */; };
+		42BBCD09146C89DF00D2A5F8 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC96146C89DF00D2A5F8 /* Platform.h */; };
+		42BBCD0A146C89DF00D2A5F8 /* PlatformMacOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC97146C89DF00D2A5F8 /* PlatformMacOSX.mm */; };
+		42BBCD0B146C89DF00D2A5F8 /* PlatformQNX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC98146C89DF00D2A5F8 /* PlatformQNX.cpp */; };
+		42BBCD0C146C89DF00D2A5F8 /* PlatformWin32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC99146C89DF00D2A5F8 /* PlatformWin32.cpp */; };
+		42BBCD0D146C89DF00D2A5F8 /* Properties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC9A146C89DF00D2A5F8 /* Properties.cpp */; };
+		42BBCD0E146C89DF00D2A5F8 /* Properties.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC9B146C89DF00D2A5F8 /* Properties.h */; };
+		42BBCD0F146C89DF00D2A5F8 /* Quaternion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC9C146C89DF00D2A5F8 /* Quaternion.cpp */; };
+		42BBCD10146C89DF00D2A5F8 /* Quaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC9D146C89DF00D2A5F8 /* Quaternion.h */; };
+		42BBCD11146C89DF00D2A5F8 /* Ray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCC9E146C89DF00D2A5F8 /* Ray.cpp */; };
+		42BBCD12146C89DF00D2A5F8 /* Ray.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCC9F146C89DF00D2A5F8 /* Ray.h */; };
+		42BBCD13146C89DF00D2A5F8 /* Rectangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCA0146C89DF00D2A5F8 /* Rectangle.cpp */; };
+		42BBCD14146C89DF00D2A5F8 /* Rectangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCA1146C89DF00D2A5F8 /* Rectangle.h */; };
+		42BBCD15146C89DF00D2A5F8 /* Ref.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCA2146C89DF00D2A5F8 /* Ref.cpp */; };
+		42BBCD16146C89DF00D2A5F8 /* Ref.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCA3146C89DF00D2A5F8 /* Ref.h */; };
+		42BBCD17146C89DF00D2A5F8 /* RenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCA4146C89DF00D2A5F8 /* RenderState.cpp */; };
+		42BBCD18146C89DF00D2A5F8 /* RenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCA5146C89DF00D2A5F8 /* RenderState.h */; };
+		42BBCD19146C89DF00D2A5F8 /* RenderTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCA6146C89DF00D2A5F8 /* RenderTarget.cpp */; };
+		42BBCD1A146C89DF00D2A5F8 /* RenderTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCA7146C89DF00D2A5F8 /* RenderTarget.h */; };
+		42BBCD1B146C89DF00D2A5F8 /* Scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCA8146C89DF00D2A5F8 /* Scene.cpp */; };
+		42BBCD1C146C89DF00D2A5F8 /* Scene.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCA9146C89DF00D2A5F8 /* Scene.h */; };
+		42BBCD1D146C89DF00D2A5F8 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCAA146C89DF00D2A5F8 /* SpriteBatch.cpp */; };
+		42BBCD1E146C89DF00D2A5F8 /* SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCAB146C89DF00D2A5F8 /* SpriteBatch.h */; };
+		42BBCD1F146C89DF00D2A5F8 /* Technique.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCAC146C89DF00D2A5F8 /* Technique.cpp */; };
+		42BBCD20146C89DF00D2A5F8 /* Technique.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCAD146C89DF00D2A5F8 /* Technique.h */; };
+		42BBCD21146C89DF00D2A5F8 /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCAE146C89DF00D2A5F8 /* Texture.cpp */; };
+		42BBCD22146C89DF00D2A5F8 /* Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCAF146C89DF00D2A5F8 /* Texture.h */; };
+		42BBCD23146C89DF00D2A5F8 /* Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCB0146C89DF00D2A5F8 /* Transform.cpp */; };
+		42BBCD24146C89DF00D2A5F8 /* Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCB1146C89DF00D2A5F8 /* Transform.h */; };
+		42BBCD25146C89DF00D2A5F8 /* Vector2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCB2146C89DF00D2A5F8 /* Vector2.cpp */; };
+		42BBCD26146C89DF00D2A5F8 /* Vector2.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCB3146C89DF00D2A5F8 /* Vector2.h */; };
+		42BBCD27146C89DF00D2A5F8 /* Vector3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCB4146C89DF00D2A5F8 /* Vector3.cpp */; };
+		42BBCD28146C89DF00D2A5F8 /* Vector3.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCB5146C89DF00D2A5F8 /* Vector3.h */; };
+		42BBCD29146C89DF00D2A5F8 /* Vector4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCB6146C89DF00D2A5F8 /* Vector4.cpp */; };
+		42BBCD2A146C89DF00D2A5F8 /* Vector4.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCB7146C89DF00D2A5F8 /* Vector4.h */; };
+		42BBCD2B146C89DF00D2A5F8 /* VertexAttributeBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCB8146C89DF00D2A5F8 /* VertexAttributeBinding.cpp */; };
+		42BBCD2C146C89DF00D2A5F8 /* VertexAttributeBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCB9146C89DF00D2A5F8 /* VertexAttributeBinding.h */; };
+		42BBCD2D146C89DF00D2A5F8 /* VertexFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCBA146C89DF00D2A5F8 /* VertexFormat.cpp */; };
+		42BBCD2E146C89DF00D2A5F8 /* VertexFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCBB146C89DF00D2A5F8 /* VertexFormat.h */; };
+		42BBCD2F146C89DF00D2A5F8 /* Viewport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42BBCCBC146C89DF00D2A5F8 /* Viewport.cpp */; };
+		42BBCD30146C89DF00D2A5F8 /* Viewport.h in Headers */ = {isa = PBXBuildFile; fileRef = 42BBCCBD146C89DF00D2A5F8 /* Viewport.h */; };
+		42CCD554146EC1DD00353661 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42CCD553146EC1DD00353661 /* libz.dylib */; };
+		42CCD556146EC1EB00353661 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42CCD555146EC1EB00353661 /* libpng.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		4220A6E7146B122B00CAEB3A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+		4234D99A14686C52003031B3 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		4234D99D14686C52003031B3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		4299EFA8146AC94300FF4A73 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/OpenGL.framework; sourceTree = DEVELOPER_DIR; };
+		4299EFAA146AC94B00FF4A73 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		42BBCC4B146C89DF00D2A5F8 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animation.cpp; path = src/Animation.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC4C146C89DF00D2A5F8 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = src/Animation.h; sourceTree = SOURCE_ROOT; };
+		42BBCC4D146C89DF00D2A5F8 /* AnimationClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationClip.cpp; path = src/AnimationClip.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC4E146C89DF00D2A5F8 /* AnimationClip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationClip.h; path = src/AnimationClip.h; sourceTree = SOURCE_ROOT; };
+		42BBCC4F146C89DF00D2A5F8 /* AnimationController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationController.cpp; path = src/AnimationController.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC50146C89DF00D2A5F8 /* AnimationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationController.h; path = src/AnimationController.h; sourceTree = SOURCE_ROOT; };
+		42BBCC51146C89DF00D2A5F8 /* AnimationTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationTarget.cpp; path = src/AnimationTarget.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC52146C89DF00D2A5F8 /* AnimationTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationTarget.h; path = src/AnimationTarget.h; sourceTree = SOURCE_ROOT; };
+		42BBCC53146C89DF00D2A5F8 /* AnimationValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationValue.cpp; path = src/AnimationValue.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC54146C89DF00D2A5F8 /* AnimationValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationValue.h; path = src/AnimationValue.h; sourceTree = SOURCE_ROOT; };
+		42BBCC55146C89DF00D2A5F8 /* AudioBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioBuffer.cpp; path = src/AudioBuffer.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC56146C89DF00D2A5F8 /* AudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioBuffer.h; path = src/AudioBuffer.h; sourceTree = SOURCE_ROOT; };
+		42BBCC57146C89DF00D2A5F8 /* AudioController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioController.cpp; path = src/AudioController.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC58146C89DF00D2A5F8 /* AudioController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioController.h; path = src/AudioController.h; sourceTree = SOURCE_ROOT; };
+		42BBCC59146C89DF00D2A5F8 /* AudioListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioListener.cpp; path = src/AudioListener.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC5A146C89DF00D2A5F8 /* AudioListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioListener.h; path = src/AudioListener.h; sourceTree = SOURCE_ROOT; };
+		42BBCC5B146C89DF00D2A5F8 /* AudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioSource.cpp; path = src/AudioSource.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC5C146C89DF00D2A5F8 /* AudioSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioSource.h; path = src/AudioSource.h; sourceTree = SOURCE_ROOT; };
+		42BBCC5D146C89DF00D2A5F8 /* Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Base.h; path = src/Base.h; sourceTree = SOURCE_ROOT; };
+		42BBCC5E146C89DF00D2A5F8 /* BoundingBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoundingBox.cpp; path = src/BoundingBox.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC5F146C89DF00D2A5F8 /* BoundingBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoundingBox.h; path = src/BoundingBox.h; sourceTree = SOURCE_ROOT; };
+		42BBCC60146C89DF00D2A5F8 /* BoundingSphere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoundingSphere.cpp; path = src/BoundingSphere.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC61146C89DF00D2A5F8 /* BoundingSphere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoundingSphere.h; path = src/BoundingSphere.h; sourceTree = SOURCE_ROOT; };
+		42BBCC62146C89DF00D2A5F8 /* Camera.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Camera.cpp; path = src/Camera.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC63146C89DF00D2A5F8 /* Camera.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Camera.h; path = src/Camera.h; sourceTree = SOURCE_ROOT; };
+		42BBCC64146C89DF00D2A5F8 /* Curve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Curve.cpp; path = src/Curve.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC65146C89DF00D2A5F8 /* Curve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Curve.h; path = src/Curve.h; sourceTree = SOURCE_ROOT; };
+		42BBCC66146C89DF00D2A5F8 /* DepthStencilTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DepthStencilTarget.cpp; path = src/DepthStencilTarget.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC67146C89DF00D2A5F8 /* DepthStencilTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DepthStencilTarget.h; path = src/DepthStencilTarget.h; sourceTree = SOURCE_ROOT; };
+		42BBCC68146C89DF00D2A5F8 /* Effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Effect.cpp; path = src/Effect.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC69146C89DF00D2A5F8 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Effect.h; path = src/Effect.h; sourceTree = SOURCE_ROOT; };
+		42BBCC6A146C89DF00D2A5F8 /* FileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileSystem.cpp; path = src/FileSystem.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC6B146C89DF00D2A5F8 /* FileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileSystem.h; path = src/FileSystem.h; sourceTree = SOURCE_ROOT; };
+		42BBCC6C146C89DF00D2A5F8 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Font.cpp; path = src/Font.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC6D146C89DF00D2A5F8 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Font.h; path = src/Font.h; sourceTree = SOURCE_ROOT; };
+		42BBCC6E146C89DF00D2A5F8 /* FrameBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FrameBuffer.cpp; path = src/FrameBuffer.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC6F146C89DF00D2A5F8 /* FrameBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FrameBuffer.h; path = src/FrameBuffer.h; sourceTree = SOURCE_ROOT; };
+		42BBCC70146C89DF00D2A5F8 /* Frustum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Frustum.cpp; path = src/Frustum.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC71146C89DF00D2A5F8 /* Frustum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Frustum.h; path = src/Frustum.h; sourceTree = SOURCE_ROOT; };
+		42BBCC72146C89DF00D2A5F8 /* Game.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Game.cpp; path = src/Game.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC73146C89DF00D2A5F8 /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Game.h; path = src/Game.h; sourceTree = SOURCE_ROOT; };
+		42BBCC74146C89DF00D2A5F8 /* gameplay-main-macosx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "gameplay-main-macosx.mm"; path = "src/gameplay-main-macosx.mm"; sourceTree = SOURCE_ROOT; };
+		42BBCC75146C89DF00D2A5F8 /* gameplay-main-qnx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gameplay-main-qnx.cpp"; path = "src/gameplay-main-qnx.cpp"; sourceTree = SOURCE_ROOT; };
+		42BBCC76146C89DF00D2A5F8 /* gameplay-main-win32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gameplay-main-win32.cpp"; path = "src/gameplay-main-win32.cpp"; sourceTree = SOURCE_ROOT; };
+		42BBCC77146C89DF00D2A5F8 /* gameplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gameplay.h; path = src/gameplay.h; sourceTree = SOURCE_ROOT; };
+		42BBCC78146C89DF00D2A5F8 /* Input.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Input.cpp; path = src/Input.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC79146C89DF00D2A5F8 /* Input.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Input.h; path = src/Input.h; sourceTree = SOURCE_ROOT; };
+		42BBCC7A146C89DF00D2A5F8 /* Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Joint.cpp; path = src/Joint.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC7B146C89DF00D2A5F8 /* Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Joint.h; path = src/Joint.h; sourceTree = SOURCE_ROOT; };
+		42BBCC7C146C89DF00D2A5F8 /* Light.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Light.cpp; path = src/Light.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC7D146C89DF00D2A5F8 /* Light.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Light.h; path = src/Light.h; sourceTree = SOURCE_ROOT; };
+		42BBCC7E146C89DF00D2A5F8 /* Material.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Material.cpp; path = src/Material.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC7F146C89DF00D2A5F8 /* Material.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Material.h; path = src/Material.h; sourceTree = SOURCE_ROOT; };
+		42BBCC80146C89DF00D2A5F8 /* MaterialParameter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MaterialParameter.cpp; path = src/MaterialParameter.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC81146C89DF00D2A5F8 /* MaterialParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MaterialParameter.h; path = src/MaterialParameter.h; sourceTree = SOURCE_ROOT; };
+		42BBCC82146C89DF00D2A5F8 /* Matrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Matrix.cpp; path = src/Matrix.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC83146C89DF00D2A5F8 /* Matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Matrix.h; path = src/Matrix.h; sourceTree = SOURCE_ROOT; };
+		42BBCC84146C89DF00D2A5F8 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Mesh.cpp; path = src/Mesh.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC85146C89DF00D2A5F8 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mesh.h; path = src/Mesh.h; sourceTree = SOURCE_ROOT; };
+		42BBCC86146C89DF00D2A5F8 /* MeshPart.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeshPart.cpp; path = src/MeshPart.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC87146C89DF00D2A5F8 /* MeshPart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshPart.h; path = src/MeshPart.h; sourceTree = SOURCE_ROOT; };
+		42BBCC88146C89DF00D2A5F8 /* MeshSkin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MeshSkin.cpp; path = src/MeshSkin.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC89146C89DF00D2A5F8 /* MeshSkin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MeshSkin.h; path = src/MeshSkin.h; sourceTree = SOURCE_ROOT; };
+		42BBCC8A146C89DF00D2A5F8 /* Model.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Model.cpp; path = src/Model.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC8B146C89DF00D2A5F8 /* Model.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Model.h; path = src/Model.h; sourceTree = SOURCE_ROOT; };
+		42BBCC8C146C89DF00D2A5F8 /* Node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Node.cpp; path = src/Node.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC8D146C89DF00D2A5F8 /* Node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Node.h; path = src/Node.h; sourceTree = SOURCE_ROOT; };
+		42BBCC8E146C89DF00D2A5F8 /* Package.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Package.cpp; path = src/Package.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC8F146C89DF00D2A5F8 /* Package.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Package.h; path = src/Package.h; sourceTree = SOURCE_ROOT; };
+		42BBCC90146C89DF00D2A5F8 /* ParticleEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParticleEmitter.cpp; path = src/ParticleEmitter.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC91146C89DF00D2A5F8 /* ParticleEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParticleEmitter.h; path = src/ParticleEmitter.h; sourceTree = SOURCE_ROOT; };
+		42BBCC92146C89DF00D2A5F8 /* Pass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Pass.cpp; path = src/Pass.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC93146C89DF00D2A5F8 /* Pass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Pass.h; path = src/Pass.h; sourceTree = SOURCE_ROOT; };
+		42BBCC94146C89DF00D2A5F8 /* Plane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Plane.cpp; path = src/Plane.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC95146C89DF00D2A5F8 /* Plane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Plane.h; path = src/Plane.h; sourceTree = SOURCE_ROOT; };
+		42BBCC96146C89DF00D2A5F8 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = src/Platform.h; sourceTree = SOURCE_ROOT; };
+		42BBCC97146C89DF00D2A5F8 /* PlatformMacOSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlatformMacOSX.mm; path = src/PlatformMacOSX.mm; sourceTree = SOURCE_ROOT; };
+		42BBCC98146C89DF00D2A5F8 /* PlatformQNX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformQNX.cpp; path = src/PlatformQNX.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC99146C89DF00D2A5F8 /* PlatformWin32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformWin32.cpp; path = src/PlatformWin32.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC9A146C89DF00D2A5F8 /* Properties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Properties.cpp; path = src/Properties.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC9B146C89DF00D2A5F8 /* Properties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Properties.h; path = src/Properties.h; sourceTree = SOURCE_ROOT; };
+		42BBCC9C146C89DF00D2A5F8 /* Quaternion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Quaternion.cpp; path = src/Quaternion.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC9D146C89DF00D2A5F8 /* Quaternion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Quaternion.h; path = src/Quaternion.h; sourceTree = SOURCE_ROOT; };
+		42BBCC9E146C89DF00D2A5F8 /* Ray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ray.cpp; path = src/Ray.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCC9F146C89DF00D2A5F8 /* Ray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Ray.h; path = src/Ray.h; sourceTree = SOURCE_ROOT; };
+		42BBCCA0146C89DF00D2A5F8 /* Rectangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Rectangle.cpp; path = src/Rectangle.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCA1146C89DF00D2A5F8 /* Rectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Rectangle.h; path = src/Rectangle.h; sourceTree = SOURCE_ROOT; };
+		42BBCCA2146C89DF00D2A5F8 /* Ref.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ref.cpp; path = src/Ref.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCA3146C89DF00D2A5F8 /* Ref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Ref.h; path = src/Ref.h; sourceTree = SOURCE_ROOT; };
+		42BBCCA4146C89DF00D2A5F8 /* RenderState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderState.cpp; path = src/RenderState.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCA5146C89DF00D2A5F8 /* RenderState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RenderState.h; path = src/RenderState.h; sourceTree = SOURCE_ROOT; };
+		42BBCCA6146C89DF00D2A5F8 /* RenderTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderTarget.cpp; path = src/RenderTarget.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCA7146C89DF00D2A5F8 /* RenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RenderTarget.h; path = src/RenderTarget.h; sourceTree = SOURCE_ROOT; };
+		42BBCCA8146C89DF00D2A5F8 /* Scene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Scene.cpp; path = src/Scene.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCA9146C89DF00D2A5F8 /* Scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scene.h; path = src/Scene.h; sourceTree = SOURCE_ROOT; };
+		42BBCCAA146C89DF00D2A5F8 /* SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SpriteBatch.cpp; path = src/SpriteBatch.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCAB146C89DF00D2A5F8 /* SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SpriteBatch.h; path = src/SpriteBatch.h; sourceTree = SOURCE_ROOT; };
+		42BBCCAC146C89DF00D2A5F8 /* Technique.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Technique.cpp; path = src/Technique.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCAD146C89DF00D2A5F8 /* Technique.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Technique.h; path = src/Technique.h; sourceTree = SOURCE_ROOT; };
+		42BBCCAE146C89DF00D2A5F8 /* Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Texture.cpp; path = src/Texture.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCAF146C89DF00D2A5F8 /* Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Texture.h; path = src/Texture.h; sourceTree = SOURCE_ROOT; };
+		42BBCCB0146C89DF00D2A5F8 /* Transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Transform.cpp; path = src/Transform.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCB1146C89DF00D2A5F8 /* Transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Transform.h; path = src/Transform.h; sourceTree = SOURCE_ROOT; };
+		42BBCCB2146C89DF00D2A5F8 /* Vector2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector2.cpp; path = src/Vector2.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCB3146C89DF00D2A5F8 /* Vector2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector2.h; path = src/Vector2.h; sourceTree = SOURCE_ROOT; };
+		42BBCCB4146C89DF00D2A5F8 /* Vector3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector3.cpp; path = src/Vector3.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCB5146C89DF00D2A5F8 /* Vector3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector3.h; path = src/Vector3.h; sourceTree = SOURCE_ROOT; };
+		42BBCCB6146C89DF00D2A5F8 /* Vector4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vector4.cpp; path = src/Vector4.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCB7146C89DF00D2A5F8 /* Vector4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vector4.h; path = src/Vector4.h; sourceTree = SOURCE_ROOT; };
+		42BBCCB8146C89DF00D2A5F8 /* VertexAttributeBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexAttributeBinding.cpp; path = src/VertexAttributeBinding.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCB9146C89DF00D2A5F8 /* VertexAttributeBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexAttributeBinding.h; path = src/VertexAttributeBinding.h; sourceTree = SOURCE_ROOT; };
+		42BBCCBA146C89DF00D2A5F8 /* VertexFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexFormat.cpp; path = src/VertexFormat.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCBB146C89DF00D2A5F8 /* VertexFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexFormat.h; path = src/VertexFormat.h; sourceTree = SOURCE_ROOT; };
+		42BBCCBC146C89DF00D2A5F8 /* Viewport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Viewport.cpp; path = src/Viewport.cpp; sourceTree = SOURCE_ROOT; };
+		42BBCCBD146C89DF00D2A5F8 /* Viewport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Viewport.h; path = src/Viewport.h; sourceTree = SOURCE_ROOT; };
+		42CCD553146EC1DD00353661 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = SDKs/MacOSX10.7.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		42CCD555146EC1EB00353661 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		4234D99714686C52003031B3 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				42CCD556146EC1EB00353661 /* libpng.a in Frameworks */,
+				42CCD554146EC1DD00353661 /* libz.dylib in Frameworks */,
+				4234D99E14686C52003031B3 /* Cocoa.framework in Frameworks */,
+				4220A6E8146B122B00CAEB3A /* QuartzCore.framework in Frameworks */,
+				4299EFA9146AC94300FF4A73 /* OpenGL.framework in Frameworks */,
+				4299EFAB146AC94B00FF4A73 /* OpenAL.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		4234D98A14686BB6003031B3 = {
+			isa = PBXGroup;
+			children = (
+				42CCD555146EC1EB00353661 /* libpng.a */,
+				42CCD553146EC1DD00353661 /* libz.dylib */,
+				4234D9A314686C52003031B3 /* gameplay */,
+				42CCD4AF146D811D00353661 /* Frameworks */,
+				4234D99B14686C52003031B3 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		4234D99B14686C52003031B3 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4234D99A14686C52003031B3 /* libgameplay.a */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		4234D9A314686C52003031B3 /* gameplay */ = {
+			isa = PBXGroup;
+			children = (
+				42BBCC4B146C89DF00D2A5F8 /* Animation.cpp */,
+				42BBCC4C146C89DF00D2A5F8 /* Animation.h */,
+				42BBCC4D146C89DF00D2A5F8 /* AnimationClip.cpp */,
+				42BBCC4E146C89DF00D2A5F8 /* AnimationClip.h */,
+				42BBCC4F146C89DF00D2A5F8 /* AnimationController.cpp */,
+				42BBCC50146C89DF00D2A5F8 /* AnimationController.h */,
+				42BBCC51146C89DF00D2A5F8 /* AnimationTarget.cpp */,
+				42BBCC52146C89DF00D2A5F8 /* AnimationTarget.h */,
+				42BBCC53146C89DF00D2A5F8 /* AnimationValue.cpp */,
+				42BBCC54146C89DF00D2A5F8 /* AnimationValue.h */,
+				42BBCC55146C89DF00D2A5F8 /* AudioBuffer.cpp */,
+				42BBCC56146C89DF00D2A5F8 /* AudioBuffer.h */,
+				42BBCC57146C89DF00D2A5F8 /* AudioController.cpp */,
+				42BBCC58146C89DF00D2A5F8 /* AudioController.h */,
+				42BBCC59146C89DF00D2A5F8 /* AudioListener.cpp */,
+				42BBCC5A146C89DF00D2A5F8 /* AudioListener.h */,
+				42BBCC5B146C89DF00D2A5F8 /* AudioSource.cpp */,
+				42BBCC5C146C89DF00D2A5F8 /* AudioSource.h */,
+				42BBCC5D146C89DF00D2A5F8 /* Base.h */,
+				42BBCC5E146C89DF00D2A5F8 /* BoundingBox.cpp */,
+				42BBCC5F146C89DF00D2A5F8 /* BoundingBox.h */,
+				42BBCC60146C89DF00D2A5F8 /* BoundingSphere.cpp */,
+				42BBCC61146C89DF00D2A5F8 /* BoundingSphere.h */,
+				42BBCC62146C89DF00D2A5F8 /* Camera.cpp */,
+				42BBCC63146C89DF00D2A5F8 /* Camera.h */,
+				42BBCC64146C89DF00D2A5F8 /* Curve.cpp */,
+				42BBCC65146C89DF00D2A5F8 /* Curve.h */,
+				42BBCC66146C89DF00D2A5F8 /* DepthStencilTarget.cpp */,
+				42BBCC67146C89DF00D2A5F8 /* DepthStencilTarget.h */,
+				42BBCC68146C89DF00D2A5F8 /* Effect.cpp */,
+				42BBCC69146C89DF00D2A5F8 /* Effect.h */,
+				42BBCC6A146C89DF00D2A5F8 /* FileSystem.cpp */,
+				42BBCC6B146C89DF00D2A5F8 /* FileSystem.h */,
+				42BBCC6C146C89DF00D2A5F8 /* Font.cpp */,
+				42BBCC6D146C89DF00D2A5F8 /* Font.h */,
+				42BBCC6E146C89DF00D2A5F8 /* FrameBuffer.cpp */,
+				42BBCC6F146C89DF00D2A5F8 /* FrameBuffer.h */,
+				42BBCC70146C89DF00D2A5F8 /* Frustum.cpp */,
+				42BBCC71146C89DF00D2A5F8 /* Frustum.h */,
+				42BBCC72146C89DF00D2A5F8 /* Game.cpp */,
+				42BBCC73146C89DF00D2A5F8 /* Game.h */,
+				42BBCC74146C89DF00D2A5F8 /* gameplay-main-macosx.mm */,
+				42BBCC75146C89DF00D2A5F8 /* gameplay-main-qnx.cpp */,
+				42BBCC76146C89DF00D2A5F8 /* gameplay-main-win32.cpp */,
+				42BBCC77146C89DF00D2A5F8 /* gameplay.h */,
+				42BBCC78146C89DF00D2A5F8 /* Input.cpp */,
+				42BBCC79146C89DF00D2A5F8 /* Input.h */,
+				42BBCC7A146C89DF00D2A5F8 /* Joint.cpp */,
+				42BBCC7B146C89DF00D2A5F8 /* Joint.h */,
+				42BBCC7C146C89DF00D2A5F8 /* Light.cpp */,
+				42BBCC7D146C89DF00D2A5F8 /* Light.h */,
+				42BBCC7E146C89DF00D2A5F8 /* Material.cpp */,
+				42BBCC7F146C89DF00D2A5F8 /* Material.h */,
+				42BBCC80146C89DF00D2A5F8 /* MaterialParameter.cpp */,
+				42BBCC81146C89DF00D2A5F8 /* MaterialParameter.h */,
+				42BBCC82146C89DF00D2A5F8 /* Matrix.cpp */,
+				42BBCC83146C89DF00D2A5F8 /* Matrix.h */,
+				42BBCC84146C89DF00D2A5F8 /* Mesh.cpp */,
+				42BBCC85146C89DF00D2A5F8 /* Mesh.h */,
+				42BBCC86146C89DF00D2A5F8 /* MeshPart.cpp */,
+				42BBCC87146C89DF00D2A5F8 /* MeshPart.h */,
+				42BBCC88146C89DF00D2A5F8 /* MeshSkin.cpp */,
+				42BBCC89146C89DF00D2A5F8 /* MeshSkin.h */,
+				42BBCC8A146C89DF00D2A5F8 /* Model.cpp */,
+				42BBCC8B146C89DF00D2A5F8 /* Model.h */,
+				42BBCC8C146C89DF00D2A5F8 /* Node.cpp */,
+				42BBCC8D146C89DF00D2A5F8 /* Node.h */,
+				42BBCC8E146C89DF00D2A5F8 /* Package.cpp */,
+				42BBCC8F146C89DF00D2A5F8 /* Package.h */,
+				42BBCC90146C89DF00D2A5F8 /* ParticleEmitter.cpp */,
+				42BBCC91146C89DF00D2A5F8 /* ParticleEmitter.h */,
+				42BBCC92146C89DF00D2A5F8 /* Pass.cpp */,
+				42BBCC93146C89DF00D2A5F8 /* Pass.h */,
+				42BBCC94146C89DF00D2A5F8 /* Plane.cpp */,
+				42BBCC95146C89DF00D2A5F8 /* Plane.h */,
+				42BBCC96146C89DF00D2A5F8 /* Platform.h */,
+				42BBCC97146C89DF00D2A5F8 /* PlatformMacOSX.mm */,
+				42BBCC98146C89DF00D2A5F8 /* PlatformQNX.cpp */,
+				42BBCC99146C89DF00D2A5F8 /* PlatformWin32.cpp */,
+				42BBCC9A146C89DF00D2A5F8 /* Properties.cpp */,
+				42BBCC9B146C89DF00D2A5F8 /* Properties.h */,
+				42BBCC9C146C89DF00D2A5F8 /* Quaternion.cpp */,
+				42BBCC9D146C89DF00D2A5F8 /* Quaternion.h */,
+				42BBCC9E146C89DF00D2A5F8 /* Ray.cpp */,
+				42BBCC9F146C89DF00D2A5F8 /* Ray.h */,
+				42BBCCA0146C89DF00D2A5F8 /* Rectangle.cpp */,
+				42BBCCA1146C89DF00D2A5F8 /* Rectangle.h */,
+				42BBCCA2146C89DF00D2A5F8 /* Ref.cpp */,
+				42BBCCA3146C89DF00D2A5F8 /* Ref.h */,
+				42BBCCA4146C89DF00D2A5F8 /* RenderState.cpp */,
+				42BBCCA5146C89DF00D2A5F8 /* RenderState.h */,
+				42BBCCA6146C89DF00D2A5F8 /* RenderTarget.cpp */,
+				42BBCCA7146C89DF00D2A5F8 /* RenderTarget.h */,
+				42BBCCA8146C89DF00D2A5F8 /* Scene.cpp */,
+				42BBCCA9146C89DF00D2A5F8 /* Scene.h */,
+				42BBCCAA146C89DF00D2A5F8 /* SpriteBatch.cpp */,
+				42BBCCAB146C89DF00D2A5F8 /* SpriteBatch.h */,
+				42BBCCAC146C89DF00D2A5F8 /* Technique.cpp */,
+				42BBCCAD146C89DF00D2A5F8 /* Technique.h */,
+				42BBCCAE146C89DF00D2A5F8 /* Texture.cpp */,
+				42BBCCAF146C89DF00D2A5F8 /* Texture.h */,
+				42BBCCB0146C89DF00D2A5F8 /* Transform.cpp */,
+				42BBCCB1146C89DF00D2A5F8 /* Transform.h */,
+				42BBCCB2146C89DF00D2A5F8 /* Vector2.cpp */,
+				42BBCCB3146C89DF00D2A5F8 /* Vector2.h */,
+				42BBCCB4146C89DF00D2A5F8 /* Vector3.cpp */,
+				42BBCCB5146C89DF00D2A5F8 /* Vector3.h */,
+				42BBCCB6146C89DF00D2A5F8 /* Vector4.cpp */,
+				42BBCCB7146C89DF00D2A5F8 /* Vector4.h */,
+				42BBCCB8146C89DF00D2A5F8 /* VertexAttributeBinding.cpp */,
+				42BBCCB9146C89DF00D2A5F8 /* VertexAttributeBinding.h */,
+				42BBCCBA146C89DF00D2A5F8 /* VertexFormat.cpp */,
+				42BBCCBB146C89DF00D2A5F8 /* VertexFormat.h */,
+				42BBCCBC146C89DF00D2A5F8 /* Viewport.cpp */,
+				42BBCCBD146C89DF00D2A5F8 /* Viewport.h */,
+			);
+			path = gameplay;
+			sourceTree = "<group>";
+		};
+		42CCD4AF146D811D00353661 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				4234D99D14686C52003031B3 /* Cocoa.framework */,
+				4220A6E7146B122B00CAEB3A /* QuartzCore.framework */,
+				4299EFA8146AC94300FF4A73 /* OpenGL.framework */,
+				4299EFAA146AC94B00FF4A73 /* OpenAL.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		4234D99814686C52003031B3 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				42BBCCBF146C89DF00D2A5F8 /* Animation.h in Headers */,
+				42BBCCC1146C89DF00D2A5F8 /* AnimationClip.h in Headers */,
+				42BBCCC3146C89DF00D2A5F8 /* AnimationController.h in Headers */,
+				42BBCCC5146C89DF00D2A5F8 /* AnimationTarget.h in Headers */,
+				42BBCCC7146C89DF00D2A5F8 /* AnimationValue.h in Headers */,
+				42BBCCC9146C89DF00D2A5F8 /* AudioBuffer.h in Headers */,
+				42BBCCCB146C89DF00D2A5F8 /* AudioController.h in Headers */,
+				42BBCCCD146C89DF00D2A5F8 /* AudioListener.h in Headers */,
+				42BBCCCF146C89DF00D2A5F8 /* AudioSource.h in Headers */,
+				42BBCCD0146C89DF00D2A5F8 /* Base.h in Headers */,
+				42BBCCD2146C89DF00D2A5F8 /* BoundingBox.h in Headers */,
+				42BBCCD4146C89DF00D2A5F8 /* BoundingSphere.h in Headers */,
+				42BBCCD6146C89DF00D2A5F8 /* Camera.h in Headers */,
+				42BBCCD8146C89DF00D2A5F8 /* Curve.h in Headers */,
+				42BBCCDA146C89DF00D2A5F8 /* DepthStencilTarget.h in Headers */,
+				42BBCCDC146C89DF00D2A5F8 /* Effect.h in Headers */,
+				42BBCCDE146C89DF00D2A5F8 /* FileSystem.h in Headers */,
+				42BBCCE0146C89DF00D2A5F8 /* Font.h in Headers */,
+				42BBCCE2146C89DF00D2A5F8 /* FrameBuffer.h in Headers */,
+				42BBCCE4146C89DF00D2A5F8 /* Frustum.h in Headers */,
+				42BBCCE6146C89DF00D2A5F8 /* Game.h in Headers */,
+				42BBCCEA146C89DF00D2A5F8 /* gameplay.h in Headers */,
+				42BBCCEC146C89DF00D2A5F8 /* Input.h in Headers */,
+				42BBCCEE146C89DF00D2A5F8 /* Joint.h in Headers */,
+				42BBCCF0146C89DF00D2A5F8 /* Light.h in Headers */,
+				42BBCCF2146C89DF00D2A5F8 /* Material.h in Headers */,
+				42BBCCF4146C89DF00D2A5F8 /* MaterialParameter.h in Headers */,
+				42BBCCF6146C89DF00D2A5F8 /* Matrix.h in Headers */,
+				42BBCCF8146C89DF00D2A5F8 /* Mesh.h in Headers */,
+				42BBCCFA146C89DF00D2A5F8 /* MeshPart.h in Headers */,
+				42BBCCFC146C89DF00D2A5F8 /* MeshSkin.h in Headers */,
+				42BBCCFE146C89DF00D2A5F8 /* Model.h in Headers */,
+				42BBCD00146C89DF00D2A5F8 /* Node.h in Headers */,
+				42BBCD02146C89DF00D2A5F8 /* Package.h in Headers */,
+				42BBCD04146C89DF00D2A5F8 /* ParticleEmitter.h in Headers */,
+				42BBCD06146C89DF00D2A5F8 /* Pass.h in Headers */,
+				42BBCD08146C89DF00D2A5F8 /* Plane.h in Headers */,
+				42BBCD09146C89DF00D2A5F8 /* Platform.h in Headers */,
+				42BBCD0E146C89DF00D2A5F8 /* Properties.h in Headers */,
+				42BBCD10146C89DF00D2A5F8 /* Quaternion.h in Headers */,
+				42BBCD12146C89DF00D2A5F8 /* Ray.h in Headers */,
+				42BBCD14146C89DF00D2A5F8 /* Rectangle.h in Headers */,
+				42BBCD16146C89DF00D2A5F8 /* Ref.h in Headers */,
+				42BBCD18146C89DF00D2A5F8 /* RenderState.h in Headers */,
+				42BBCD1A146C89DF00D2A5F8 /* RenderTarget.h in Headers */,
+				42BBCD1C146C89DF00D2A5F8 /* Scene.h in Headers */,
+				42BBCD1E146C89DF00D2A5F8 /* SpriteBatch.h in Headers */,
+				42BBCD20146C89DF00D2A5F8 /* Technique.h in Headers */,
+				42BBCD22146C89DF00D2A5F8 /* Texture.h in Headers */,
+				42BBCD24146C89DF00D2A5F8 /* Transform.h in Headers */,
+				42BBCD26146C89DF00D2A5F8 /* Vector2.h in Headers */,
+				42BBCD28146C89DF00D2A5F8 /* Vector3.h in Headers */,
+				42BBCD2A146C89DF00D2A5F8 /* Vector4.h in Headers */,
+				42BBCD2C146C89DF00D2A5F8 /* VertexAttributeBinding.h in Headers */,
+				42BBCD2E146C89DF00D2A5F8 /* VertexFormat.h in Headers */,
+				42BBCD30146C89DF00D2A5F8 /* Viewport.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		4234D99914686C52003031B3 /* gameplay */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4234D9AB14686C52003031B3 /* Build configuration list for PBXNativeTarget "gameplay" */;
+			buildPhases = (
+				4234D99614686C52003031B3 /* Sources */,
+				4234D99714686C52003031B3 /* Frameworks */,
+				4234D99814686C52003031B3 /* Headers */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = gameplay;
+			productName = gameplay;
+			productReference = 4234D99A14686C52003031B3 /* libgameplay.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		4234D98C14686BB6003031B3 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0420;
+			};
+			buildConfigurationList = 4234D98F14686BB6003031B3 /* Build configuration list for PBXProject "gameplay" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 4234D98A14686BB6003031B3;
+			productRefGroup = 4234D99B14686C52003031B3 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				4234D99914686C52003031B3 /* gameplay */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		4234D99614686C52003031B3 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				42BBCCBE146C89DF00D2A5F8 /* Animation.cpp in Sources */,
+				42BBCCC0146C89DF00D2A5F8 /* AnimationClip.cpp in Sources */,
+				42BBCCC2146C89DF00D2A5F8 /* AnimationController.cpp in Sources */,
+				42BBCCC4146C89DF00D2A5F8 /* AnimationTarget.cpp in Sources */,
+				42BBCCC6146C89DF00D2A5F8 /* AnimationValue.cpp in Sources */,
+				42BBCCC8146C89DF00D2A5F8 /* AudioBuffer.cpp in Sources */,
+				42BBCCCA146C89DF00D2A5F8 /* AudioController.cpp in Sources */,
+				42BBCCCC146C89DF00D2A5F8 /* AudioListener.cpp in Sources */,
+				42BBCCCE146C89DF00D2A5F8 /* AudioSource.cpp in Sources */,
+				42BBCCD1146C89DF00D2A5F8 /* BoundingBox.cpp in Sources */,
+				42BBCCD3146C89DF00D2A5F8 /* BoundingSphere.cpp in Sources */,
+				42BBCCD5146C89DF00D2A5F8 /* Camera.cpp in Sources */,
+				42BBCCD7146C89DF00D2A5F8 /* Curve.cpp in Sources */,
+				42BBCCD9146C89DF00D2A5F8 /* DepthStencilTarget.cpp in Sources */,
+				42BBCCDB146C89DF00D2A5F8 /* Effect.cpp in Sources */,
+				42BBCCDD146C89DF00D2A5F8 /* FileSystem.cpp in Sources */,
+				42BBCCDF146C89DF00D2A5F8 /* Font.cpp in Sources */,
+				42BBCCE1146C89DF00D2A5F8 /* FrameBuffer.cpp in Sources */,
+				42BBCCE3146C89DF00D2A5F8 /* Frustum.cpp in Sources */,
+				42BBCCE5146C89DF00D2A5F8 /* Game.cpp in Sources */,
+				42BBCCE7146C89DF00D2A5F8 /* gameplay-main-macosx.mm in Sources */,
+				42BBCCE8146C89DF00D2A5F8 /* gameplay-main-qnx.cpp in Sources */,
+				42BBCCE9146C89DF00D2A5F8 /* gameplay-main-win32.cpp in Sources */,
+				42BBCCEB146C89DF00D2A5F8 /* Input.cpp in Sources */,
+				42BBCCED146C89DF00D2A5F8 /* Joint.cpp in Sources */,
+				42BBCCEF146C89DF00D2A5F8 /* Light.cpp in Sources */,
+				42BBCCF1146C89DF00D2A5F8 /* Material.cpp in Sources */,
+				42BBCCF3146C89DF00D2A5F8 /* MaterialParameter.cpp in Sources */,
+				42BBCCF5146C89DF00D2A5F8 /* Matrix.cpp in Sources */,
+				42BBCCF7146C89DF00D2A5F8 /* Mesh.cpp in Sources */,
+				42BBCCF9146C89DF00D2A5F8 /* MeshPart.cpp in Sources */,
+				42BBCCFB146C89DF00D2A5F8 /* MeshSkin.cpp in Sources */,
+				42BBCCFD146C89DF00D2A5F8 /* Model.cpp in Sources */,
+				42BBCCFF146C89DF00D2A5F8 /* Node.cpp in Sources */,
+				42BBCD01146C89DF00D2A5F8 /* Package.cpp in Sources */,
+				42BBCD03146C89DF00D2A5F8 /* ParticleEmitter.cpp in Sources */,
+				42BBCD05146C89DF00D2A5F8 /* Pass.cpp in Sources */,
+				42BBCD07146C89DF00D2A5F8 /* Plane.cpp in Sources */,
+				42BBCD0A146C89DF00D2A5F8 /* PlatformMacOSX.mm in Sources */,
+				42BBCD0B146C89DF00D2A5F8 /* PlatformQNX.cpp in Sources */,
+				42BBCD0C146C89DF00D2A5F8 /* PlatformWin32.cpp in Sources */,
+				42BBCD0D146C89DF00D2A5F8 /* Properties.cpp in Sources */,
+				42BBCD0F146C89DF00D2A5F8 /* Quaternion.cpp in Sources */,
+				42BBCD11146C89DF00D2A5F8 /* Ray.cpp in Sources */,
+				42BBCD13146C89DF00D2A5F8 /* Rectangle.cpp in Sources */,
+				42BBCD15146C89DF00D2A5F8 /* Ref.cpp in Sources */,
+				42BBCD17146C89DF00D2A5F8 /* RenderState.cpp in Sources */,
+				42BBCD19146C89DF00D2A5F8 /* RenderTarget.cpp in Sources */,
+				42BBCD1B146C89DF00D2A5F8 /* Scene.cpp in Sources */,
+				42BBCD1D146C89DF00D2A5F8 /* SpriteBatch.cpp in Sources */,
+				42BBCD1F146C89DF00D2A5F8 /* Technique.cpp in Sources */,
+				42BBCD21146C89DF00D2A5F8 /* Texture.cpp in Sources */,
+				42BBCD23146C89DF00D2A5F8 /* Transform.cpp in Sources */,
+				42BBCD25146C89DF00D2A5F8 /* Vector2.cpp in Sources */,
+				42BBCD27146C89DF00D2A5F8 /* Vector3.cpp in Sources */,
+				42BBCD29146C89DF00D2A5F8 /* Vector4.cpp in Sources */,
+				42BBCD2B146C89DF00D2A5F8 /* VertexAttributeBinding.cpp in Sources */,
+				42BBCD2D146C89DF00D2A5F8 /* VertexFormat.cpp in Sources */,
+				42BBCD2F146C89DF00D2A5F8 /* Viewport.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		4234D99114686BB6003031B3 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+			};
+			name = Debug;
+		};
+		4234D99214686BB6003031B3 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+			};
+			name = Release;
+		};
+		4234D9A914686C52003031B3 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COPY_PHASE_STRIP = NO;
+				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = NO;
+				GCC_PREFIX_HEADER = "";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
+				GCC_WARN_MISSING_PARENTHESES = NO;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = "../external-deps/libpng/include";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../external-deps/libpng/lib/macosx\"",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				ONLY_ACTIVE_ARCH = YES;
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = macosx;
+				SHARED_PRECOMPS_DIR = "";
+				USER_HEADER_SEARCH_PATHS = "$(inherited)";
+			};
+			name = Debug;
+		};
+		4234D9AA14686C52003031B3 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PRECOMPILE_PREFIX_HEADER = NO;
+				GCC_PREFIX_HEADER = "";
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
+				GCC_WARN_MISSING_PARENTHESES = NO;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = "../external-deps/libpng/include";
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"\"$(SRCROOT)/../external-deps/libpng/lib/macosx\"",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = macosx;
+				SHARED_PRECOMPS_DIR = "";
+				USER_HEADER_SEARCH_PATHS = "$(inherited)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		4234D98F14686BB6003031B3 /* Build configuration list for PBXProject "gameplay" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4234D99114686BB6003031B3 /* Debug */,
+				4234D99214686BB6003031B3 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4234D9AB14686C52003031B3 /* Build configuration list for PBXNativeTarget "gameplay" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4234D9A914686C52003031B3 /* Debug */,
+				4234D9AA14686C52003031B3 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 4234D98C14686BB6003031B3 /* Project object */;
+}

+ 18 - 15
gameplay/res/shaders/bumped-specular.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                  // Light color.
@@ -36,8 +38,8 @@ void lighting(vec3 normalVector, vec3 cameraDirection, vec3 lightDirection, floa
 
 #if defined(POINT_LIGHT)
 
-varying vec3 v_vertexToPointLightDirection; // Light direction w.r.t current vertex in tangent space.
-varying float v_pointLightAttenuation;      // Attenuation of point light.
+varying vec3 v_vertexToPointLightDirection;   // Light direction w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;        // Attenuation of point light.
 
 void applyLight()
 {
@@ -45,19 +47,20 @@ void applyLight()
     // Fetch normals from the normal map.
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
     vec3 cameraDirection = normalize(v_cameraDirection);
-    
     vec3 vertexToPointLightDirection = normalize(v_vertexToPointLightDirection);
     
-    // Fetch point light attenuation.
-    lighting(normalVector, cameraDirection, vertexToPointLightDirection, v_pointLightAttenuation);
+    float pointLightAttenuation = clamp(v_pointLightAttenuation, 0.0, 1.0);
+    
+    lighting(normalVector, cameraDirection, vertexToPointLightDirection, pointLightAttenuation);
 }
 
 #elif defined(SPOT_LIGHT)
 
-uniform float u_spotLightInnerAngleCos;     // The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;     // The soft outer part [0.0 - 1.0]
-varying vec3 v_spotLightDirection;          // Direction of spot light in tangent space.
-varying vec3 v_vertexToSpotLightDirection;  // Direction of the spot light w.r.t current vertex in tangent space.
+uniform float u_spotLightInnerAngleCos;       // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;       // The soft outer part [0.0 - 1.0]
+varying vec3 v_spotLightDirection;            // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;    // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;         // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -66,7 +69,6 @@ float lerpstep( float lower, float upper, float s)
 
 void applyLight()
 {
-    // Normalize the vectors.
     // Fetch normals from the normal map.
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
     vec3 cameraDirection = normalize(v_cameraDirection);
@@ -78,23 +80,24 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
     
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, cameraDirection, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-varying vec3 v_directionalLightDirection;    // Direction of light in tangent space.
+varying vec3 v_lightDirection;                 // Direction of light in tangent space.
 
 void applyLight()
 {
-    // Normalize vectors.
     // Fetch normals from the normal map
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
     vec3 cameraDirection = normalize(v_cameraDirection);
-    vec3 lightDirection = normalize(v_directionalLightDirection);
+    vec3 lightDirection = normalize(v_lightDirection);
 
     lighting(normalVector, cameraDirection, -lightDirection, 1.0);
 }

+ 180 - 37
gameplay/res/shaders/bumped-specular.vsh

@@ -1,33 +1,160 @@
 // Uniforms
-uniform mat4 u_worldViewProjectionMatrix;       // Matrix to transform a position to clip space.
-uniform mat4 u_inverseTransposeWorldViewMatrix; // Matrix to transform a normal to view space.
-uniform mat4 u_worldMatrix;                     // Matrix to tranform a position to world space.
-uniform mat4 u_worldViewMatrix;                 // Matrix to tranform a position to view space.
-uniform vec3 u_cameraPosition;                  // Position of the camera.
+uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
+uniform mat4 u_worldViewProjectionMatrix;           // Matrix to transform a position to clip space.
+uniform mat4 u_inverseTransposeWorldViewMatrix;     // Matrix to transform a normal to view space.
+uniform vec3 u_cameraPosition;                      // Position of the camera.
 
 // Inputs
-attribute vec4 a_position;                      // Vertex Position (x, y, z, w)
-attribute vec3 a_normal;                        // Vertex Normal (x, y, z)
-attribute vec2 a_texCoord;                      // Vertex Texture Coordinate (u, v)
-attribute vec3 a_tangent;                       // Vertex Tangent (x, y, z)
-attribute vec3 a_binormal;                      // Vertex Binormal (actually Bi-tangent) (x, y, z)
+attribute vec4 a_position;                          // Vertex Position (x, y, z, w)
+attribute vec3 a_normal;                            // Vertex Normal (x, y, z)
+attribute vec2 a_texCoord;                          // Vertex Texture Coordinate (u, v)
+attribute vec3 a_tangent;                           // Vertex Tangent (x, y, z)
+attribute vec3 a_binormal;                          // Vertex Binormal (actually Bi-tangent) (x, y, z)
 
 // Outputs
-varying vec2 v_texCoord;                        // Texture Coordinate (u,v)
-varying vec3 v_cameraDirection;                 // Direction the camera is looking at in tangent space.
+varying vec2 v_texCoord;                            // Texture Coordinate (u,v)
+varying vec3 v_cameraDirection;                     // Direction the camera is looking at in tangent space.
+
+#if defined(SKINNING)
+
+attribute vec4 a_blendWeights;
+attribute vec4 a_blendIndices;
+
+// 32 4x3 matrices as an array of floats
+uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
+
+// Common vectors.
+vec4 _skinnedPosition;
+vec3 _skinnedNormal;
+
+void skinPosition(float blendWeight, int matrixIndex)
+{
+    vec4 tmp;
+
+    tmp.x = dot(a_position, u_matrixPalette[matrixIndex]);
+    tmp.y = dot(a_position, u_matrixPalette[matrixIndex + 1]);
+    tmp.z = dot(a_position, u_matrixPalette[matrixIndex + 2]);
+    tmp.w = a_position.w;
+
+    _skinnedPosition += blendWeight * tmp;
+}
+
+vec4 getPosition()
+{
+    _skinnedPosition = vec4(0.0);
+
+    // Transform position to view space using 
+    // matrix palette with four matrices used to transform a vertex.
+
+    float blendWeight = a_blendWeights[0];
+    int matrixIndex = int (a_blendIndices[0]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[1];
+    matrixIndex = int(a_blendIndices[1]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[2];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[3];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    return _skinnedPosition;    
+}
+
+void skinTangentSpaceVector(vec3 vector, float blendWeight, int matrixIndex)
+{
+    vec3 tmp;
+
+    tmp.x = dot(vector, u_matrixPalette[matrixIndex].xyz);
+    tmp.y = dot(vector, u_matrixPalette[matrixIndex + 1].xyz);
+    tmp.z = dot(vector, u_matrixPalette[matrixIndex + 2].xyz);
+
+    _skinnedNormal += blendWeight * tmp;
+}
+
+vec3 getTangentSpaceVector(vec3 vector)
+{
+    _skinnedNormal = vec3(0.0);
+
+    // Transform normal to view space using 
+    // matrix palette with four matrices used to transform a vertex.
+
+    float blendWeight = a_blendWeights[0];
+    int matrixIndex = int (a_blendIndices[0]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[1];
+    matrixIndex = int(a_blendIndices[1]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[2];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[3];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    return _skinnedNormal;
+}
+
+vec3 getNormal()
+{
+    return getTangentSpaceVector(a_normal);
+}
+
+vec3 getTangent()
+{
+    return getTangentSpaceVector(a_tangent);
+}
+
+vec3 getBinormal()
+{
+    return getTangentSpaceVector(a_binormal);
+}
+
+#else
+
+vec4 getPosition()
+{
+    return a_position;    
+}
+
+vec3 getNormal()
+{
+    return a_normal;
+}
+
+vec3 getTangent()
+{
+    return a_tangent;
+}
+
+vec3 getBinormal()
+{
+    return a_binormal;
+}
+
+#endif
 
 #if defined(POINT_LIGHT)
 
-uniform vec3 u_pointLightPosition;              // Position
-uniform float u_pointLightRadius;               // Radius 
-varying vec3 v_vertexToPointLightDirection;     // Direction of point light w.r.t current vertex in tangent space.
-varying float v_pointLightAttenuation;          // Attenuation of point light.
+uniform vec3 u_pointLightPosition;                  // Position
+uniform float u_pointLightRangeInverse;             // Inverse of light range 
+varying vec3 v_vertexToPointLightDirection;         // Direction of point light w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;              // Attenuation of point light.
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
     
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
     // Compute the light direction with light position and the vertex position.
     vec3 lightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
     
@@ -35,7 +162,7 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     vec3 vertexToPointLightDirection = tangentSpaceTransformMatrix * lightDirection;
 
     // Attenuation
-    v_pointLightAttenuation = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    v_pointLightAttenuation = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
     v_vertexToPointLightDirection =  vertexToPointLightDirection;
@@ -43,15 +170,19 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
 
 #elif defined(SPOT_LIGHT)
 
-uniform vec3 u_spotLightPosition;               // Position
-uniform vec3 u_spotLightDirection;              // Direction
-varying vec3 v_spotLightDirection;              // Direction of spot light in tangent space.
-varying vec3 v_vertexToSpotLightDirection;      // Direction of the spot light w.r.t current vertex in tangent space.
+uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
+uniform vec3 u_spotLightDirection;                  // Direction
+varying vec3 v_spotLightDirection;                  // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;          // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
 
     // Transform spot light direction to tangent space.
     v_spotLightDirection = tangentSpaceTransformMatrix * u_spotLightDirection;
@@ -61,6 +192,9 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     
     // Transform current light direction to tangent space.
     lightDirection = tangentSpaceTransformMatrix * lightDirection;
+    
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
 
     // Output light direction.
     v_vertexToSpotLightDirection = lightDirection;
@@ -68,35 +202,44 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
 
 #else
 
-uniform vec3 u_lightDirection;                    // Direction
-varying vec3 v_directionalLightDirection;         // Direction of light in tangent space.
+uniform vec3 u_lightDirection;                      // Direction
+varying vec3 v_lightDirection;                      // Direction of light in tangent space.
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
     // Transform light direction to tangent space.
-    v_directionalLightDirection = tangentSpaceTransformMatrix * u_lightDirection;
+    v_lightDirection = tangentSpaceTransformMatrix * u_lightDirection;
 }
 
 #endif
 
 void main()
 {
+    vec4 position = getPosition();
+    vec3 normal = getNormal();
+    vec3 tangent = getTangent();
+    vec3 binormal = getBinormal();
+    
     // Transform position to clip space.
-    gl_Position = u_worldViewProjectionMatrix * a_position;
+    gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
-    vec3 tangentVector  = inverseTransposeWorldViewMatrix * a_tangent;
-    vec3 normalVector = inverseTransposeWorldViewMatrix * a_normal;
-    vec3 binormalVector = inverseTransposeWorldViewMatrix * a_binormal;
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
+    vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * tangent);
+    vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal);
+    vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * binormal);
 
     // Create a transform to convert a vector to tangent space.
-    mat3 tangentSpaceTransformMatrix = mat3(tangentVector, binormalVector, normalVector);
-
-    // Compute camera direction and transform it to tangent space.
-    vec4 positionWorldSpace = u_worldMatrix * a_position;
-    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldSpace.xyz);
-
+    mat3 tangentSpaceTransformMatrix = mat3(tangentVector.x, binormalVector.x, normalVector.x,
+                                            tangentVector.y, binormalVector.y, normalVector.y,
+                                            tangentVector.z, binormalVector.z, normalVector.z);
     // Apply light.
     applyLight(tangentSpaceTransformMatrix);
 

+ 21 - 17
gameplay/res/shaders/bumped.fsh

@@ -1,18 +1,20 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
-uniform vec3 u_lightColor;                  // Light color.
-uniform vec3 u_ambientColor;                // Ambient color.
-uniform sampler2D u_diffuseTexture;         // Diffuse texture.
-uniform sampler2D u_normalMapTexture;       // Normal map texture.
+uniform vec3 u_lightColor;                   // Light color.
+uniform vec3 u_ambientColor;                 // Ambient color.
+uniform sampler2D u_diffuseTexture;          // Diffuse texture.
+uniform sampler2D u_normalMapTexture;        // Normal map texture.
 
 // Inputs
-varying vec2 v_texCoord;                    // Texture Coordinate.
+varying vec2 v_texCoord;                     // Texture Coordinate.
 
 // Common colors
-vec4 _baseColor;                            // Base color
-vec3 _ambientColor;                         // Ambient Color
-vec3 _diffuseColor;                         // Diffuse Color
+vec4 _baseColor;                             // Base color
+vec3 _ambientColor;                          // Ambient Color
+vec3 _diffuseColor;                          // Diffuse Color
 
 void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 {
@@ -35,11 +37,11 @@ void applyLight()
     // Normalize the vectors.
     // Fetch normals from the normal map.
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
-    
     vec3 vertexToPointLightDirection = normalize(v_vertexToPointLightDirection);
+    float pointLightAttenuation = clamp(v_pointLightAttenuation, 0.0, 1.0);
     
     // Fetch point light attenuation.
-    lighting(normalVector, vertexToPointLightDirection, v_pointLightAttenuation);
+    lighting(normalVector, vertexToPointLightDirection, pointLightAttenuation);
 }
 
 #elif defined(SPOT_LIGHT)
@@ -48,6 +50,7 @@ uniform float u_spotLightInnerAngleCos;       // The bright spot [0.0 - 1.0]
 uniform float u_spotLightOuterAngleCos;       // The soft outer part [0.0 - 1.0]
 varying vec3 v_spotLightDirection;            // Direction of spot light in tangent space.
 varying vec3 v_vertexToSpotLightDirection;    // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;         // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -56,9 +59,8 @@ float lerpstep( float lower, float upper, float s)
 
 void applyLight()
 {
-    // Normalize the vectors.
     // Fetch normals from the normal map.
-    vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).xyz * 2.0 - 1.0);
     vec3 spotLightDirection =normalize(v_spotLightDirection);
     vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection);
     
@@ -67,22 +69,24 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
     
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-varying vec3 v_directionalLightDirection;    // Direction of light in tangent space.
+varying vec3 v_lightDirection;                  // Direction of light in tangent space.
 
 void applyLight()
 {
     // Normalize vectors.
     // Fetch normals from the normal map
-    vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).rgb * 2.0 - 1.0);
-    vec3 lightDirection = normalize(v_directionalLightDirection);
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, v_texCoord).xyz * 2.0 - 1.0);
+    vec3 lightDirection = normalize(v_lightDirection);
 
     lighting(normalVector, -lightDirection, 1.0);
 }

+ 154 - 17
gameplay/res/shaders/bumped.vsh

@@ -12,11 +12,137 @@ attribute vec3 a_binormal;                      // Vertex Binormal (actually Bi-
 // Outputs
 varying vec2 v_texCoord;                        // Texture Coordinate (u,v)
 
+#if defined(SKINNING)
+
+attribute vec4 a_blendWeights;
+attribute vec4 a_blendIndices;
+
+// 32 4x3 matrices as an array of floats
+uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
+
+// Common vectors.
+vec4 _skinnedPosition;
+vec3 _skinnedNormal;
+
+void skinPosition(float blendWeight, int matrixIndex)
+{
+    vec4 tmp;
+
+    tmp.x = dot(a_position, u_matrixPalette[matrixIndex]);
+    tmp.y = dot(a_position, u_matrixPalette[matrixIndex + 1]);
+    tmp.z = dot(a_position, u_matrixPalette[matrixIndex + 2]);
+    tmp.w = a_position.w;
+
+    _skinnedPosition += blendWeight * tmp;
+}
+
+vec4 getPosition()
+{
+    _skinnedPosition = vec4(0.0);
+
+    // Transform position to view space using 
+    // matrix palette with four matrices used to transform a vertex.
+
+    float blendWeight = a_blendWeights[0];
+    int matrixIndex = int (a_blendIndices[0]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[1];
+    matrixIndex = int(a_blendIndices[1]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[2];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[3];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinPosition(blendWeight, matrixIndex);
+
+    return _skinnedPosition;    
+}
+
+void skinTangentSpaceVector(vec3 vector, float blendWeight, int matrixIndex)
+{
+    vec3 tmp;
+
+    tmp.x = dot(vector, u_matrixPalette[matrixIndex].xyz);
+    tmp.y = dot(vector, u_matrixPalette[matrixIndex + 1].xyz);
+    tmp.z = dot(vector, u_matrixPalette[matrixIndex + 2].xyz);
+
+    _skinnedNormal += blendWeight * tmp;
+}
+
+vec3 getTangentSpaceVector(vec3 vector)
+{
+    _skinnedNormal = vec3(0.0);
+
+    // Transform normal to view space using 
+    // matrix palette with four matrices used to transform a vertex.
+
+    float blendWeight = a_blendWeights[0];
+    int matrixIndex = int (a_blendIndices[0]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[1];
+    matrixIndex = int(a_blendIndices[1]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[2];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    blendWeight = a_blendWeights[3];
+    matrixIndex = int(a_blendIndices[2]) * 3;
+    skinTangentSpaceVector(vector, blendWeight, matrixIndex);
+
+    return _skinnedNormal;
+}
+
+vec3 getNormal()
+{
+    return getTangentSpaceVector(a_normal);
+}
+
+vec3 getTangent()
+{
+    return getTangentSpaceVector(a_tangent);
+}
+
+vec3 getBinormal()
+{
+    return getTangentSpaceVector(a_binormal);
+}
+
+#else
+
+vec4 getPosition()
+{
+    return a_position;    
+}
+
+vec3 getNormal()
+{
+    return a_normal;
+}
+
+vec3 getTangent()
+{
+    return a_tangent;
+}
+
+vec3 getBinormal()
+{
+    return a_binormal;
+}
+
+#endif
+
 #if defined(POINT_LIGHT)
 
 uniform mat4 u_worldViewMatrix;                 // Matrix to tranform a position to view space.
 uniform vec3 u_pointLightPosition;              // Position
-uniform float u_pointLightRadius;               // Radius 
+uniform float u_pointLightRangeInverse;         // Inverse of light range.
 varying vec3 v_vertexToPointLightDirection;     // Direction of point light w.r.t current vertex in tangent space.
 varying float v_pointLightAttenuation;          // Attenuation of point light.
 
@@ -32,23 +158,24 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     vec3 vertexToSpotLightDirection = tangentSpaceTransformMatrix * lightDirection;
 
     // Attenuation
-    v_pointLightAttenuation = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    v_pointLightAttenuation = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
-    v_vertexToSpotLightDirection =  vertexToSpotLightDirection;
+    v_vertexToPointLightDirection =  vertexToSpotLightDirection;
 }
 
 #elif defined(SPOT_LIGHT)
 
-uniform mat4 u_worldViewMatrix;                  // Matrix to tranform a position to view space.
-uniform vec3 u_spotLightPosition;                // Position
-uniform vec3 u_spotLightDirection;               // Direction
-varying vec3 v_spotLightDirection;               // Direction of spot light in tangent space.
-varying vec3 v_vertexToSpotLightDirection;       // Direction of the spot light w.r.t current vertex in tangent space.
+uniform mat4 u_worldViewMatrix;                 // Matrix to tranform a position to view space.
+uniform vec3 u_spotLightPosition;               // Position
+uniform float u_spotLightRangeInverse;          // Inverse of light range.
+uniform vec3 u_spotLightDirection;              // Direction
+varying vec3 v_spotLightDirection;              // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;      // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
 
     // Transform spot light direction to tangent space.
@@ -59,6 +186,9 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     
     // Transform current light direction to tangent space.
     lightDirection = tangentSpaceTransformMatrix * lightDirection;
+    
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
 
     // Output light direction.
     v_vertexToSpotLightDirection = lightDirection;
@@ -66,30 +196,37 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
 
 #else
 
-uniform vec3 u_lightDirection;                    // Direction
-varying vec3 v_directionalLightDirection;         // Direction of light in tangent space.
+uniform vec3 u_lightDirection;                  // Direction
+varying vec3 v_lightDirection;                  // Direction of light in tangent space.
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
     // Transform light direction to tangent space.
-    v_directionalLightDirection = tangentSpaceTransformMatrix * u_lightDirection;
+    v_lightDirection = tangentSpaceTransformMatrix * u_lightDirection;
 }
 
 #endif
 
 void main()
 {
+    vec4 position = getPosition();
+    vec3 normal = getNormal();
+    vec3 tangent = getTangent();
+    vec3 binormal = getBinormal();
+    
     // Transform position to clip space.
-    gl_Position = u_worldViewProjectionMatrix * a_position;
+    gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform the normal, tangent and binormals to  view space.
     mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
-    vec3 tangentVector  = inverseTransposeWorldViewMatrix * a_tangent;
-    vec3 normalVector = inverseTransposeWorldViewMatrix * a_normal;
-    vec3 binormalVector = inverseTransposeWorldViewMatrix * a_binormal;
+    vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * tangent);
+    vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal);
+    vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * binormal);
 
     // Create a transform to convert a vector to tangent space.
-    mat3 tangentSpaceTransformMatrix = mat3(tangentVector, binormalVector, normalVector);
+    mat3 tangentSpaceTransformMatrix = mat3(tangentVector.x, binormalVector.x, normalVector.x,
+                                            tangentVector.y, binormalVector.y, normalVector.y,
+                                            tangentVector.z, binormalVector.z, normalVector.z);
 
     // Apply light.
     applyLight(tangentSpaceTransformMatrix);

+ 12 - 7
gameplay/res/shaders/colored-specular.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color
@@ -52,10 +54,11 @@ void applyLight()
 
 #elif defined(SPOT_LIGHT)
 
-uniform vec3 u_spotLightDirection;          // Direction of the spot light.
-uniform float u_spotLightInnerAngleCos;     // The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;     // The soft outer part [0.0 - 1.0]
-varying vec3 v_vertexToSpotLightDirection;  // Light direction w.r.t current vertex.
+uniform vec3 u_spotLightDirection;              // Direction of the spot light.
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_vertexToSpotLightDirection;      // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -75,15 +78,17 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
 
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, cameraDirection, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-uniform vec3 u_lightDirection;       // Light direction
+uniform vec3 u_lightDirection;                  // Light direction
 
 void applyLight()
 {

+ 14 - 4
gameplay/res/shaders/colored-specular.vsh

@@ -119,7 +119,7 @@ vec3 getNormal()
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_pointLightPosition;                  // Position
-uniform float u_pointLightRadius;                   // Radius 
+uniform float u_pointLightRangeInverse;             // Inverse of light range. 
 varying vec4 v_vertexToPointLightDirection;         // Light direction w.r.t current vertex.
 
 void applyLight(vec4 position)
@@ -134,7 +134,7 @@ void applyLight(vec4 position)
     vertexToPointLightDirection.xyz = lightDirection;
     
     // Attenuation
-    vertexToPointLightDirection.w = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    vertexToPointLightDirection.w = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
     v_vertexToPointLightDirection =  vertexToPointLightDirection;
@@ -144,7 +144,9 @@ void applyLight(vec4 position)
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
 varying vec3 v_vertexToSpotLightDirection;          // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
 
 void applyLight(vec4 position)
 {
@@ -152,7 +154,13 @@ void applyLight(vec4 position)
     vec4 positionWorldViewSpace = u_worldViewMatrix * position;
 
     // Compute the light direction with light position and the vertex position.
-    v_vertexToSpotLightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
+    // Compute the light direction with light position and the vertex position.
+    v_vertexToSpotLightDirection = lightDirection;
 }
 
 #else
@@ -172,7 +180,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Compute the camera direction.

+ 20 - 15
gameplay/res/shaders/colored.fsh

@@ -1,17 +1,19 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
-uniform vec3 u_lightColor;                  // Light color
-uniform vec3 u_ambientColor;                // Ambient color
-uniform vec4 u_diffuseColor;                // Diffuse color
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec4 u_diffuseColor;                    // Diffuse color
 
 // Inputs
-varying vec3 v_normalVector;                // NormalVector in view space.
+varying vec3 v_normalVector;                    // NormalVector in view space.
 
 // Global variables
-vec4 _baseColor;                            // Base color
-vec3 _ambientColor;                         // Ambient Color
-vec3 _diffuseColor;                         // Diffuse Color
+vec4 _baseColor;                                // Base color
+vec3 _ambientColor;                             // Ambient Color
+vec3 _diffuseColor;                             // Diffuse Color
 
 void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 {
@@ -26,7 +28,7 @@ void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 
 #if defined(POINT_LIGHT)
 
-varying vec4 v_vertexToPointLightDirection;   // Light direction w.r.t current vertex.
+varying vec4 v_vertexToPointLightDirection;     // Light direction w.r.t current vertex.
 
 void applyLight()
 {
@@ -42,10 +44,11 @@ void applyLight()
 
 #elif defined(SPOT_LIGHT)
 
-uniform vec3 u_spotLightDirection;          // Direction of the spot light.
-uniform float u_spotLightInnerAngleCos;     // The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;     // The soft outer part [0.0 - 1.0]
-varying vec3 v_vertexToSpotLightDirection;  // Light direction w.r.t current vertex.
+uniform vec3 u_spotLightDirection;              // Direction of the spot light.
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_vertexToSpotLightDirection;      // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -64,15 +67,17 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
 
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-uniform vec3 u_lightDirection;       // Light direction
+uniform vec3 u_lightDirection;       	        // Light direction
 
 void applyLight()
 {

+ 10 - 5
gameplay/res/shaders/colored.vsh

@@ -114,12 +114,11 @@ vec3 getNormal()
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_pointLightPosition;                  // Position
-uniform float u_pointLightRadius;                   // Radius 
+uniform float u_pointLightRangeInverse;             // Inverse of light range.
 varying vec4 v_vertexToPointLightDirection;         // Light direction w.r.t current vertex.
 
 void applyLight(vec4 position)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * position;
     
     // Compute the light direction.
@@ -129,7 +128,7 @@ void applyLight(vec4 position)
     vertexToPointLightDirection.xyz = lightDirection;
     
     // Attenuation.
-    vertexToPointLightDirection.w = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    vertexToPointLightDirection.w = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
     v_vertexToPointLightDirection =  vertexToPointLightDirection;
@@ -139,16 +138,20 @@ void applyLight(vec4 position)
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
 varying vec3 v_vertexToSpotLightDirection;          // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
 
 void applyLight(vec4 position)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * position;
 
     // Compute the light direction.
     vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
 
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
     // Output light direction.
     v_vertexToSpotLightDirection = lightDirection;
 }
@@ -170,7 +173,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Apply light.

+ 12 - 7
gameplay/res/shaders/diffuse-specular.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color
@@ -53,10 +55,11 @@ void applyLight()
 
 #elif defined(SPOT_LIGHT)
 
-uniform vec3 u_spotLightDirection;          // Direction of the spot light.
-uniform float u_spotLightInnerAngleCos;     // The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;     // The soft outer part [0.0 - 1.0]
-varying vec3 v_vertexToSpotLightDirection;  // Light direction w.r.t current vertex.
+uniform vec3 u_spotLightDirection;              // Direction of the spot light.
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_vertexToSpotLightDirection;      // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -76,15 +79,17 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
     
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, cameraDirection, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-uniform vec3 u_lightDirection;       // Light direction
+uniform vec3 u_lightDirection;                  // Light direction
 
 void applyLight()
 {

+ 21 - 12
gameplay/res/shaders/diffuse-specular.vsh

@@ -117,14 +117,13 @@ vec3 getNormal()
 
 #if defined(POINT_LIGHT)
 
-uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
-uniform vec3 u_pointLightPosition;                  // Position
-uniform float u_pointLightRadius;                   // Radius 
-varying vec4 v_vertexToPointLightDirection;         // Light direction w.r.t current vertex.
+uniform mat4 u_worldViewMatrix;                         // Matrix to tranform a position to view space.
+uniform vec3 u_pointLightPosition;                      // Position
+uniform float u_pointLightRangeInverse;                 // Inverse of light range.
+varying vec4 v_vertexToPointLightDirection;             // Light direction w.r.t current vertex.
 
 void applyLight(vec4 position)
 {
-    // World space position.
     vec4 positionWorldViewSpace = u_worldViewMatrix * position;
     
     // Compute the light direction with light position and the vertex position.
@@ -134,7 +133,7 @@ void applyLight(vec4 position)
     vertexToPointLightDirection.xyz = lightDirection;
 
     // Attenuation
-    vertexToPointLightDirection.w = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    vertexToPointLightDirection.w = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
     v_vertexToPointLightDirection =  vertexToPointLightDirection;
@@ -142,9 +141,11 @@ void applyLight(vec4 position)
 
 #elif defined(SPOT_LIGHT)
 
-uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
-uniform vec3 u_spotLightPosition;                   // Position
-varying vec3 v_vertexToSpotLightDirection;          // Light direction w.r.t current vertex.
+uniform mat4 u_worldViewMatrix;                         // Matrix to tranform a position to view space.
+uniform vec3 u_spotLightPosition;                       // Position
+uniform float u_spotLightRangeInverse;                  // Inverse of light range.
+varying vec3 v_vertexToSpotLightDirection;              // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;                   // Attenuation of spot light.
 
 void applyLight(vec4 position)
 {
@@ -152,7 +153,13 @@ void applyLight(vec4 position)
     vec4 positionWorldViewSpace = u_worldViewMatrix * position;
 
     // Compute the light direction with light position and the vertex position.
-    v_vertexToSpotLightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
+    // Compute the light direction with light position and the vertex position.
+    v_vertexToSpotLightDirection = lightDirection;
 }
 
 #else
@@ -172,7 +179,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Compute the camera direction.
@@ -184,4 +193,4 @@ void main()
 
     // Pass on the texture coordinates to Fragment shader.
     v_texCoord = a_texCoord;
-}
+}

+ 21 - 17
gameplay/res/shaders/diffuse.fsh

@@ -1,18 +1,20 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
-uniform vec3 u_lightColor;                  // Light color
-uniform vec3 u_ambientColor;                // Ambient color
-uniform sampler2D u_diffuseTexture;         // Diffuse texture.
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform sampler2D u_diffuseTexture;             // Diffuse texture.
 
 // Inputs
-varying vec3 v_normalVector;                // NormalVector in view space.
-varying vec2 v_texCoord;                    // Texture coordinate (u, v).
+varying vec3 v_normalVector;                    // NormalVector in view space.
+varying vec2 v_texCoord;                        // Texture coordinate (u, v).
 
 // Global variables
-vec4 _baseColor;                            // Base color
-vec3 _ambientColor;                         // Ambient Color
-vec3 _diffuseColor;                         // Diffuse Color
+vec4 _baseColor;                                // Base color
+vec3 _ambientColor;                             // Ambient Color
+vec3 _diffuseColor;                             // Diffuse Color
 
 void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 {
@@ -27,7 +29,7 @@ void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 
 #if defined(POINT_LIGHT)
 
-varying vec4 v_vertexToPointLightDirection;  // Light direction w.r.t current vertex.
+varying vec4 v_vertexToPointLightDirection;     // Light direction w.r.t current vertex.
 
 void applyLight()
 {
@@ -43,10 +45,11 @@ void applyLight()
 
 #elif defined(SPOT_LIGHT)
 
-uniform vec3 u_spotLightDirection;          // Direction of the spot light.
-uniform float u_spotLightInnerAngleCos;     // The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;     // The soft outer part [0.0 - 1.0]
-varying vec3 v_vertexToSpotLightDirection;  // Light direction w.r.t current vertex.
+uniform vec3 u_spotLightDirection;              // Direction of the spot light.
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_vertexToSpotLightDirection;      // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
 
 float lerpstep( float lower, float upper, float s)
 {
@@ -65,19 +68,20 @@ void applyLight()
     // Calculate spot light effect.
     float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
 
-    // Intensity of spot depends on the part of the cone the light direction points to (inner or outer).
-    float spotLightAttenuation = lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
 
     lighting(normalVector, vertexToSpotLightDirection, spotLightAttenuation);
 }
 
 #else
 
-uniform vec3 u_lightDirection;       // Light direction
+uniform vec3 u_lightDirection;                  // Light direction
 
 void applyLight()
 {
-    // Normalize the vectors.
     vec3 normalVector = normalize(v_normalVector);
     vec3 lightDirection = normalize(u_lightDirection);
 

+ 10 - 3
gameplay/res/shaders/diffuse.vsh

@@ -117,7 +117,7 @@ vec3 getNormal()
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_pointLightPosition;                  // Position
-uniform float u_pointLightRadius;                   // Radius
+uniform float u_pointLightRange;                    // Inverse of light range.
 varying vec4 v_vertexToPointLightDirection;         // Light direction w.r.t current vertex.
 
 void applyLight(vec4 position)
@@ -132,7 +132,7 @@ void applyLight(vec4 position)
     vertexToPointLightDirection.xyz = lightDirection;
     
     // Attenuation
-    vertexToPointLightDirection.w = 1 - dot (lightDirection * u_pointLightRadius, lightDirection * u_pointLightRadius);
+    vertexToPointLightDirection.w = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
     v_vertexToPointLightDirection =  vertexToPointLightDirection;
@@ -142,7 +142,9 @@ void applyLight(vec4 position)
 
 uniform mat4 u_worldViewMatrix;                     // Matrix to tranform a position to view space.
 uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
 varying vec3 v_vertexToSpotLightDirection;          // Light direction w.r.t current vertex.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
 
 void applyLight(vec4 position)
 {
@@ -152,6 +154,9 @@ void applyLight(vec4 position)
     // Compute the light direction with light position and the vertex position.
     vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
 
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
     // Output light direction.
     v_vertexToSpotLightDirection = lightDirection;
 }
@@ -173,7 +178,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Apply light.

+ 140 - 28
gameplay/res/shaders/parallax-specular.fsh

@@ -1,28 +1,59 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
-uniform vec3 u_lightColor;                      // RGB color of the light
-uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec3 u_lightColor;                      // Light color.
+uniform vec3 u_ambientColor;                    // Ambient color.
 uniform float u_specularExponent;               // Specular exponent or shininess property.
-uniform float u_parallaxHeight;                 // Parallax height
-uniform sampler2D u_diffuseTexture;             // Diffuse texture
+uniform sampler2D u_diffuseTexture;             // Diffuse texture.
 uniform sampler2D u_bumpMapTexture;             // Height map texture
-uniform sampler2D u_normalMapTexture;           // Normal map texture    
+uniform sampler2D u_normalMapTexture;           // Normal map texture.
+uniform float u_parallaxHeight;                 // Parallax height
 
 // Inputs
-varying vec2 v_texCoord;                        // Texture coordinates (u,v)
-varying vec3 v_lightDirectionTangentSpace;      // Light direction in tangent space
-varying vec3 v_cameraDirectionTangentSpace;     // Camera direction in tangent space
+varying vec2 v_texCoord;                        // Texture Coordinate.
+varying vec3 v_cameraDirection;                 // Direction the camera is looking at in tangent space.
 
-void main()
+// Global variables
+vec4 _baseColor;                                // Base color
+vec3 _ambientColor;                             // Ambient Color
+vec3 _diffuseColor;                             // Diffuse Color
+vec3 _specularColor;                            // Specular color
+
+void lighting(vec3 normalVector, vec3 cameraDirection, vec3 lightDirection, float attenuation)
 {
-    // Normalize vectors.
-    vec3 lightDirection = normalize(v_lightDirectionTangentSpace);
-    vec3 cameraDirection = normalize(v_cameraDirectionTangentSpace);
+    // Ambient
+    _ambientColor = _baseColor.rgb * u_ambientColor;
+
+    // Diffuse
+    float diffuseIntensity = attenuation * max(0.0, dot(normalVector, lightDirection));
+    diffuseIntensity = max(0.0, diffuseIntensity);
+    _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;
+
+    // Specular
+    vec3 halfVector = normalize(cameraDirection + lightDirection);
+    float specularIntensity = attenuation * max(0.0, pow(dot(normalVector, halfVector), u_specularExponent));
+    specularIntensity = max(0.0, specularIntensity);
+    _specularColor = u_lightColor * _baseColor.rgb * specularIntensity;
+}
+
+#if defined(POINT_LIGHT)
+
+varying vec3 v_vertexToPointLightDirection;     // Light direction w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;          // Attenuation of point light.
+
+void applyLight()
+{
+    // Normalize the vectors.
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 vertexToPointLightDirection = normalize(v_vertexToPointLightDirection);
     
+    float pointLightAttenuation = clamp(v_pointLightAttenuation, 0.0, 1.0);
+
     // Get the height in the bumpmap texture.
     float height = texture2D(u_bumpMapTexture, v_texCoord).r;
-    
+
     // Compute offset within the range (-parallax height to +parallax height).
     float offset = u_parallaxHeight * (2.0 * height - 1.0);
     vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
@@ -31,26 +62,107 @@ void main()
     // Find out the mean height.
     height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
     offset = u_parallaxHeight * (height - 1.0);
-    parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
-    
+    parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
+
+    // Fetch normals from the normal map with the modified texture coordinates.
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
+
     // Fetch diffuse color from texture.
-    vec4 diffuseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
     
-    // Ambient
-    vec3 lightColor = u_ambientColor;
+    lighting(normalVector, cameraDirection, vertexToPointLightDirection, pointLightAttenuation);
+}
+
+#elif defined(SPOT_LIGHT)
+
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_spotLightDirection;              // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;      // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
+
+float lerpstep( float lower, float upper, float s)
+{
+    return clamp( ( s - lower ) / ( upper - lower ), 0.0, 1.0 );
+}
+
+void applyLight()
+{
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 spotLightDirection = normalize(v_spotLightDirection);
+    vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection);
+
+    // "-lightDirection" because light direction points in opposite direction to
+    // to spot direction.
+    // Calculate spot light effect.
+    float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
+    
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+
+    // Get the height in the bumpmap texture.
+    float height = texture2D(u_bumpMapTexture, v_texCoord).r;
+
+    // Compute offset within the range (-parallax height to +parallax height).
+    float offset = u_parallaxHeight * (2.0 * height - 1.0);
+    vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
+
+    // Compute offset again with the new texture coordinates to get better precision.
+    // Find out the mean height.
+    height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
+    offset = u_parallaxHeight * (height - 1.0);
+    parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
 
-    // Diffuse
     // Fetch normals from the normal map with the modified texture coordinates.
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
-    float diffuseIntensity = max(0.0, dot(normalVector, lightDirection));
-    lightColor += (u_lightColor * diffuseIntensity);
 
-    // Specular
-    vec3 halfVector = normalize(cameraDirection + lightDirection);
-    float specularIntensity = pow(max(0.0, dot(normalVector, halfVector)), u_specularExponent);
+    // Fetch diffuse color from texture.
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+
+    lighting(normalVector, cameraDirection, vertexToSpotLightDirection, spotLightAttenuation);
+}
+
+#else
+
+varying vec3 v_lightDirection;                  // Direction of light in tangent space.
+
+void applyLight()
+{
+    // Normalize vectors.
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 lightDirection = normalize(v_lightDirection);
+
+    // Get the height in the bumpmap texture.
+    float height = texture2D(u_bumpMapTexture, v_texCoord).r;
+
+    // Compute offset within the range (-parallax height to +parallax height).
+    float offset = u_parallaxHeight * (2.0 * height - 1.0);
+    vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
+
+    // Compute offset again with the new texture coordinates to get better precision.
+    // Find out the mean height.
+    height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
+    offset = u_parallaxHeight * (height - 1.0);
+    parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
+
+    // Fetch normals from the normal map with the modified texture coordinates.
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
+
+    // Fetch diffuse color from texture.
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+
+    lighting(normalVector, cameraDirection, -lightDirection, 1.0);
+}
+#endif
+
+void main()
+{
+    // Apply light
+    applyLight();
 
-    // Light the pixel.
-    gl_FragColor = diffuseColor;
-    gl_FragColor.rgb *= lightColor;
-    gl_FragColor.rgb += vec3(diffuseColor.rgb * specularIntensity);
+    // Light the pixel
+    gl_FragColor.a = _baseColor.a;
+    gl_FragColor.rgb = _ambientColor + _diffuseColor + _specularColor;
 }

+ 100 - 25
gameplay/res/shaders/parallax-specular.vsh

@@ -1,21 +1,97 @@
 // Uniforms
-uniform    vec3 u_lightDirection;                    // Direction of the light
-uniform mat4 u_worldViewProjectionMatrix;            // Matrix to transform a position to clip space.
-uniform mat4 u_inverseTransposeWorldViewMatrix;      // Matrix to transform a normal to view space.
-uniform mat4 u_worldMatrix;                          // Matrix to tranform a position to world space.
-uniform vec3 u_cameraPosition;                       // Position of the camera.
+uniform mat4 u_worldViewMatrix;                     // Matrix to transform a position to view space.
+uniform mat4 u_worldViewProjectionMatrix;           // Matrix to transform a position to clip space.
+uniform mat4 u_inverseTransposeWorldViewMatrix;     // Matrix to transform a normal to view space.
+uniform vec3 u_cameraPosition;                      // Position of the camera.
+
 
 // Inputs
-attribute vec4 a_position;                           // Vertex Position (x, y, z, w)
-attribute vec3 a_normal;                             // Vertex Normal (x, y, z)
-attribute vec2 a_texCoord;                           // Vertex Texture Coordinate (u, v)
-attribute vec3 a_tangent;                            // Vertex Tangent (x, y, z)
-attribute vec3 a_binormal;                           // Vertex Binormal (actually Bi-tangent) (x, y, z)
+attribute vec4 a_position;                          // Vertex Position (x, y, z, w)
+attribute vec3 a_normal;                            // Vertex Normal (x, y, z)
+attribute vec2 a_texCoord;                          // Vertex Texture Coordinate (u, v)
+attribute vec3 a_tangent;                           // Vertex Tangent (x, y, z)
+attribute vec3 a_binormal;                          // Vertex Binormal (actually Bi-tangent) (x, y, z)
 
 // Outputs
-varying vec2 v_texCoord;                             // Texture Coordinate (u,v)
-varying vec3 v_lightDirectionTangentSpace;           // Direction of the light in tangent space.
-varying vec3 v_cameraDirectionTangentSpace;          // Direction the camera is looking at in tangent space.
+varying vec2 v_texCoord;                            // Texture Coordinate (u,v)
+varying vec3 v_cameraDirection;                     // Direction the camera is looking at in tangent space.
+
+#if defined(POINT_LIGHT)
+
+uniform vec3 u_pointLightPosition;                  // Position
+uniform float u_pointLightRangeInverse;             // Inverse of light range 
+varying vec3 v_vertexToPointLightDirection;         // Direction of point light w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;              // Attenuation of point light.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
+    // Compute the light direction with light position and the vertex position.
+    vec3 lightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
+    
+    // Transform current light direction to tangent space.
+    vec3 vertexToPointLightDirection = tangentSpaceTransformMatrix * lightDirection;
+
+    // Attenuation
+    v_pointLightAttenuation = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
+
+    // Output light direction.
+    v_vertexToPointLightDirection =  vertexToPointLightDirection;
+}
+
+#elif defined(SPOT_LIGHT)
+
+uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
+uniform vec3 u_spotLightDirection;                  // Direction
+varying vec3 v_spotLightDirection;                  // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;          // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+
+    // Transform spot light direction to tangent space.
+    v_spotLightDirection = tangentSpaceTransformMatrix * u_spotLightDirection;
+
+    // Compute the light direction with light position and the vertex position.
+    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+    
+    // Transform current light direction to tangent space.
+    lightDirection = tangentSpaceTransformMatrix * lightDirection;
+    
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
+    // Output light direction.
+    v_vertexToSpotLightDirection = lightDirection;
+}
+
+#else
+
+uniform vec3 u_lightDirection;                      // Direction
+varying vec3 v_lightDirection;                      // Direction of light in tangent space.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
+    // Transform light direction to tangent space.
+    v_lightDirection = tangentSpaceTransformMatrix * u_lightDirection;
+}
+
+#endif
 
 void main()
 {
@@ -23,20 +99,19 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * a_position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
-    vec3 tangentVector  = inverseTransposeWorldViewMatrix * a_tangent;
-    vec3 normalVector = inverseTransposeWorldViewMatrix * a_normal;
-    vec3 binormalVector = inverseTransposeWorldViewMatrix * a_binormal;
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
+    vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * a_tangent);
+    vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * a_normal);
+    vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * a_binormal);
 
     // Create a transform to convert a vector to tangent space.
-    mat3 tangentSpaceTransformMatrix = mat3(tangentVector, binormalVector, normalVector);
-
-    // Transform light direction to tangent space.
-    v_lightDirectionTangentSpace = tangentSpaceTransformMatrix * u_lightDirection;
-
-    // Compute camera direction and transform it to tangent space.
-    vec4 positionWorldSpace = u_worldMatrix * a_position;
-    v_cameraDirectionTangentSpace = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldSpace.xyz);
+    mat3 tangentSpaceTransformMatrix = mat3(tangentVector.x, binormalVector.x, normalVector.x,
+                                            tangentVector.y, binormalVector.y, normalVector.y,
+                                            tangentVector.z, binormalVector.z, normalVector.z);
+    // Apply light.
+    applyLight(tangentSpaceTransformMatrix);
 
     // Pass on the texture coordinates to Fragment shader.
     v_texCoord = a_texCoord;

+ 132 - 21
gameplay/res/shaders/parallax.fsh

@@ -1,27 +1,51 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
-uniform vec3 u_lightColor;                      // RGB color of the light
-uniform vec3 u_ambientColor;                    // Ambient color
-uniform sampler2D u_diffuseTexture;             // Diffuse texture
+uniform vec3 u_lightColor;                      // Light color.
+uniform vec3 u_ambientColor;                    // Ambient color.
+uniform sampler2D u_diffuseTexture;             // Diffuse texture.
 uniform sampler2D u_bumpMapTexture;             // Height map texture
-uniform sampler2D u_normalMapTexture;           // Normal map texture    
+uniform sampler2D u_normalMapTexture;           // Normal map texture.
 uniform float u_parallaxHeight;                 // Parallax height
 
 // Inputs
-varying vec2 v_texCoord;                        // Texture coordinates (u,v)
-varying vec3 v_lightDirectionTangentSpace;      // Light direction in tangent space
-varying vec3 v_cameraDirectionTangentSpace;     // Camera direction in tangent space
+varying vec2 v_texCoord;                        // Texture Coordinate.
+varying vec3 v_cameraDirection;                 // Direction the camera is looking at in tangent space.
 
-void main()
+// Global variables
+vec4 _baseColor;                                // Base color
+vec3 _ambientColor;                             // Ambient Color
+vec3 _diffuseColor;                             // Diffuse Color
+
+void lighting(vec3 normalVector, vec3 lightDirection, float attenuation)
 {
-    // Normalize vectors.
-    vec3 lightDirection = normalize(v_lightDirectionTangentSpace);
-    vec3 cameraDirection = normalize(v_cameraDirectionTangentSpace);
+    // Ambient
+    _ambientColor = _baseColor.rgb * u_ambientColor;
+
+    // Diffuse
+    float diffuseIntensity = attenuation * max(0.0, dot(normalVector, lightDirection));
+    diffuseIntensity = max(0.0, diffuseIntensity);
+    _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;
+}
+
+#if defined(POINT_LIGHT)
+
+varying vec3 v_vertexToPointLightDirection;     // Light direction w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;          // Attenuation of point light.
+
+void applyLight()
+{
+    // Normalize the vectors.
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 vertexToPointLightDirection = normalize(v_vertexToPointLightDirection);
     
+    float pointLightAttenuation = clamp(v_pointLightAttenuation, 0.0, 1.0);
+
     // Get the height in the bumpmap texture.
     float height = texture2D(u_bumpMapTexture, v_texCoord).r;
-    
+
     // Compute offset within the range (-parallax height to +parallax height).
     float offset = u_parallaxHeight * (2.0 * height - 1.0);
     vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
@@ -31,19 +55,106 @@ void main()
     height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
     offset = u_parallaxHeight * (height - 1.0);
     parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
-    
+
+    // Fetch normals from the normal map with the modified texture coordinates.
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
+
     // Fetch diffuse color from texture.
-    gl_FragColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
     
-    // Ambient
-    vec3 lightColor = u_ambientColor;
+    lighting(normalVector, vertexToPointLightDirection, pointLightAttenuation);
+}
+
+#elif defined(SPOT_LIGHT)
+
+uniform float u_spotLightInnerAngleCos;         // The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;         // The soft outer part [0.0 - 1.0]
+varying vec3 v_spotLightDirection;              // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;      // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;           // Attenuation of spot light.
+
+float lerpstep( float lower, float upper, float s)
+{
+    return clamp( ( s - lower ) / ( upper - lower ), 0.0, 1.0 );
+}
+
+void applyLight()
+{
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 spotLightDirection = normalize(v_spotLightDirection);
+    vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection);
+
+    // "-lightDirection" because light direction points in opposite direction to
+    // to spot direction.
+    // Calculate spot light effect.
+    float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
+    
+    // Intensity of spot depends on the spot light attenuation and the 
+    // part of the cone vertexToSpotLightDirection points to (inner or outer).
+    float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
+    spotLightAttenuation *= lerpstep(u_spotLightOuterAngleCos, u_spotLightInnerAngleCos, spotCurrentAngleCos);
+
+    // Get the height in the bumpmap texture.
+    float height = texture2D(u_bumpMapTexture, v_texCoord).r;
+
+    // Compute offset within the range (-parallax height to +parallax height).
+    float offset = u_parallaxHeight * (2.0 * height - 1.0);
+    vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
+
+    // Compute offset again with the new texture coordinates to get better precision.
+    // Find out the mean height.
+    height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
+    offset = u_parallaxHeight * (height - 1.0);
+    parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
 
-    // Diffuse
     // Fetch normals from the normal map with the modified texture coordinates.
     vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
-    float diffuseIntensity = max(0.0, dot(normalVector, lightDirection));
-    lightColor += (u_lightColor * diffuseIntensity);
 
-    // Light the pixel.
-    gl_FragColor.rgb *= lightColor;
+    // Fetch diffuse color from texture.
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+
+    lighting(normalVector, vertexToSpotLightDirection, spotLightAttenuation);
 }
+
+#else
+
+varying vec3 v_lightDirection;                      // Direction of light in tangent space.
+
+void applyLight()
+{
+    // Normalize vectors.
+    vec3 cameraDirection = normalize(v_cameraDirection);
+    vec3 lightDirection = normalize(v_lightDirection);
+
+    // Get the height in the bumpmap texture.
+    float height = texture2D(u_bumpMapTexture, v_texCoord).r;
+
+    // Compute offset within the range (-parallax height to +parallax height).
+    float offset = u_parallaxHeight * (2.0 * height - 1.0);
+    vec2 parallaxTexCoord = v_texCoord + (cameraDirection.xy * offset);
+
+    // Compute offset again with the new texture coordinates to get better precision.
+    // Find out the mean height.
+    height += texture2D(u_bumpMapTexture, parallaxTexCoord).r;
+    offset = u_parallaxHeight * (height - 1.0);
+    parallaxTexCoord = v_texCoord + ( cameraDirection.xy * offset);
+
+    // Fetch normals from the normal map with the modified texture coordinates.
+    vec3 normalVector = normalize(texture2D(u_normalMapTexture, parallaxTexCoord).xyz * 2.0 - 1.0);
+
+    // Fetch diffuse color from texture.
+    _baseColor = texture2D(u_diffuseTexture, parallaxTexCoord);
+
+    lighting(normalVector, -lightDirection, 1.0);
+}
+#endif
+
+void main()
+{
+    // Apply light
+    applyLight();
+
+    // Light the pixel
+    gl_FragColor.a = _baseColor.a;
+    gl_FragColor.rgb = _ambientColor + _diffuseColor;
+}

+ 98 - 23
gameplay/res/shaders/parallax.vsh

@@ -1,21 +1,97 @@
 // Uniforms
-uniform    vec3 u_lightDirection;                    // Direction of the light
-uniform mat4 u_worldViewProjectionMatrix;            // Matrix to transform a position to clip space.
-uniform mat4 u_inverseTransposeWorldViewMatrix;      // Matrix to transform a normal to view space.
-uniform mat4 u_worldMatrix;                          // Matrix to tranform a position to world space.
-uniform vec3 u_cameraPosition;                       // Position of the camera.
+uniform mat4 u_worldViewMatrix;                     // Matrix to transform a position to view space.
+uniform mat4 u_worldViewProjectionMatrix;           // Matrix to transform a position to clip space.
+uniform mat4 u_inverseTransposeWorldViewMatrix;     // Matrix to transform a normal to view space.
+uniform vec3 u_cameraPosition;                      // Position of the camera.
+
 
 // Inputs
-attribute vec4 a_position;                           // Vertex Position (x, y, z, w)
-attribute vec3 a_normal;                             // Vertex Normal (x, y, z)
-attribute vec2 a_texCoord;                           // Vertex Texture Coordinate (u, v)
-attribute vec3 a_tangent;                            // Vertex Tangent (x, y, z)
-attribute vec3 a_binormal;                           // Vertex Binormal (actually Bi-tangent) (x, y, z)
+attribute vec4 a_position;                          // Vertex Position (x, y, z, w)
+attribute vec3 a_normal;                            // Vertex Normal (x, y, z)
+attribute vec2 a_texCoord;                          // Vertex Texture Coordinate (u, v)
+attribute vec3 a_tangent;                           // Vertex Tangent (x, y, z)
+attribute vec3 a_binormal;                          // Vertex Binormal (actually Bi-tangent) (x, y, z)
 
 // Outputs
-varying vec2 v_texCoord;                             // Texture Coordinate (u,v)
-varying vec3 v_lightDirectionTangentSpace;           // Direction of the light in tangent space.
-varying vec3 v_cameraDirectionTangentSpace;          // Direction the camera is looking at in tangent space.
+varying vec2 v_texCoord;                            // Texture Coordinate (u,v)
+varying vec3 v_cameraDirection;                     // Direction the camera is looking at in tangent space.
+
+#if defined(POINT_LIGHT)
+
+uniform vec3 u_pointLightPosition;                  // Position
+uniform float u_pointLightRangeInverse;             // Inverse of light range 
+varying vec3 v_vertexToPointLightDirection;         // Direction of point light w.r.t current vertex in tangent space.
+varying float v_pointLightAttenuation;              // Attenuation of point light.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
+    // Compute the light direction with light position and the vertex position.
+    vec3 lightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
+    
+    // Transform current light direction to tangent space.
+    vec3 vertexToPointLightDirection = tangentSpaceTransformMatrix * lightDirection;
+
+    // Attenuation
+    v_pointLightAttenuation = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
+
+    // Output light direction.
+    v_vertexToPointLightDirection =  vertexToPointLightDirection;
+}
+
+#elif defined(SPOT_LIGHT)
+
+uniform vec3 u_spotLightPosition;                   // Position
+uniform float u_spotLightRangeInverse;              // Inverse of light range.
+uniform vec3 u_spotLightDirection;                  // Direction
+varying vec3 v_spotLightDirection;                  // Direction of spot light in tangent space.
+varying vec3 v_vertexToSpotLightDirection;          // Direction of the spot light w.r.t current vertex in tangent space.
+varying float v_spotLightAttenuation;               // Attenuation of spot light.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+
+    // Transform spot light direction to tangent space.
+    v_spotLightDirection = tangentSpaceTransformMatrix * u_spotLightDirection;
+
+    // Compute the light direction with light position and the vertex position.
+    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+    
+    // Transform current light direction to tangent space.
+    lightDirection = tangentSpaceTransformMatrix * lightDirection;
+    
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
+
+    // Output light direction.
+    v_vertexToSpotLightDirection = lightDirection;
+}
+
+#else
+
+uniform vec3 u_lightDirection;                      // Direction
+varying vec3 v_lightDirection;                      // Direction of light in tangent space.
+
+void applyLight(mat3 tangentSpaceTransformMatrix)
+{
+    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    
+    // Compute camera direction and transform it to tangent space.
+    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+    
+    // Transform light direction to tangent space.
+    v_lightDirection = tangentSpaceTransformMatrix * u_lightDirection;
+}
+
+#endif
 
 void main()
 {
@@ -23,20 +99,19 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * a_position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
-    vec3 tangentVector  = inverseTransposeWorldViewMatrix * a_tangent;
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
+    vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * a_tangent);
     vec3 normalVector = inverseTransposeWorldViewMatrix * a_normal;
     vec3 binormalVector = inverseTransposeWorldViewMatrix * a_binormal;
 
     // Create a transform to convert a vector to tangent space.
-    mat3 tangentSpaceTransformMatrix = mat3(tangentVector, binormalVector, normalVector);
-
-    // Transform light direction to tangent space.
-    v_lightDirectionTangentSpace = tangentSpaceTransformMatrix * u_lightDirection;
-
-    // Compute camera direction and transform it to tangent space.
-    vec4 positionWorldSpace = u_worldMatrix * a_position;
-    v_cameraDirectionTangentSpace = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldSpace.xyz);
+    mat3 tangentSpaceTransformMatrix = mat3(tangentVector.x, binormalVector.x, normalVector.x,
+                                            tangentVector.y, binormalVector.y, normalVector.y,
+                                            tangentVector.z, binormalVector.z, normalVector.z);
+    // Apply light.
+    applyLight(tangentSpaceTransformMatrix);
 
     // Pass on the texture coordinates to Fragment shader.
     v_texCoord = a_texCoord;

+ 4 - 2
gameplay/res/shaders/solid.fsh

@@ -1,6 +1,8 @@
-precision mediump float;
+#ifdef OPENGL_ES
+precision highp float;
+#endif
 
-// Diffuse color
+// Uniforms
 uniform vec4 u_diffuseColor;        // Diffuse color
 
 void main()

+ 1 - 1
gameplay/res/shaders/solid.vsh

@@ -1,4 +1,4 @@
-// Uniform
+// Uniforms
 uniform mat4 u_worldViewProjectionMatrix;        // Matrix to transform a position to clip space.
 
 // Inputs

+ 2 - 0
gameplay/res/shaders/textured.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform sampler2D u_diffuseTexture;     // Diffuse texture

+ 0 - 2
gameplay/src/Animation.cpp

@@ -64,7 +64,6 @@ Animation::Channel::Channel(AnimationTarget* target, int propertyId, Curve* curv
     assert(target->getAnimationPropertyComponentCount(propertyId));
 
     _target = target;
-    _target->addRef();
     _propertyId = propertyId;
     _curve = curve;
     _duration = duration;
@@ -72,7 +71,6 @@ Animation::Channel::Channel(AnimationTarget* target, int propertyId, Curve* curv
 
 Animation::Channel::~Channel()
 {
-    SAFE_RELEASE(_target);
     SAFE_DELETE(_curve);
 }
 

+ 10 - 25
gameplay/src/AnimationClip.cpp

@@ -12,7 +12,8 @@ namespace gameplay
 {
 
 AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
-    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0), _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
+    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0), 
+       _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
 {
     assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
 
@@ -27,37 +28,21 @@ AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long
 
 AnimationClip::~AnimationClip()
 {
+    // Explicitly stop this clip if it's currently playing so it gets removed from the controller
+    if (_isPlaying)
+    {
+        stop();
+    }
+
     std::vector<AnimationValue*>::iterator valueIter = _values.begin();
     while (valueIter != _values.end())
     {
         SAFE_DELETE(*valueIter);
         valueIter++;
     }
-    _values.clear();
-
-    if (_beginListeners)
-    {
-        std::vector<Listener*>::iterator bIter = _beginListeners->begin();
-        while (bIter != _beginListeners->end())
-        {
-            SAFE_DELETE(*bIter);
-            bIter++;
-        }
-        _beginListeners->clear();
-        SAFE_DELETE(_beginListeners);
-    }
 
-    if (_endListeners)
-    {
-        std::vector<Listener*>::iterator eIter = _endListeners->begin();
-        while (eIter != _endListeners->end())
-        {
-            SAFE_DELETE(*eIter);
-            eIter++;
-        }
-        _endListeners->clear();
-        SAFE_DELETE(_endListeners);
-    }
+    SAFE_DELETE(_beginListeners);
+    SAFE_DELETE(_endListeners);
 }
 
 const char* AnimationClip::getID() const

+ 3 - 2
gameplay/src/AnimationController.cpp

@@ -57,7 +57,6 @@ Animation* AnimationController::createAnimation(const char* id, AnimationTarget*
 
 Animation* AnimationController::createAnimationFromTo(const char* id, AnimationTarget* target, int propertyId, float* from, float* to, Curve::InterpolationType type, unsigned long duration)
 {
-    const unsigned int keyCount = 2;
     const unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
     float* keyValues = new float[2 * propertyComponentCount];
 
@@ -113,11 +112,11 @@ void AnimationController::stopAllAnimations()
     while (clipIter != _runningClips.end())
     {
         AnimationClip* clip = *clipIter;
-        clipIter = _runningClips.erase(clipIter);
         clip->_isPlaying = false;
         SAFE_RELEASE(clip);
         clipIter++;
     }
+    _runningClips.clear();
 
     _state = IDLE;
 }
@@ -229,6 +228,8 @@ void AnimationController::destroyAnimation(Animation* animation)
 
 void AnimationController::destroyAllAnimations()
 {
+    stopAllAnimations();
+
     std::vector<Animation*>::iterator itr = _animations.begin();
     
     while (itr != _animations.end())

+ 144 - 10
gameplay/src/AudioBuffer.cpp

@@ -31,7 +31,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     assert(path);
 
     // Search the cache for a stream from this file.
-    unsigned int bufferCount = __buffers.size();
+    unsigned int bufferCount = (unsigned int)__buffers.size();
     AudioBuffer* buffer = NULL;
     for (unsigned int i = 0; i < bufferCount; i++)
     {
@@ -44,7 +44,6 @@ AudioBuffer* AudioBuffer::create(const char* path)
     }
 
     ALuint alBuffer;
-    ALboolean loop = AL_TRUE;
     ALCenum al_error;
 
     // Load audio data into a buffer.
@@ -56,18 +55,47 @@ AudioBuffer* AudioBuffer::create(const char* path)
         alDeleteBuffers(1, &alBuffer);
         return NULL;
     }
-
-    std::string fullPath = FileSystem::getResourcePath();
-    fullPath += "/";
-    fullPath += path;
     
     // Load sound file.
-    alBuffer = alutCreateBufferFromFile(fullPath.c_str());
-    if (alBuffer == AL_NONE)
+    FILE* file = FileSystem::openFile(path, "rb");
+    if (!file)
     {
-        LOG_ERROR_VARG("AudioBuffer error (%d) loading file: %s", fullPath.c_str());
-        return NULL;
+        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        goto cleanup;
+    }
+    
+    // Read the file header
+    char header[12];
+    if (fread(header, 1, 12, file) != 12)
+    {
+        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        goto cleanup;
+    }
+    
+    // Check the file format
+    if (memcmp(header, "RIFF", 4) == 0)
+    {
+        if (!AudioBuffer::loadWav(file, alBuffer))
+        {
+            LOG_ERROR_VARG("Invalid wave file: %s", path);
+            goto cleanup;
+        }
+    }
+    else if(memcmp(header, "OGG", 3) == 0)
+    {
+        if (!AudioBuffer::loadOgg(file, alBuffer))
+        {
+            LOG_ERROR_VARG("Invalid ogg file: %s", path);
+            goto cleanup;
+        }
+    }
+    else
+    {
+        LOG_ERROR_VARG("Unsupported audio file: %s", path);
     }
+    
+    
+    fclose(file);
 
     buffer = new AudioBuffer(path, alBuffer);
 
@@ -75,6 +103,112 @@ AudioBuffer* AudioBuffer::create(const char* path)
     __buffers.push_back(buffer);
 
     return buffer;
+    
+cleanup:
+    
+    if (file)
+        fclose(file);
+    if (alBuffer)
+        alDeleteBuffers(1, &alBuffer);
+    return NULL;
+}
+    
+    
+bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
+{
+    unsigned char stream[12];
+    
+    // Verify the wave fmt magic value meaning format.
+    if (fread(stream, 1, 8, file) != 8 || memcmp(stream, "fmt ", 4) != 0 )
+        return false;
+    
+    // Check for a valid pcm format.
+    if(fread(stream, 1, 2, file) != 2 || stream[1] != 0 || stream[0] != 1)
+    {
+        LOG_ERROR("Unsupported audio file, not PCM format.");
+        return false;
+    }
+    
+    // Get the channel count (16-bit little-endian)
+    int channels;
+    if (fread(stream, 1, 2, file) != 2)
+        return false;
+    channels  = stream[1]<<8;
+    channels |= stream[0];
+    
+    // Get the sample frequency (32-bit little-endian) 
+    ALuint frequency;
+    if (fread(stream, 1, 4, file) != 4)
+        return false;
+    frequency  = stream[3]<<24;
+    frequency |= stream[2]<<16;
+    frequency |= stream[1]<<8;
+    frequency |= stream[0];
+    
+    // The next 6 bytes hold the block size and bytes-per-second. 
+    // We don't need that info, so just read and ignore it. 
+    // We could use this later if we need to know the duration.
+    if (fread(stream, 1, 6, file) != 6)
+        return false;
+    
+    // Get the bit depth (16-bit little-endian)
+    int bits;
+    if (fread(stream, 1, 2, file) != 2)
+        return false;
+    bits  = stream[1]<<8;
+    bits |= stream[0];
+    
+    
+    // Now convert the given channel count and bit depth into an OpenAL format. 
+    ALuint format = 0;
+    if(bits == 8)
+    {
+        if(channels == 1)
+            format = AL_FORMAT_MONO8;
+        else if(channels == 2)
+            format = AL_FORMAT_STEREO8;
+    }
+    else if(bits == 16)
+    {
+        if(channels == 1)
+            format = AL_FORMAT_MONO16;
+        else if(channels == 2)
+            format = AL_FORMAT_STEREO16;
+    }
+    else
+    {
+        LOG_ERROR_VARG("Incompatible format: (%d, %d)", channels, bits);
+        return false;
+    }
+    
+    // Read the data chunk, which will hold the decoded sample data 
+    if (fread(stream, 1, 4, file) != 4 || memcmp(stream, "data", 4) != 0)
+    {
+        LOG_ERROR("WAV file has no data.");
+        return false;
+    }
+    
+    // Read how much data is remaining and buffer it up.
+    unsigned int dataSize;
+    fread(&dataSize, sizeof(int), 1, file);
+    unsigned char* data = new unsigned char[dataSize];
+    if (fread(data, sizeof(unsigned char), dataSize, file) != dataSize)
+    {
+        LOG_ERROR("WAV file missing data.");
+        SAFE_DELETE_ARRAY(data);
+        return false;
+    }
+    alBufferData(buffer, format, data, dataSize, frequency);
+    SAFE_DELETE_ARRAY(data);
+    return true;
+}
+    
+// TODO:
+bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
+{
+    LOG_ERROR("Ogg Vorbis not supported yet");
+    
+    return false;
 }
 
 }

+ 4 - 0
gameplay/src/AudioBuffer.h

@@ -41,6 +41,10 @@ private:
      * @return The buffer from a file.
      */
     static AudioBuffer* create(const char* path);
+    
+    static bool loadWav(FILE* file, ALuint buffer);
+    
+    static bool loadOgg(FILE* file, ALuint buffer);
 
     std::string _filePath;
     ALuint _alBuffer;

+ 34 - 8
gameplay/src/AudioController.cpp

@@ -3,17 +3,19 @@
  */
 
 #include "Base.h"
+#include "AudioController.h"
 #include "AudioListener.h"
 #include "AudioBuffer.h"
 #include "AudioSource.h"
-#include "AudioController.h"
+
 
 namespace gameplay
 {
 
 std::list<AudioSource*> AudioController::_playingSources;
 
-AudioController::AudioController()
+AudioController::AudioController() 
+    : _alcDevice(NULL), _alcContext(NULL)
 {
 }
 
@@ -23,19 +25,43 @@ AudioController::~AudioController()
 
 void AudioController::initialize()
 {    
-    alutInit(0, 0);
-
-    ALenum errorID = alutGetError();
-    if ( errorID != ALUT_ERROR_NO_ERROR)
+    _alcDevice = alcOpenDevice (NULL);
+    if (!_alcDevice)
     {
-        LOG_ERROR_VARG("AudioController::initialize() error. Unable to initialize alut: %s\n", alutGetErrorString(errorID));
+        LOG_ERROR("AudioController::initialize() error. Unable to open OpenAL device.\n");
         return;  
     }
+        
+	_alcContext = alcCreateContext(_alcDevice, NULL);
+    ALCenum alcErr = alcGetError(_alcDevice);
+	if (!_alcContext || alcErr != ALC_NO_ERROR)
+    {
+        alcCloseDevice (_alcDevice);
+        LOG_ERROR_VARG("AudioController::initialize() error. Unable to create OpenAL context. Error: %d\n", alcErr);
+        return;
+    }
+    
+    alcMakeContextCurrent(_alcContext);
+    alcErr = alcGetError(_alcDevice);
+    if (alcErr != ALC_NO_ERROR)
+    {
+        LOG_ERROR_VARG("AudioController::initialize() error. Unable to make OpenAL context current. Error: %d\n", alcErr);
+    }
 }
 
 void AudioController::finalize()
 {
-    alutExit();
+    alcMakeContextCurrent(NULL);
+    if (_alcContext)
+    {
+        alcDestroyContext(_alcContext);
+        _alcContext = NULL;
+    }
+    if (_alcDevice)
+    {
+        alcCloseDevice(_alcDevice);
+        _alcDevice = NULL;
+    }
 }
 
 void AudioController::pause()

+ 2 - 1
gameplay/src/AudioController.h

@@ -58,7 +58,8 @@ private:
      */
     void update(long elapsedTime);
 
-
+    ALCdevice* _alcDevice;
+    ALCcontext* _alcContext;
     static std::list<AudioSource*> _playingSources;     // List of currently running sources.
 };
 

+ 1 - 2
gameplay/src/AudioSource.cpp

@@ -167,14 +167,13 @@ void AudioSource::setNode(Node* node)
         if (_node)
         {
             _node->removeListener(this);
-            SAFE_RELEASE(_node);
         }
 
         // Connect the new node.
         _node = node;
+
         if (_node)
         {
-            _node->addRef();
             _node->addListener(this);
         }
     }

+ 56 - 16
gameplay/src/Base.h

@@ -5,6 +5,8 @@
 #define BASE_H_
 
 // C/C++
+#include <new>
+#include <cstdio>
 #include <cassert>
 #include <memory>
 #include <iostream>
@@ -17,12 +19,11 @@
 #include <list>
 #include <stack>
 #include <map>
-#include <hash_map>
 #include <algorithm>
 #include <ctime>
-#include <cstdio>
 #include <limits>
 #include <functional>
+#include <assert.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdint.h>
@@ -62,6 +63,37 @@ extern void printError(const char* format, ...);
 #define WARN(x) printError(x)
 #define WARN_VARG(x, ...) printError(x, __VA_ARGS__)
 
+// Bullet Physics
+#include <btBulletDynamicsCommon.h>
+
+// Since Bullet overrides new, we have to allocate objects manually using its
+// aligned allocation function when we turn on memory leak detection in GamePlay.
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+#define BULLET_NEW(type, name, ...) \
+    type* name = (type*)btAlignedAlloc(sizeof(type), 16); \
+    type __##name##_tmp (__VA_ARGS__); \
+    memcpy(name, &__##name##_tmp, sizeof(type))
+
+#define BULLET_DELETE(name) \
+    if (name) \
+    { \
+        btAlignedFree(name); \
+        name = NULL; \
+    }
+
+#else
+#define BULLET_NEW(type, name, ...) \
+    type* name = new type(__VA_ARGS__)
+
+#define BULLET_DELETE(name) SAFE_DELETE(name)
+#endif
+
+
+// Debug new for memory leak detection
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+#include "DebugNew.h"
+#endif
+
 // Object deletion macro
 #define SAFE_DELETE(x) \
     if (x) \
@@ -105,26 +137,28 @@ extern void printError(const char* format, ...);
 #define M_1_PI                      0.31830988618379067154
 #endif
 
-// Audio (OpenAL/alut)
+// Audio (OpenAL)
 #ifdef __QNX__
 #include <AL/al.h>
 #include <AL/alc.h>
-#include <AL/alut.h>
 #elif WIN32
 #include <al.h>
 #include <alc.h>
-#include <alut.h>
+#elif __APPLE__
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
 #endif
 
-// Bullet Physics
-#include <btBulletDynamicsCommon.h>
-
-// Graphics (OpenGLES/OpenGL/png)
-#define WINDOW_VSYNC        1
-#define WINDOW_FULLSCREEN   0
+// Screen/Window
 #define WINDOW_WIDTH        1024
 #define WINDOW_HEIGHT       600
+#define WINDOW_VSYNC        1
+#define WINDOW_FULLSCREEN   0
+
+// Image
+#include <png.h>
 
+// Graphics (OpenGL)
 #ifdef __QNX__
     #include <EGL/egl.h>
     #include <GLES2/gl2.h>
@@ -134,14 +168,21 @@ extern void printError(const char* format, ...);
     extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
     extern PFNGLISVERTEXARRAYOESPROC glIsVertexArray;
     #define glClearDepth glClearDepthf
+   #define OPENGL_ES
 #elif WIN32
     #define WIN32_LEAN_AND_MEAN
     #include <GL/glew.h>
     #include <GL/wglew.h>
+#elif __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#define glBindVertexArray glBindVertexArrayAPPLE
+#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
+#define glGenVertexArrays glGenVertexArraysAPPLE
+#define glIsVertexArray glIsVertexArrayAPPLE
 #endif
-#include <png.h>
 
-// Attributes
+// Graphics (GLSL)
 #define VERTEX_ATTRIBUTE_POSITION_NAME              "a_position"
 #define VERTEX_ATTRIBUTE_NORMAL_NAME                "a_normal"
 #define VERTEX_ATTRIBUTE_COLOR_NAME                 "a_color"
@@ -214,8 +255,7 @@ extern GLenum __gl_error_code;
 #define GL_LAST_ERROR() __gl_error_code
 
 
-// Missing platform functionality and warnings.
-#ifdef WIN32
+#if defined(WIN32) || defined(__APPLE__)
 
     inline float fminf(float a, float b)
     {
@@ -242,4 +282,4 @@ extern GLenum __gl_error_code;
     #pragma warning( disable : 4996 )
 #endif
 
-#endif 
+#endif

+ 19 - 0
gameplay/src/BoundingBox.h

@@ -178,8 +178,27 @@ public:
      * @param matrix The transformation matrix to transform by.
      */
     void transform(const Matrix& matrix);
+
+    /**
+     * Transforms this bounding box by the given matrix.
+     * 
+     * @param matrix The matrix to transform by.
+     * @return This bounding box, after the transformation occurs.
+     */
+    inline BoundingBox& operator*=(const Matrix& matrix);
 };
 
+/**
+ * Transforms the given bounding box by the given matrix.
+ * 
+ * @param matrix The matrix to transform by.
+ * @param box The bounding box to transform.
+ * @return The resulting transformed bounding box.
+ */
+inline BoundingBox operator*(const Matrix& matrix, const BoundingBox& box);
+
 }
 
+#include "BoundingBox.inl"
+
 #endif

+ 23 - 0
gameplay/src/BoundingBox.inl

@@ -0,0 +1,23 @@
+/** 
+ * BoundingBox.inl
+ */
+
+#include "BoundingBox.h"
+
+namespace gameplay
+{
+
+inline BoundingBox& BoundingBox::operator*=(const Matrix& matrix)
+{
+    transform(matrix);
+    return *this;
+}
+
+inline BoundingBox operator*(const Matrix& matrix, const BoundingBox& box)
+{
+    BoundingBox b(box);
+    b.transform(matrix);
+    return b;
+}
+
+}

+ 19 - 0
gameplay/src/BoundingSphere.h

@@ -165,6 +165,14 @@ public:
      */
     void transform(const Matrix& matrix);
 
+    /**
+     * Transforms this bounding sphere by the given matrix.
+     * 
+     * @param matrix The matrix to transform by.
+     * @return This bounding sphere, after the transformation occurs.
+     */
+    inline BoundingSphere& operator*=(const Matrix& matrix);
+
 private:
 
     float distance(const BoundingSphere& sphere, const Vector3&);
@@ -172,6 +180,17 @@ private:
     bool contains(const BoundingSphere& sphere, Vector3* points, unsigned int count);
 };
 
+/**
+ * Transforms the given bounding sphere by the given matrix.
+ * 
+ * @param matrix The matrix to transform by.
+ * @param sphere The bounding sphere to transform.
+ * @return The resulting transformed bounding sphere.
+ */
+inline BoundingSphere operator*(const Matrix& matrix, const BoundingSphere& sphere);
+
 }
 
+#include "BoundingSphere.inl"
+
 #endif

+ 23 - 0
gameplay/src/BoundingSphere.inl

@@ -0,0 +1,23 @@
+/** 
+ * BoundingSphere.inl
+ */
+
+#include "BoundingSphere.h"
+
+namespace gameplay
+{
+
+inline BoundingSphere& BoundingSphere::operator*=(const Matrix& matrix)
+{
+    transform(matrix);
+    return *this;
+}
+
+inline BoundingSphere operator*(const Matrix& matrix, const BoundingSphere& sphere)
+{
+    BoundingSphere s(sphere);
+    s.transform(matrix);
+    return s;
+}
+
+}

+ 1 - 6
gameplay/src/Camera.cpp

@@ -36,7 +36,6 @@ Camera::Camera(float zoomX, float zoomY, float aspectRatio, float nearPlane, flo
 
 Camera::~Camera()
 {
-    SAFE_RELEASE(_node);
 }
 
 Camera* Camera::createPerspective(float fieldOfView, float aspectRatio, float nearPlane, float farPlane)
@@ -144,17 +143,13 @@ void Camera::setNode(Node* node)
         if (_node)
         {
             _node->removeListener(this);
-
-            // Disconnect our current node.
-            SAFE_RELEASE(_node);
         }
 
         // Connect the new node.
         _node = node;
+
         if (_node)
         {
-            _node->addRef();
-
             _node->addListener(this);
         }
 

+ 2 - 1
gameplay/src/Curve.cpp

@@ -31,6 +31,7 @@ Curve::Curve(unsigned int pointCount, unsigned int componentCount)
 Curve::~Curve()
 {
     SAFE_DELETE_ARRAY(_points);
+    SAFE_DELETE_ARRAY(_quaternionOffsets);
 }
 
 Curve::Point::Point()
@@ -233,7 +234,7 @@ void Curve::interpolateBezier(float s, Point* from, Point* to, float* dst) const
                 i++;
             }
             // Handle quaternion component.
-            float interpTime = from->time * eq1 + from->outValue[i] * eq2 + to->inValue[i] * eq3 + to->time * eq4;
+            //float interpTime = from->time * eq1 + from->outValue[i] * eq2 + to->inValue[i] * eq3 + to->time * eq4;
             interpolateQuaternion(s, (from->value + i), (to->value + i), (dst + i));
             i += 4;
             quaternionOffsetIndex++;

+ 162 - 0
gameplay/src/DebugNew.cpp

@@ -0,0 +1,162 @@
+/**
+ * DebugNew.cpp
+ */
+
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+
+#include <new>
+#include <exception>
+#include <cstdio>
+#include <cstdarg>
+
+struct MemoryAllocationRecord
+{
+    unsigned long address;          // address returned to the caller after allocation
+    unsigned int size;              // size of the allocation request
+    const char* file;               // source file of allocation request
+    int line;                       // source line of the allocation request
+    MemoryAllocationRecord* next;
+    MemoryAllocationRecord* prev;
+};
+
+MemoryAllocationRecord* __memoryAllocations = 0;
+int __memoryAllocationCount = 0;
+
+void* debugAlloc(std::size_t size, const char* file, int line);
+void debugFree(void* p);
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4290 )
+#endif
+
+void* operator new (std::size_t size, const char* file, int line)
+{
+    return debugAlloc(size, file, line);
+}
+
+void* operator new[] (std::size_t size, const char* file, int line)
+{
+    return operator new (size, file, line);
+}
+
+void* operator new (std::size_t size) throw(std::bad_alloc)
+{
+    return operator new (size, "", 0);
+}
+
+void* operator new[] (std::size_t size) throw(std::bad_alloc)
+{
+    return operator new (size, "", 0);
+}
+
+void* operator new (std::size_t size, const std::nothrow_t&) throw()
+{
+    return operator new (size, "", 0);
+}
+
+void* operator new[] (std::size_t size, const std::nothrow_t&) throw()
+{
+    return operator new (size, "", 0);
+}
+
+void operator delete (void* p) throw()
+{
+    debugFree(p);
+}
+
+void operator delete[] (void* p) throw()
+{
+    operator delete (p);
+}
+
+void operator delete (void* p, const char* file, int line) throw()
+{
+    operator delete (p);
+}
+
+void operator delete[] (void* p, const char* file, int line) throw()
+{
+    operator delete (p);
+}
+
+#ifdef _MSC_VER
+#pragma warning( default : 4290 )
+#endif
+
+// Include Base.h (needed for logging macros) AFTER new operator impls
+#include "Base.h"
+
+void* debugAlloc(size_t size, const char* file, int line)
+{
+    // Allocate memory + size for a MemoryAlloctionRecord
+    unsigned char* mem = (unsigned char*)malloc(size + sizeof(MemoryAllocationRecord));
+
+    MemoryAllocationRecord* rec = (MemoryAllocationRecord*)mem;
+
+    // Move memory pointer past record
+    mem += sizeof(MemoryAllocationRecord);
+
+    rec->address = (unsigned long)mem;
+    rec->size = size;
+    rec->file = file;
+    rec->line = line;
+    rec->next = __memoryAllocations;
+    rec->prev = 0;
+
+    if (__memoryAllocations)
+        __memoryAllocations->prev = rec;
+    __memoryAllocations = rec;
+    ++__memoryAllocationCount;
+
+    return mem;
+}
+
+void debugFree(void* p)
+{
+    assert(p);
+
+    // Backup passed in pointer to access memory allocation record
+    void* mem = ((unsigned char*)p) - sizeof(MemoryAllocationRecord);
+
+    MemoryAllocationRecord* rec = (MemoryAllocationRecord*)mem;
+
+    // Sanity check: ensure that address in record matches passed in address
+    if (rec->address != (unsigned long)p)
+    {
+        gameplay::printError("[memory] CORRUPTION: Attempting to free memory address with invalid memory allocation record.");
+        return;
+    }
+
+    // Link this item out
+    if (__memoryAllocations == rec)
+        __memoryAllocations = rec->next;
+    if (rec->prev)
+        rec->prev->next = rec->next;
+    if (rec->next)
+        rec->next->prev = rec->prev;
+    --__memoryAllocationCount;
+
+    // Free the address from the original alloc location (before mem allocation record)
+    free(mem);
+}
+
+extern void printMemoryLeaks()
+{
+    // Dump general heap memory leaks
+    if (__memoryAllocationCount == 0)
+    {
+        gameplay::printError("[memory] All HEAP allocations successfully cleaned up (no leaks detected).");
+    }
+    else
+    {
+        gameplay::printError("[memory] WARNING: %d HEAP allocations still active in memory.", __memoryAllocationCount);
+        MemoryAllocationRecord* rec = __memoryAllocations;
+        while (rec)
+        {
+            gameplay::printError("[memory] LEAK: HEAP allocation leak of size %d leak from line %d in file '%s'.", rec->size, rec->line, rec->file);
+            rec = rec->next;
+        }
+    }
+}
+
+#endif

+ 42 - 0
gameplay/src/DebugNew.h

@@ -0,0 +1,42 @@
+/**
+ * DebugNew.h
+ *
+ * Global overrides of the new and delete operators for memory tracking.
+ * This file is only included when memory leak detection is explicitly
+ * request via the pre-processor defintion GAMEPLAY_MEM_LEAK_DETECTION.
+ */
+
+#ifndef DEBUGNEW_H_
+#define DEBUGNEW_H_
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+
+#include <new>
+#include <exception>
+
+// Prints all heap and reference leaks to stderr.
+extern void printMemoryLeaks();
+
+// global new/delete operator overloads
+#ifdef _MSC_VER
+#pragma warning( disable : 4290 ) // C++ exception specification ignored.
+#endif
+void* operator new (std::size_t size, const char* file, int line);
+void* operator new[] (std::size_t size, const char* file, int line);
+void* operator new (std::size_t size) throw(std::bad_alloc);
+void* operator new[] (std::size_t size) throw(std::bad_alloc);
+void* operator new (std::size_t size, const std::nothrow_t&) throw();
+void* operator new[] (std::size_t size, const std::nothrow_t&) throw();
+void operator delete (void* p) throw();
+void operator delete[] (void* p) throw();
+void operator delete (void* p, const char* file, int line) throw();
+void operator delete[] (void* p, const char* file, int line) throw();
+#ifdef _MSC_VER
+#pragma warning( default : 4290 )
+#endif
+
+// Re-define new to use versions with file and line number
+#define DEBUG_NEW new (__FILE__, __LINE__)
+#define new DEBUG_NEW
+
+#endif
+#endif

+ 17 - 3
gameplay/src/Effect.cpp

@@ -6,6 +6,8 @@
 #include "Effect.h"
 #include "FileSystem.h"
 
+#define OPENGL_ES_DEFINE  "#define OPENGL_ES"
+
 namespace gameplay
 {
 
@@ -110,7 +112,13 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
     GLint success;
 
     // Compile vertex shader.
-    shaderSource[0] = defines == NULL ? "" : defines;
+    std::string definesStr = (defines == NULL) ? "" : defines;
+#ifdef OPENGL_ES
+    if (defines && strlen(defines) != 0)
+        definesStr += "\n";
+    definesStr+= OPENGL_ES_DEFINE;
+#endif
+    shaderSource[0] = definesStr.c_str();
     shaderSource[1] = "\n";
     shaderSource[2] = vshSource;
     GL_ASSERT( vertexShader = glCreateShader(GL_VERTEX_SHADER) );
@@ -135,8 +143,14 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
         return NULL;
     }
 
-    // Compile fragment shader.
-    shaderSource[0] = defines == NULL ? "" : defines;
+    // Compile the fragment shader.
+    definesStr = (defines == NULL) ? "" : defines;
+#ifdef OPENGL_ES
+    if (defines && strlen(defines) != 0)
+        definesStr += "\n";
+    definesStr+= OPENGL_ES_DEFINE;
+#endif
+    shaderSource[0] = definesStr.c_str();
     shaderSource[1] = "\n";
     shaderSource[2] = fshSource;
     GL_ASSERT( fragmentShader = glCreateShader(GL_FRAGMENT_SHADER) );

+ 3 - 2
gameplay/src/FileSystem.cpp

@@ -34,14 +34,15 @@ FILE* FileSystem::openFile(const char* path, const char* mode)
     fullPath += path;
 
     FILE* fp = fopen(fullPath.c_str(), mode);
-
+    
+// Win32 doesnt support a asset or bundle definitions.
 #ifdef WIN32
-    // HACK: For testing purposes, search the gameplay-resources folder as well.
     if (fp == NULL)
     {
         fullPath = __resourcePath;
         fullPath += "../../gameplay/";
         fullPath += path;
+        
         fp = fopen(fullPath.c_str(), mode);
     }
 #endif

+ 22 - 20
gameplay/src/Font.cpp

@@ -10,29 +10,31 @@
 
 // Default font vertex shader
 #define FONT_VSH \
-    "uniform mat4 sb_projection_matrix;" \
-    "attribute vec3 a_position;" \
-    "attribute vec2 a_texcoord;" \
-    "attribute vec4 a_color;" \
-    "varying vec2 vtexcoord;" \
-    "varying vec4 vcolor;" \
-    "void main()" \
-    "{" \
-        "gl_Position = sb_projection_matrix * vec4(a_position, 1);" \
-        "vtexcoord = a_texcoord;" \
-        "vcolor = a_color;" \
-    "}"
+    "uniform mat4 u_projectionMatrix;\n" \
+    "attribute vec3 a_position;\n" \
+    "attribute vec2 a_texcoord;\n" \
+    "attribute vec4 a_color;\n" \
+    "varying vec2 v_texcoord;\n" \
+    "varying vec4 v_color;\n" \
+    "void main()\n" \
+    "{\n" \
+        "gl_Position = u_projectionMatrix * vec4(a_position, 1);\n" \
+        "v_texcoord = a_texcoord;\n" \
+        "v_color = a_color;\n" \
+    "}\n"
 
 // Default font fragment shader
 #define FONT_FSH \
-    "precision mediump float;" \
-    "varying vec2 vtexcoord;" \
-    "varying vec4 vcolor;" \
-    "uniform sampler2D texture;" \
-    "void main()" \
-    "{" \
-        "gl_FragColor = vcolor;" \
-        "gl_FragColor.a = texture2D(texture, vtexcoord).a;" \
+    "#ifdef OPENGL_ES\n" \
+    "precision highp float;\n" \
+    "#endif\n" \
+    "varying vec2 v_texcoord;\n" \
+    "varying vec4 v_color;\n" \
+    "uniform sampler2D u_texture;\n" \
+    "void main()\n" \
+    "{\n" \
+        "gl_FragColor = v_color;\n" \
+        "gl_FragColor.a = texture2D(u_texture, v_texcoord).a;\n" \
     "}"
 
 namespace gameplay

+ 40 - 19
gameplay/src/Game.cpp

@@ -5,6 +5,7 @@
 #include "Base.h"
 #include "Game.h"
 #include "Platform.h"
+#include "RenderState.h"
 
 // Extern global variables
 GLenum __gl_error_code = GL_NO_ERROR;
@@ -19,7 +20,8 @@ long Game::_pausedTimeTotal = 0L;
 Game::Game() 
     : _state(UNINITIALIZED), 
       _frameLastFPS(0), _frameCount(0), _frameRate(0), 
-      _clearColor(Vector4::zero()), _clearDepth(1.0f), _clearStencil(0)
+      _clearDepth(1.0f), _clearStencil(0),
+      _animationController(NULL), _audioController(NULL)
 {
     assert(__gameInstance == NULL);
     __gameInstance = this;
@@ -33,6 +35,11 @@ Game::~Game()
 {
     // Do not call any virtual functions from the destructor.
     // Finalization is done from outside this class.
+
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+    Ref::printLeaks();
+    printMemoryLeaks();
+#endif
 }
 
 Game* Game::getInstance()
@@ -92,9 +99,16 @@ bool Game::startup()
     if (_state != UNINITIALIZED)
         return false;
 
-    _animationController.initialize();
-    _audioController.initialize();
-    _physicsController.initialize();
+    RenderState::initialize();
+
+    _animationController = new AnimationController();
+    _animationController->initialize();
+
+    _audioController = new AudioController();
+    _audioController->initialize();
+
+    _physicsController = new PhysicsController();
+    _physicsController->initialize();
 
     // Call user initialization.
     initialize();
@@ -110,9 +124,16 @@ void Game::shutdown()
     {
         finalize();
 
-        _animationController.finalize();
-        _audioController.finalize();
-        _physicsController.finalize();
+        _animationController->finalize();
+        SAFE_DELETE(_animationController);
+
+        _audioController->finalize();
+        SAFE_DELETE(_audioController);
+
+        _physicsController->finalize();
+        SAFE_DELETE(_physicsController);
+
+        RenderState::finalize();
     }
 
     _state = UNINITIALIZED;
@@ -124,9 +145,9 @@ void Game::pause()
     {
         _state = PAUSED;
         _pausedTimeLast = Platform::getAbsoluteTime();
-        _animationController.pause();
-        _audioController.pause();
-        _physicsController.pause();
+        _animationController->pause();
+        _audioController->pause();
+        _physicsController->pause();
     }
 }
 
@@ -136,9 +157,9 @@ void Game::resume()
     {
         _state = RUNNING;
         _pausedTimeTotal += Platform::getAbsoluteTime() - _pausedTimeLast;
-        _animationController.resume();
-        _audioController.resume();
-        _physicsController.resume();
+        _animationController->resume();
+        _audioController->resume();
+        _physicsController->resume();
     }
 }
 
@@ -159,14 +180,14 @@ void Game::frame()
     lastFrameTime = frameTime;
 
     // Update the scheduled and running animations.
-    _animationController.update(elapsedTime);
+    _animationController->update(elapsedTime);
     // Update the physics.
-    _physicsController.update(elapsedTime);
+    _physicsController->update(elapsedTime);
     // Application Update.
     update(elapsedTime);
 
     // Audio Rendering.
-    _audioController.update(elapsedTime);
+    _audioController->update(elapsedTime);
     // Graphics Rendering.
     render(elapsedTime);
 
@@ -230,17 +251,17 @@ void Game::clear(ClearFlags flags, const Vector4& clearColor, float clearDepth,
 
 AnimationController* Game::getAnimationController()
 {
-    return &_animationController;
+    return _animationController;
 }
 
-const AudioController& Game::getAudioController() const
+const AudioController* Game::getAudioController() const
 {
     return _audioController;
 }
 
 PhysicsController* Game::getPhysicsController()
 {
-    return &_physicsController;
+    return _physicsController;
 }
 
 void Game::menu()

+ 5 - 9
gameplay/src/Game.h

@@ -19,7 +19,6 @@ namespace gameplay
  */
 class Game
 {
-
 public:
 
     /**
@@ -35,8 +34,7 @@ public:
     /**
      * Flags used when clearing the active frame buffer targets.
      */
-
-     enum ClearFlags
+    enum ClearFlags
     {
         CLEAR_COLOR = GL_COLOR_BUFFER_BIT,
         CLEAR_DEPTH = GL_DEPTH_BUFFER_BIT,
@@ -47,8 +45,6 @@ public:
         CLEAR_COLOR_DEPTH_STENCIL = CLEAR_COLOR | CLEAR_DEPTH | CLEAR_STENCIL
     };
 
-
-
     /**
      * Destructor.
      */
@@ -169,7 +165,7 @@ public:
      *
      * @return The audio controller for this game.
      */
-    const AudioController& getAudioController() const;
+    const AudioController* getAudioController() const;
 
     /**
      * Gets the animation controller for managing control of animations
@@ -288,9 +284,9 @@ private:
     Vector4 _clearColor;                        // The clear color value last used for clearing the color buffer.
     float _clearDepth;                          // The clear depth value last used for clearing the depth buffer.
     int _clearStencil;                          // The clear stencil value last used for clearing the stencil buffer.
-    AnimationController _animationController;   // Controls the scheduling and running of animations.
-    AudioController _audioController;           // Controls audio sources that are playing in the game.
-    PhysicsController _physicsController;       // Controls the simulation of a physics scene and entities.
+    AnimationController* _animationController;  // Controls the scheduling and running of animations.
+    AudioController* _audioController;          // Controls audio sources that are playing in the game.
+    PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
 };
 
 }

+ 2 - 2
gameplay/src/Joint.cpp

@@ -31,13 +31,13 @@ void Joint::transformChanged()
 {
     Node::transformChanged();
 
-    const char* id = _id.c_str();
+    //const char* id = _id.c_str();
     _jointMatrixDirty = true;
 }
 
 void Joint::updateJointMatrix(const Matrix& bindShape, Vector4* matrixPalette)
 {
-    const char* id = _id.c_str();
+    //const char* id = _id.c_str();
 
     if (_jointMatrixDirty)
     {

+ 22 - 13
gameplay/src/Light.cpp

@@ -70,19 +70,8 @@ Node* Light::getNode() const
 
 void Light::setNode(Node* node)
 {
-    if (_node != node)
-    {
-        // Disconnect our current node.
-        SAFE_RELEASE(_node);
-
-        // Connect the new node.
-        _node = node;
-
-        if (_node)
-        {
-            _node->addRef();
-        }
-    }
+    // Connect the new node.
+    _node = node;
 }
 
 const Vector3& Light::getColor() const
@@ -142,12 +131,30 @@ void Light::setRange(float range)
     {
     case POINT:
         _point->range = range;
+        _point->rangeInverse = 1.0f / range;
         break;
     case SPOT:
         _spot->range = range;
+        _spot->rangeInverse = 1.0f / range;
         break;
     }
 }
+
+float Light::getRangeInverse() const
+{
+    assert(_type != DIRECTIONAL);
+
+    switch (_type)
+    {
+    case POINT:
+        return _point->rangeInverse;
+    case SPOT:
+        return _spot->rangeInverse;
+    default:
+        assert(0);
+        return 0.0f;
+    }
+}
     
 float Light::getInnerAngle()  const
 {
@@ -201,11 +208,13 @@ Light::Directional::Directional(const Vector3& color)
 Light::Point::Point(const Vector3& color, float range)
     : color(color), range(range)
 {
+    rangeInverse = 1.0f / range;
 }
 
 Light::Spot::Spot(const Vector3& color, float range, float innerAngle, float outerAngle)
     : color(color), range(range), innerAngle(innerAngle), outerAngle(outerAngle)
 {
+    rangeInverse = 1.0f / range;
     innerAngleCos = cos(innerAngle);
     outerAngleCos = cos(outerAngle);
 }

+ 9 - 0
gameplay/src/Light.h

@@ -112,6 +112,13 @@ public:
      */
     void setRange(float range);
 
+    /**
+     * Returns the inverse of the range of point or spot light.
+     *
+     * @return The range of the point or spot light.
+     */
+    float getRangeInverse() const;
+
     /**
      * Returns the inner angle the spot light (in radians).
      *
@@ -176,6 +183,7 @@ private:
     public:
         Vector3 color;
         float range;
+        float rangeInverse;
 
         Point(const Vector3& color, float range);
     };
@@ -188,6 +196,7 @@ private:
     public:
         Vector3 color;
         float range;
+        float rangeInverse;
         float innerAngle;
         float innerAngleCos;
         float outerAngle;

+ 2 - 0
gameplay/src/MaterialParameter.h

@@ -269,6 +269,7 @@ void MaterialParameter::bindValue(ClassType* classInstance, ParameterType (Class
     clearValue();
 
     _value.method = new MethodValueBinding<ClassType, ParameterType>(this, classInstance, valueMethod);
+    _dynamic = true;
     _type = MaterialParameter::METHOD;
 }
 
@@ -278,6 +279,7 @@ void MaterialParameter::bindValue(ClassType* classInstance, ParameterType (Class
     clearValue();
 
     _value.method = new MethodArrayBinding<ClassType, ParameterType>(this, classInstance, valueMethod, countMethod);
+    _dynamic = true;
     _type = MaterialParameter::METHOD;
 }
 

+ 25 - 18
gameplay/src/Matrix.cpp

@@ -44,20 +44,22 @@ Matrix::~Matrix()
 
 const Matrix& Matrix::identity()
 {
-    static Matrix* m = new Matrix( 1, 0, 0, 0,
-                                   0, 1, 0, 0,
-                                   0, 0, 1, 0,
-                                   0, 0, 0, 1 );
-    return *m;
+    static Matrix m(
+        1, 0, 0, 0,
+        0, 1, 0, 0,
+        0, 0, 1, 0,
+        0, 0, 0, 1 );
+    return m;
 }
 
 const Matrix& Matrix::zero()
 {
-    static Matrix* m = new Matrix( 0, 0, 0, 0,
-                                   0, 0, 0, 0,
-                                   0, 0, 0, 0,
-                                   0, 0, 0, 0 );
-    return *m;
+    static Matrix m(
+        0, 0, 0, 0,
+        0, 0, 0, 0,
+        0, 0, 0, 0,
+        0, 0, 0, 0 );
+    return m;
 }
 
 void Matrix::createLookAt(const Vector3& eyePosition, const Vector3& targetPosition, const Vector3& up, Matrix* dst)
@@ -902,24 +904,24 @@ void Matrix::subtract(const Matrix& m1, const Matrix& m2, Matrix* dst)
     dst->m[15] = m1.m[15] - m2.m[15];
 }
 
-void Matrix::transformVector(Vector3* vector) const
+void Matrix::transformPoint(Vector3* point) const
 {
-    transformVector(vector->x, vector->y, vector->z, 0.0f, vector);
+    transformVector(point->x, point->y, point->z, 1.0f, point);
 }
 
-void Matrix::transformVector(const Vector3& vector, Vector3* dst) const
+void Matrix::transformPoint(const Vector3& point, Vector3* dst) const
 {
-    transformVector(vector.x, vector.y, vector.z, 0.0f, dst);
+    transformVector(point.x, point.y, point.z, 1.0f, dst);
 }
 
-void Matrix::transformPoint(Vector3* point) const
+void Matrix::transformVector(Vector3* vector) const
 {
-    transformVector(point->x, point->y, point->z, 1.0f, point);
+    transformVector(vector->x, vector->y, vector->z, 0.0f, vector);
 }
 
-void Matrix::transformPoint(const Vector3& point, Vector3* dst) const
+void Matrix::transformVector(const Vector3& vector, Vector3* dst) const
 {
-    transformVector(point.x, point.y, point.z, 1.0f, dst);
+    transformVector(vector.x, vector.y, vector.z, 0.0f, dst);
 }
 
 void Matrix::transformVector(float x, float y, float z, float w, Vector3* dst) const
@@ -932,6 +934,11 @@ void Matrix::transformVector(float x, float y, float z, float w, Vector3* dst) c
         x * m[2] + y * m[6] + z * m[10] + w * m[14] );
 }
 
+void Matrix::transformVector(Vector4* vector) const
+{
+    transformVector(*vector, vector);
+}
+
 void Matrix::transformVector(const Vector4& vector, Vector4* dst) const
 {
     assert(dst);

+ 136 - 19
gameplay/src/Matrix.h

@@ -5,7 +5,6 @@
 #ifndef MATRIX_H_
 #define MATRIX_H_
 
-#include "Vector2.h"
 #include "Vector3.h"
 #include "Vector4.h"
 
@@ -712,6 +711,24 @@ public:
      */
     static void subtract(const Matrix& m1, const Matrix& m2, Matrix* dst);
 
+    /**
+     * Transforms the specified point by this matrix.
+     *
+     * The result of the transformation is stored directly into point.
+     *
+     * @param point The point to transform and also a vector to hold the result in.
+     */
+    void transformPoint(Vector3* point) const;
+
+    /**
+     * Transforms the specified point by this matrix, and stores
+     * the result in dst.
+     *
+     * @param point The point to transform.
+     * @param dst A vector to store the transformed point in.
+     */
+    void transformPoint(const Vector3& point, Vector3* dst) const;
+
     /**
      * Transforms the specified vector by this matrix by
      * treating the fourth (w) coordinate as zero.
@@ -732,24 +749,6 @@ public:
      */
     void transformVector(const Vector3& vector, Vector3* dst) const;
 
-    /**
-     * Transforms the specified point by this matrix.
-     *
-     * The result of the transformation is stored directly into point.
-     *
-     * @param point The point to transform and also a vector to hold the result in.
-     */
-    void transformPoint(Vector3* point) const;
-
-    /**
-     * Transforms the specified point by this matrix, and stores
-     * the result in dst.
-     *
-     * @param point The point to transform.
-     * @param dst A vector to store the transformed point in.
-     */
-    void transformPoint(const Vector3& point, Vector3* dst) const;
-
     /**
      * Transforms the specified vector by this matrix.
      *
@@ -761,6 +760,15 @@ public:
      */
     void transformVector(float x, float y, float z, float w, Vector3* dst) const;
 
+    /**
+     * Transforms the specified vector by this matrix.
+     *
+     * The result of the transformation is stored directly into vector.
+     *
+     * @param vector The vector to transform.
+     */
+    void transformVector(Vector4* vector) const;
+
     /**
      * Transforms the specified vector by this matrix.
      *
@@ -818,8 +826,117 @@ public:
      * @param dst A matrix to store the result in.
      */
     void transpose(Matrix* dst) const;
+
+    /**
+     * Calculates the sum of this matrix with the given matrix.
+     * 
+     * Note: this does not modify this matrix.
+     * 
+     * @param m The matrix to add.
+     * @return The matrix sum.
+     */
+    inline Matrix operator+(const Matrix& m);
+    
+    /**
+     * Adds the given matrix to this matrix.
+     * 
+     * @param m The matrix to add.
+     * @return This matrix, after the addition occurs.
+     */
+    inline Matrix& operator+=(const Matrix& m);
+
+    /**
+     * Calculates the sum of this matrix with the given matrix.
+     * 
+     * Note: this does not modify this matrix.
+     * 
+     * @param m The matrix to add.
+     * @return The matrix sum.
+     */
+    inline Matrix operator-(const Matrix& m);
+
+    /**
+     * Subtracts the given matrix from this matrix.
+     * 
+     * @param m The matrix to subtract.
+     * @return This matrix, after the subtraction occurs.
+     */
+    inline Matrix& operator-=(const Matrix& m);
+
+    /**
+     * Calculates the negation of this matrix.
+     * 
+     * Note: this does not modify this matrix.
+     * 
+     * @return The negation of this matrix.
+     */
+    inline Matrix operator-();
+
+    /**
+     * Calculates the matrix product of this matrix with the given matrix.
+     * 
+     * Note: this does not modify this matrix.
+     * 
+     * @param m The matrix to multiply by.
+     * @return The matrix product.
+     */
+    inline Matrix operator*(const Matrix& m);
+
+    /**
+     * Right-multiplies this matrix by the given matrix.
+     * 
+     * @param m The matrix to multiply by.
+     * @return This matrix, after the multiplication occurs.
+     */
+    inline Matrix& operator*=(const Matrix& m);
 };
 
+/**
+ * Transforms the given vector by the given matrix.
+ * 
+ * Note: this treats the given vector as a vector and not as a point.
+ * 
+ * @param v The vector to transform.
+ * @param m The matrix to transform by.
+ * @return This vector, after the transformation occurs.
+ */
+inline Vector3& operator*=(Vector3& v, const Matrix& m);
+
+/**
+ * Transforms the given vector by the given matrix.
+ * 
+ * Note: this treats the given vector as a vector and not as a point.
+ * 
+ * @param m The matrix to transform by.
+ * @param v The vector to transform.
+ * @return The resulting transformed vector.
+ */
+inline Vector3 operator*(const Matrix& m, const Vector3& v);
+
+/**
+ * Transforms the given vector by the given matrix.
+ * 
+ * Note: this treats the given vector as a vector and not as a point.
+ * 
+ * @param v The vector to transform.
+ * @param m The matrix to transform by.
+ * @return This vector, after the transformation occurs.
+ */
+inline Vector4& operator*=(Vector4& v, const Matrix& m);
+
+/**
+ * Transforms the given vector by the given matrix.
+ * 
+ * Note: this treats the given vector as a vector and not as a point.
+ * 
+ * @param m The matrix to transform by.
+ * @param v The vector to transform.
+ * @return The resulting transformed vector.
+ */
+inline Vector4 operator*(const Matrix& m, const Vector4& v);
+
 }
 
+//#include "Matrix.inl"
+
 #endif

+ 82 - 0
gameplay/src/Matrix.inl

@@ -0,0 +1,82 @@
+/** 
+ * Matrix.inl
+ */
+
+#include "Matrix.h"
+
+namespace gameplay
+{
+
+inline Matrix Matrix::operator+(const Matrix& m)
+{
+    Matrix result(*this);
+    result.add(m);
+    return result;
+}
+
+inline Matrix& Matrix::operator+=(const Matrix& m)
+{
+    add(m);
+    return *this;
+}
+
+inline Matrix Matrix::operator-(const Matrix& m)
+{
+    Matrix result(*this);
+    result.subtract(m);
+    return result;
+}
+
+inline Matrix& Matrix::operator-=(const Matrix& m)
+{
+    subtract(m);
+    return *this;
+}
+
+inline Matrix Matrix::operator-()
+{
+    Matrix m(*this);
+    m.negate();
+    return m;
+}
+
+inline Matrix Matrix::operator*(const Matrix& m)
+{
+    Matrix result(*this);
+    result.multiply(m);
+    return result;
+}
+
+inline Matrix& Matrix::operator*=(const Matrix& m)
+{
+    multiply(m);
+    return *this;
+}
+
+inline Vector3& operator*=(Vector3& v, const Matrix& m)
+{
+    m.transformVector(&v);
+    return v;
+}
+
+inline Vector3 operator*(const Matrix& m, const Vector3& v)
+{
+    Vector3 x;
+    m.transformVector(v, &x);
+    return x;
+}
+
+inline Vector4& operator*=(Vector4& v, const Matrix& m)
+{
+    m.transformVector(&v);
+    return v;
+}
+
+inline Vector4 operator*(const Matrix& m, const Vector4& v)
+{
+    Vector4 x;
+    m.transformVector(v, &x);
+    return x;
+}
+
+}

+ 0 - 12
gameplay/src/MeshSkin.cpp

@@ -80,15 +80,8 @@ void MeshSkin::setJoint(Joint* joint, unsigned int index)
 {
     assert(index < _joints.size());
 
-    if (_joints[index])
-    {
-        _joints[index]->_skin = NULL;
-        SAFE_RELEASE(_joints[index]);
-    }
-
     _joints[index] = joint;
     _joints[index]->_skin = this;
-    joint->addRef();
 }
 
 Vector4* MeshSkin::getMatrixPalette() const
@@ -114,11 +107,6 @@ Joint* MeshSkin::getJoint(unsigned int index) const
 
 void MeshSkin::clearJoints()
 {
-    unsigned int prevCount = _joints.size();
-    for (unsigned int i = 0; i < prevCount; i++)
-    {
-        SAFE_RELEASE(_joints[i]);
-    }
     _joints.clear();
 }
 

+ 3 - 6
gameplay/src/Model.cpp

@@ -198,10 +198,7 @@ Node* Model::getNode() const
 
 void Model::setNode(Node* node)
 {
-    if (_node != node)
-    {
-        _node = node;
-    }
+    _node = node;
 
     // Re-bind node related material parameters
     if (node)
@@ -317,9 +314,9 @@ void Model::validatePartCount()
         _partCount = _mesh->getPartCount();
     }
 }
-
+
 void Model::setMaterialNodeBinding(Material *material)
-{
+{
     if (_node)
     {
         material->setNodeBinding(_node);

+ 25 - 37
gameplay/src/Node.cpp

@@ -51,7 +51,7 @@ Node::~Node()
     SAFE_RELEASE(_model);
     SAFE_RELEASE(_audioSource);
     SAFE_RELEASE(_particleEmitter);
-    SAFE_RELEASE(_physicsRigidBody);
+    SAFE_DELETE(_physicsRigidBody);
 }
 
 Node* Node::create(const char* id)
@@ -81,11 +81,22 @@ void Node::addChild(Node* child)
 {
     assert(child);
 
+    if (child->_parent == this)
+    {
+        // This node is already present in our hierarchy
+        return;
+    }
+
+    child->addRef();
+
     // If the item belongs to another hierarchy, remove it first.
-    Node* parent = child->_parent;
-    if (parent)
+    if (child->_parent)
     {
-        parent->removeChild(child);
+        child->_parent->removeChild(child);
+    }
+    else if (child->_scene)
+    {
+        child->_scene->removeNode(child);
     }
 
     // Order is irrelevant, so add to the beginning of the list.
@@ -104,9 +115,10 @@ void Node::addChild(Node* child)
 
     ++_childCount;
 
-    // Fire events.
-    child->parentChanged(parent);
-    childAdded(child);
+    if (_notifyHierarchyChanged)
+    {
+        hierarchyChanged();
+    }
 }
 
 void Node::removeChild(Node* child)
@@ -119,6 +131,8 @@ void Node::removeChild(Node* child)
 
     // Call remove on the child.
     child->remove();
+
+    SAFE_RELEASE(child);
 }
 
 void Node::removeAllChildren()
@@ -134,7 +148,7 @@ void Node::removeAllChildren()
     hierarchyChanged();
 }
 
-void Node   ::remove()
+void Node::remove()
 {
     // Re-link our neighbours.
     if (_prevSibling)
@@ -162,11 +176,9 @@ void Node   ::remove()
     _prevSibling = NULL;
     _parent = NULL;
 
-    // Fire events.
-    if (parent)
+    if (parent && parent->_notifyHierarchyChanged)
     {
-        parentChanged(parent);
-        parent->childRemoved(this);
+        parent->hierarchyChanged();
     }
 }
 
@@ -797,34 +809,10 @@ PhysicsRigidBody* Node::getPhysicsRigidBody() const
 void Node::setPhysicsRigidBody(PhysicsRigidBody::Type type, float mass, float friction,
         float restitution, float linearDamping, float angularDamping)
 {
-    SAFE_RELEASE(_physicsRigidBody);
+    SAFE_DELETE(_physicsRigidBody);
     
     if (type != PhysicsRigidBody::SHAPE_NONE)
         _physicsRigidBody = new PhysicsRigidBody(this, type, mass, friction, restitution, linearDamping, angularDamping);
 }
 
-void Node::childAdded(Node* child)
-{
-    child->addRef();
-
-    if (_notifyHierarchyChanged)
-    {
-        hierarchyChanged();
-    }
-}
-
-void Node::childRemoved(Node* child)
-{
-    SAFE_RELEASE(child);
-
-    if (_notifyHierarchyChanged)
-    {
-        hierarchyChanged();
-    }
-}
-
-void Node::parentChanged(Node* oldParent)
-{
-}
-
 }

+ 0 - 21
gameplay/src/Node.h

@@ -440,27 +440,6 @@ protected:
      */
     void remove();
 
-    /**
-     * Called when a child is added to this item in the tree.
-     * 
-     * @param child The child that was added.
-     */
-    virtual void childAdded(Node* child);
-
-    /**
-     * Called when a child is removed from this item in the tree.
-     *
-     * @param child The child that was removed.
-     */
-    virtual void childRemoved(Node* child);
-
-    /**
-     * Called when the parent of this node changes.
-     *
-     * @param oldParent The previous parent for this node.
-     */
-    virtual void parentChanged(Node* oldParent);
-
     void transformChanged();
 
     void hierarchyChanged();

+ 6 - 0
gameplay/src/Package.cpp

@@ -488,6 +488,7 @@ Node* Package::readNode(Scene* sceneContext, Node* nodeContext)
     if (camera)
     {
         node->setCamera(camera);
+        SAFE_RELEASE(camera);
     }
 
     // Read light
@@ -495,6 +496,7 @@ Node* Package::readNode(Scene* sceneContext, Node* nodeContext)
     if (light)
     {
         node->setLight(light);
+        SAFE_RELEASE(light);
     }
 
     // Read model
@@ -502,6 +504,7 @@ Node* Package::readNode(Scene* sceneContext, Node* nodeContext)
     if (model)
     {
         node->setModel(model);
+        SAFE_RELEASE(model);
     }
 
     return node;
@@ -639,6 +642,7 @@ Model* Package::readModel(Scene* sceneContext, Node* nodeContext)
         if (mesh)
         {
             Model* model = Model::create(mesh);
+            SAFE_RELEASE(mesh);
 
             // Read skin
             unsigned char hasSkin;
@@ -1075,10 +1079,12 @@ Mesh* Package::loadMesh(const char* id)
         if (part == NULL)
         {
             LOG_ERROR_VARG("Failed to create mesh part (i=%d): %s", i, id);
+            SAFE_DELETE_ARRAY(indexData);
             SAFE_RELEASE(mesh);
             return NULL;
         }
         part->setIndexData(indexData, 0, indexCount);
+        SAFE_DELETE_ARRAY(indexData);
     }
 
     fseek(_file, position, SEEK_SET);

+ 10 - 23
gameplay/src/ParticleEmitter.cpp

@@ -34,11 +34,12 @@ ParticleEmitter::ParticleEmitter(SpriteBatch* batch, unsigned int particleCountM
     _timePerEmission(EMISSION_RATE_TIME_INTERVAL), _timeLast(0L), _timeRunning(0L)
 {
     _particles = new Particle[particleCountMax];
+
+    _spriteBatch->getStateBlock()->setDepthWrite(false);
 }
 
 ParticleEmitter::~ParticleEmitter()
 {
-    SAFE_RELEASE(_node);
     SAFE_DELETE(_spriteBatch);
     SAFE_DELETE_ARRAY(_particles);
     SAFE_DELETE_ARRAY(_spriteTextureCoords);
@@ -60,6 +61,7 @@ ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlendin
 
     // Use default SpriteBatch material.
     SpriteBatch* batch =  SpriteBatch::create(texture, NULL, particleCountMax);
+    texture->release(); // batch owns the texture
     assert(batch);
 
     ParticleEmitter* emitter = new ParticleEmitter(batch, particleCountMax);
@@ -71,7 +73,9 @@ ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlendin
     emitter->_spriteTextureHeight = texture->getHeight();
     emitter->_spriteTextureWidthRatio = 1.0f / (float)texture->getWidth();
     emitter->_spriteTextureHeightRatio = 1.0f / (float)texture->getHeight();
-    emitter->setSpriteFrameCoords(1, new Rectangle((float)texture->getWidth(), (float)texture->getHeight()));
+
+    Rectangle texCoord((float)texture->getWidth(), (float)texture->getHeight());
+    emitter->setSpriteFrameCoords(1, &texCoord);
 
     return emitter;
 }
@@ -618,6 +622,8 @@ void ParticleEmitter::setSpriteFrameCoords(unsigned int frameCount, int width, i
     }
 
     setSpriteFrameCoords(frameCount, frameCoords);
+
+    SAFE_DELETE_ARRAY(frameCoords);
 }
 
 Node* ParticleEmitter::getNode() const
@@ -627,19 +633,8 @@ Node* ParticleEmitter::getNode() const
 
 void ParticleEmitter::setNode(Node* node)
 {
-    if (_node != node)
-    {
-        // Disconnect our current node.
-        SAFE_RELEASE(_node);
-
-        // Connect the new node.
-        _node = node;
-
-        if (_node)
-        {
-            _node->addRef();
-        }
-    }
+    // Connect the new node.
+    _node = node;
 }
 
 void ParticleEmitter::setOrbit(bool orbitPosition, bool orbitVelocity, bool orbitAcceleration)
@@ -889,16 +884,8 @@ void ParticleEmitter::draw()
             }
         }
 
-        // Disable writing to the depth buffer.
-        GLboolean depthMask;
-        glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
-        glDepthMask(GL_FALSE);
-
         // Render.
         _spriteBatch->end();
-
-        // Turn the depth mask back on if it was on before.
-        glDepthMask(depthMask);
     }
 }
 

+ 2 - 2
gameplay/src/PhysicsController.cpp

@@ -270,7 +270,7 @@ void PhysicsController::addRigidBody(PhysicsRigidBody* body)
 btCollisionShape* PhysicsController::getBox(const Vector3& min, const Vector3& max, const btVector3& scale)
 {
     btVector3 halfExtents(scale.x() * 0.5 * abs(max.x - min.x), scale.y() * 0.5 * abs(max.y - min.y), scale.z() * 0.5 * abs(max.z - min.z));
-    btBoxShape* box = new btBoxShape(halfExtents);
+    BULLET_NEW(btBoxShape, box, halfExtents);
     _shapes.push_back(box);
 
     return box;
@@ -286,7 +286,7 @@ btCollisionShape* PhysicsController::getSphere(float radius, const btVector3& sc
     if (uniformScale < scale.z())
         uniformScale = scale.z();
 
-    btSphereShape* sphere = new btSphereShape(uniformScale * radius);
+    BULLET_NEW(btSphereShape, sphere, uniformScale * radius);
     _shapes.push_back(sphere);
 
     return sphere;

+ 3 - 3
gameplay/src/PhysicsRigidBody.cpp

@@ -84,10 +84,10 @@ PhysicsRigidBody::~PhysicsRigidBody()
             delete _body->getMotionState();
 
         if (_shape)
-            SAFE_DELETE(_shape);
+            BULLET_DELETE(_shape);
 
         Game::getInstance()->getPhysicsController()->removeRigidBody(this);
-        SAFE_DELETE(_body);
+        BULLET_DELETE(_body);
     }
 
     SAFE_DELETE(_listeners);
@@ -186,7 +186,7 @@ btRigidBody* PhysicsRigidBody::createBulletRigidBody(btCollisionShape* shape, fl
     rbInfo.m_restitution = restitution;
     rbInfo.m_linearDamping = linearDamping;
     rbInfo.m_angularDamping = angularDamping;
-    btRigidBody* body = new btRigidBody(rbInfo);
+    BULLET_NEW(btRigidBody, body, rbInfo);
 
     return body;
 }

+ 1 - 2
gameplay/src/PhysicsRigidBody.h

@@ -7,7 +7,6 @@
 
 #include "Mesh.h"
 #include "PhysicsConstraint.h"
-#include "Ref.h"
 #include "Transform.h"
 #include "Vector3.h"
 
@@ -20,7 +19,7 @@ class PhysicsConstraint;
 /**
  * Defines a class for physics rigid bodies.
  */
-class PhysicsRigidBody : public Ref
+class PhysicsRigidBody
 {
     friend class Node;
     friend class PhysicsConstraint;

+ 1 - 1
gameplay/src/Plane.cpp

@@ -245,7 +245,7 @@ void Plane::set(const Plane& plane)
     _distance = plane._distance;
 }
 
-void Plane::transform(Matrix& matrix)
+void Plane::transform(const Matrix& matrix)
 {
     Matrix inverted;
     if (matrix.invert(&inverted))

+ 20 - 1
gameplay/src/Plane.h

@@ -196,7 +196,15 @@ public:
      *
      * @param matrix The transformation matrix to transform by.
      */
-    void transform(Matrix& matrix);
+    void transform(const Matrix& matrix);
+
+    /**
+     * Transforms this plane by the given matrix.
+     * 
+     * @param matrix The matrix to transform by.
+     * @return This plane, after the transformation occurs.
+     */
+    inline Plane& operator*=(const Matrix& matrix);
 
 private:
 
@@ -209,6 +217,17 @@ private:
     float _distance;    // The distance of the Plane along its normal from the origin.
 };
 
+/**
+ * Transforms the given plane by the given matrix.
+ * 
+ * @param matrix The matrix to transform by.
+ * @param plane The plane to transform.
+ * @return The resulting transformed plane.
+ */
+inline Plane operator*(const Matrix& matrix, const Plane& plane);
+
 }
 
+#include "Plane.inl"
+
 #endif

+ 23 - 0
gameplay/src/Plane.inl

@@ -0,0 +1,23 @@
+/** 
+ * Plane.inl
+ */
+
+#include "Plane.h"
+
+namespace gameplay
+{
+
+inline Plane& Plane::operator*=(const Matrix& matrix)
+{
+    transform(matrix);
+    return *this;
+}
+
+inline Plane operator*(const Matrix& matrix, const Plane& plane)
+{
+    Plane p(plane);
+    p.transform(matrix);
+    return p;
+}
+
+}

+ 5 - 5
gameplay/src/Platform.h

@@ -17,6 +17,11 @@ class Platform
 {
 public:
 
+    /**
+     * Destructor.
+     */
+    ~Platform();
+
     /**
      * Creates a platform for the specified game which is will interacte with.
      *
@@ -98,11 +103,6 @@ private:
      */
     Platform(const Platform& copy);
 
-    /**
-     * Destructor.
-     */
-    ~Platform();
-
     Game* _game;
 
 };

+ 335 - 0
gameplay/src/PlatformMacOSX.mm

@@ -0,0 +1,335 @@
+/*
+ * PlatformMacOSX.cpp
+ */
+
+#ifdef __APPLE__
+
+#include "Base.h"
+#include "Platform.h"
+#include "FileSystem.h"
+#include "Game.h"
+#include "Input.h"
+
+#import <Cocoa/Cocoa.h>
+#import <QuartzCore/CVDisplayLink.h>
+#import <OpenGL/OpenGL.h>
+#import <mach/mach_time.h>
+
+using namespace std;
+using namespace gameplay;
+
+
+static const float ACCELEROMETER_X_FACTOR = 90.0f / WINDOW_WIDTH;
+static const float ACCELEROMETER_Y_FACTOR = 90.0f / WINDOW_HEIGHT;
+
+static long __timeStart;
+static long __timeAbsolute;
+static bool __vsync = WINDOW_VSYNC;
+static float __pitch;
+static float __roll;
+static int __lx, __ly;
+static bool __hasMouse = false;
+static bool __leftMouseDown = false;
+static bool __rightMouseDown = false;
+static bool __shiftDown = false;
+
+long getMachTimeInMilliseconds()
+{
+    static const int64_t kOneMillion = 1000 * 1000;
+    static mach_timebase_info_data_t s_timebase_info;
+    
+    if (s_timebase_info.denom == 0) 
+        (void) mach_timebase_info(&s_timebase_info);
+    
+    // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
+    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+}
+
+@class View;
+
+@interface View : NSOpenGLView <NSWindowDelegate> 
+{
+    CVDisplayLinkRef displayLink;
+    
+    Game* _game;
+}
+@end
+
+
+@implementation View
+
+
+-(void)windowWillClose:(NSNotification*)note 
+{
+    _game->exit();
+    [[NSApplication sharedApplication] terminate:self];
+}
+
+- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    [self performSelectorOnMainThread:@selector(update) withObject:nil waitUntilDone:NO];
+    
+    [pool release];
+    return kCVReturnSuccess;
+}
+
+
+-(void) update
+{
+    [[self openGLContext] makeCurrentContext];
+    CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
+    _game->frame();
+    CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]);
+    CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);  
+}
+
+static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, 
+                                      CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
+{
+    CVReturn result = [(View*)displayLinkContext getFrameForTime:outputTime];
+    return result;
+}
+
+- (id) initWithFrame: (NSRect) frame
+{    
+    _game = Game::getInstance();
+    __timeStart = getMachTimeInMilliseconds();
+    NSOpenGLPixelFormatAttribute attrs[] = 
+    {
+        NSOpenGLPFAAccelerated,
+        NSOpenGLPFADoubleBuffer,
+        NSOpenGLPFAColorSize, 32,
+        NSOpenGLPFADepthSize, 24,
+        NSOpenGLPFAAlphaSize, 8,
+        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
+        0
+    };
+    
+    NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+    if (!pf)
+        NSLog(@"OpenGL pixel format not supported.");
+    
+    self = [super initWithFrame:frame pixelFormat:[pf autorelease]];  
+    
+    return self;
+}
+
+- (void) prepareOpenGL
+{
+    [super prepareOpenGL];
+    
+    NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
+    NSString* path = [bundlePath stringByAppendingString:@"/Contents/Resources/"];
+    FileSystem::setResourcePath([path cStringUsingEncoding:NSASCIIStringEncoding]);
+    _game->run(WINDOW_WIDTH, WINDOW_HEIGHT);
+    
+    [[self window] setLevel: NSFloatingWindowLevel];
+    [[self window] makeKeyAndOrderFront: self];
+    [[self window] setTitle: [NSString stringWithUTF8String: ""]];
+    
+    // Make all the OpenGL calls to setup rendering and build the necessary rendering objects
+    [[self openGLContext] makeCurrentContext];
+    // Synchronize buffer swaps with vertical refresh rate
+    GLint swapInt = __vsync ? 1 : 0;
+    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+    
+    // Create a display link capable of being used with all active displays
+    CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
+    
+    // Set the renderer output callback function
+    CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
+    
+    CGLContextObj cglContext = (CGLContextObj)[[self openGLContext] CGLContextObj];
+    CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj];
+    CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
+    
+    // Activate the display link
+    CVDisplayLinkStart(displayLink);
+}
+
+- (void) dealloc
+{       
+    _game->exit();
+    
+    // Release the display link
+    CVDisplayLinkRelease(displayLink);
+    
+    [super dealloc];
+}
+
+- (void) mouseDown: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    _game->touch(point.x, WINDOW_HEIGHT - point.y, Input::TOUCHEVENT_PRESS);
+    __leftMouseDown = true;
+}
+
+- (void) mouseUp: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    __leftMouseDown = false;
+    _game->touch(point.x, WINDOW_HEIGHT - point.y, Input::TOUCHEVENT_RELEASE);
+}
+
+- (void) mouseDragged: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    if (__leftMouseDown)
+    {
+        gameplay::Game::getInstance()->touch(point.x, WINDOW_HEIGHT - point.y, gameplay::Input::TOUCHEVENT_MOVE);
+    }
+}
+
+- (void) rightMouseDown: (NSEvent*) theEvent
+{
+    __rightMouseDown = true;
+     NSPoint point = [theEvent locationInWindow];
+    __lx = point.x;
+    __ly = WINDOW_HEIGHT - point.y;
+}
+
+- (void) rightMouseUp: (NSEvent*) theEvent
+{
+   __rightMouseDown = false;
+}
+
+- (void) rightMouseDragged: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    if (__rightMouseDown)
+    {
+        // Update the pitch and roll by adding the scaled deltas.
+        __roll += -(float)(point.x - __lx) * ACCELEROMETER_X_FACTOR;
+        __pitch -= (float)(point.y - (WINDOW_HEIGHT - __ly)) * ACCELEROMETER_Y_FACTOR;
+    
+        // Clamp the values to the valid range.
+        __roll = fmaxf(fminf(__roll, 90.0), -90.0);
+        __pitch = fmaxf(fminf(__pitch, 90.0), -90.0);
+    
+        // Update the last X/Y values.
+        __lx = point.x;
+        __ly = (WINDOW_HEIGHT - point.y);
+    }
+}
+
+- (void) mouseEntered:(NSEvent *)theEvent
+{
+    __hasMouse = true;
+}
+
+- (void) mouseExited:(NSEvent *)theEvent
+{
+    __leftMouseDown = false;
+    __rightMouseDown = false;
+    __hasMouse = false;
+}
+
+@end
+
+
+namespace gameplay
+{
+
+extern void printError(const char* format, ...)
+{
+    va_list argptr;
+    va_start(argptr, format);
+    vfprintf(stderr, format, argptr);
+    fprintf(stderr, "\n");
+    va_end(argptr);
+}
+    
+    
+Platform::Platform(Game* game)
+: _game(game)
+{
+}
+
+Platform::Platform(const Platform& copy)
+{
+    // hidden
+}
+
+Platform::~Platform()
+{
+}
+
+Platform* Platform::create(Game* game)
+{
+    Platform* platform = new Platform(game);
+    
+    return platform;
+}
+
+int Platform::enterMessagePump()
+{
+    NSAutoreleasePool *pool = [NSAutoreleasePool new];
+    NSApplication* NSApp = [NSApplication sharedApplication];
+    NSRect screenBounds = [[NSScreen mainScreen] frame];
+    NSRect viewBounds = NSMakeRect(0, 0, 1024, 600);
+    
+    View* view = [[View alloc] initWithFrame:viewBounds];
+    
+    NSRect centered = NSMakeRect(NSMidX(screenBounds) - NSMidX(viewBounds),
+                                 NSMidY(screenBounds) - NSMidY(viewBounds),
+                                 viewBounds.size.width, 
+                                 viewBounds.size.height);
+    
+    NSWindow *window = [[NSWindow alloc]
+                        initWithContentRect:centered
+                        styleMask:NSTitledWindowMask | NSClosableWindowMask
+                        backing:NSBackingStoreBuffered
+                        defer:NO];
+    
+    [window setContentView:view];
+    [window setDelegate:view];
+    [view release];
+    
+    [NSApp run];
+    
+    [pool release];
+    return EXIT_SUCCESS;
+}
+    
+long Platform::getAbsoluteTime()
+{
+    __timeAbsolute = getMachTimeInMilliseconds();
+    return __timeAbsolute;
+}
+
+void Platform::setAbsoluteTime(long time)
+{
+    __timeAbsolute = time;
+}
+
+bool Platform::isVsync()
+{
+    return __vsync;
+}
+
+void Platform::setVsync(bool enable)
+{
+    __vsync = enable;
+}
+
+int Platform::getOrientationAngle()
+{
+    return 0;
+}
+
+bool Platform::isAccelerometerSupported()
+{
+    return true;
+}
+
+void Platform::getAccelerometerPitchAndRoll(float* pitch, float* roll)
+{
+    *pitch = __pitch;
+    *roll = __roll;
+}
+    
+}
+
+#endif

+ 1 - 1
gameplay/src/PlatformQNX.cpp

@@ -324,7 +324,7 @@ Platform* Platform::create(Game* game)
     {
         // Disable VAO extension for now.
         glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
-        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glBindVertexArrayOES");
+        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArrays");
         glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
         glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
     }

+ 2 - 3
gameplay/src/Properties.cpp

@@ -2,10 +2,9 @@
  * Properties.cpp
  */
 
+#include "Base.h"
 #include "Properties.h"
 #include "FileSystem.h"
-#include <xtree>
-#include <sstream>
 
 namespace gameplay
 {
@@ -363,7 +362,7 @@ Properties::Type Properties::getType(const char* name) const
 
     // Parse the value to determine the format
     unsigned int commaCount = 0;
-    unsigned int length = strlen(value);
+    //unsigned int length = strlen(value);
     char* valuePtr = const_cast<char*>(value);
     while (valuePtr = strchr(valuePtr, ','))
     {

+ 1 - 0
gameplay/src/Properties.h

@@ -7,6 +7,7 @@
 
 #include "Base.h"
 #include "Matrix.h"
+#include "Vector2.h"
 
 namespace gameplay
 {

+ 19 - 11
gameplay/src/Quaternion.cpp

@@ -23,6 +23,15 @@ Quaternion::Quaternion(float* array)
     set(array);
 }
 
+Quaternion::Quaternion(const Matrix& m)
+{
+    set(m);
+}
+
+Quaternion::Quaternion(const Vector3& axis, float angle)
+{
+    set(axis, angle);
+}
 
 Quaternion::Quaternion(const Quaternion& copy)
 {
@@ -35,14 +44,14 @@ Quaternion::~Quaternion()
 
 const Quaternion& Quaternion::identity()
 {
-    static Quaternion* value = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
-    return *value;
+    static Quaternion value(0.0f, 0.0f, 0.0f, 1.0f);
+    return value;
 }
 
 const Quaternion& Quaternion::zero()
 {
-    static Quaternion* value = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f);
-    return *value;
+    static Quaternion value(0.0f, 0.0f, 0.0f, 0.0f);
+    return value;
 }
 
 bool Quaternion::isIdentity() const
@@ -192,15 +201,14 @@ void Quaternion::set(float* array)
     w = array[3];
 }
 
-void Quaternion::set(const Vector3& axis, float angle)
+void Quaternion::set(const Matrix& m)
 {
-    Quaternion rotationQuat;
-    Quaternion::createFromAxisAngle(axis, angle, &rotationQuat);
+    Quaternion::createFromRotationMatrix(m, this);
+}
 
-    this->x = rotationQuat.x;
-    this->y = rotationQuat.y;
-    this->z = rotationQuat.z;
-    this->w = rotationQuat.w;
+void Quaternion::set(const Vector3& axis, float angle)
+{
+    Quaternion::createFromAxisAngle(axis, angle, this);
 }
 
 void Quaternion::set(const Quaternion& q)

+ 42 - 0
gameplay/src/Quaternion.h

@@ -85,6 +85,21 @@ public:
      */
     Quaternion(float* array);
 
+    /**
+     * Constructs a quaternion equal to the rotational part of the specified matrix.
+     *
+     * @param m The matrix.
+     */
+    Quaternion(const Matrix& m);
+
+    /**
+     * Constructs a quaternion equal to the rotation from the specified axis and angle.
+     *
+     * @param axis A vector describing the axis of rotation.
+     * @param angle The angle of rotation (in radians).
+     */
+    Quaternion(const Vector3& axis, float angle);
+
     /**
      * Constructs a new quaternion that is a copy of the specified one.
      *
@@ -234,6 +249,13 @@ public:
      */
     void set(float* array);
 
+    /**
+     * Sets the quaternion equal to the rotational part of the specified matrix.
+     *
+     * @param m The matrix.
+     */
+    void set(const Matrix& m);
+
     /**
      * Sets the quaternion equal to the rotation from the specified axis and angle.
      * 
@@ -312,6 +334,24 @@ public:
      */
     static void squad(const Quaternion& q1, const Quaternion& q2, const Quaternion& s1, const Quaternion& s2, float t, Quaternion* dst);
 
+    /**
+     * Calculates the quaternion product of this quaternion with the given quaternion.
+     * 
+     * Note: this does not modify this quaternion.
+     * 
+     * @param q The quaternion to multiply.
+     * @return The quaternion product.
+     */
+    inline Quaternion operator*(const Quaternion& q);
+
+    /**
+     * Multiplies this quaternion with the given quaternion.
+     * 
+     * @param q The quaternion to multiply.
+     * @return This quaternion, after the multiplication occurs.
+     */
+    inline Quaternion& operator*=(const Quaternion& q);
+
 private:
 
     static void slerpForSquad(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
@@ -319,4 +359,6 @@ private:
 
 }
 
+#include "Quaternion.inl"
+
 #endif

+ 23 - 0
gameplay/src/Quaternion.inl

@@ -0,0 +1,23 @@
+/** 
+ * Quaternion.inl
+ */
+
+#include "Quaternion.h"
+
+namespace gameplay
+{
+
+inline Quaternion Quaternion::operator*(const Quaternion& q)
+{
+    Quaternion result(*this);
+    result.multiply(q);
+    return result;
+}
+
+inline Quaternion& Quaternion::operator*=(const Quaternion& q)
+{
+    multiply(q);
+    return *this;
+}
+
+}

+ 19 - 0
gameplay/src/Ray.h

@@ -145,6 +145,14 @@ public:
      */
     void transform(const Matrix& matrix);
 
+    /**
+     * Transforms this ray by the given matrix.
+     * 
+     * @param matrix The matrix to transform by.
+     * @return This ray, after the transformation occurs.
+     */
+    inline Ray& operator*=(const Matrix& matrix);
+
 private:
 
     /**
@@ -156,6 +164,17 @@ private:
     Vector3 _direction;     // The ray direction vector.
 };
 
+/**
+ * Transforms the given ray by the given matrix.
+ * 
+ * @param matrix The matrix to transform by.
+ * @param ray The ray to transform.
+ * @return The resulting transformed ray.
+ */
+inline Ray operator*(const Matrix& matrix, const Ray& ray);
+
 }
 
+#include "Ray.inl"
+
 #endif

+ 23 - 0
gameplay/src/Ray.inl

@@ -0,0 +1,23 @@
+/** 
+ * Ray.inl
+ */
+
+#include "Ray.h"
+
+namespace gameplay
+{
+
+inline Ray& Ray::operator*=(const Matrix& matrix)
+{
+    transform(matrix);
+    return *this;
+}
+
+inline Ray operator*(const Matrix& matrix, const Ray& ray)
+{
+    Ray r(ray);
+    r.transform(matrix);
+    return r;
+}
+
+}

+ 86 - 0
gameplay/src/Ref.cpp

@@ -4,13 +4,22 @@
 
 #include "Base.h"
 #include "Ref.h"
+#include "Game.h"
 
 namespace gameplay
 {
 
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+void* trackRef(Ref* ref);
+void untrackRef(Ref* ref, void* record);
+#endif
+
 Ref::Ref() :
     _refCount(1)
 {
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+    __record = trackRef(this);
+#endif
 }
 
 Ref::~Ref()
@@ -26,8 +35,85 @@ void Ref::release()
 {
     if ((--_refCount) <= 0)
     {
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+        untrackRef(this, __record);
+#endif
         delete this;
     }
 }
 
+unsigned int Ref::getRefCount() const
+{
+    return _refCount;
+}
+
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+
+struct RefAllocationRecord
+{
+    Ref* ref;
+    RefAllocationRecord* next;
+    RefAllocationRecord* prev;
+};
+
+RefAllocationRecord* __refAllocations = 0;
+int __refAllocationCount = 0;
+
+void Ref::printLeaks()
+{
+    // Dump Ref object memory leaks
+    if (__refAllocationCount == 0)
+    {
+        printError("[memory] All Ref objects successfully cleaned up (no leaks detected).");
+    }
+    else
+    {
+        printError("[memory] WARNING: %d Ref objects still active in memory.", __refAllocationCount);
+        for (RefAllocationRecord* rec = __refAllocations; rec != NULL; rec = rec->next)
+        {
+            Ref* ref = rec->ref;
+            const char* type = typeid(*ref).name();
+            printError("[memory] LEAK: Ref object '%s' still active with reference count %d.", (type ? type : ""), ref->getRefCount());
+        }
+    }
+}
+
+void* trackRef(Ref* ref)
+{
+    // Create memory allocation record
+    RefAllocationRecord* rec = (RefAllocationRecord*)malloc(sizeof(RefAllocationRecord));
+    rec->ref = ref;
+    rec->next = __refAllocations;
+    rec->prev = 0;
+
+    if (__refAllocations)
+        __refAllocations->prev = rec;
+    __refAllocations = rec;
+    ++__refAllocationCount;
+
+    return rec;
+}
+
+void untrackRef(Ref* ref, void* record)
+{
+    RefAllocationRecord* rec = (RefAllocationRecord*)record;
+    if (rec->ref != ref)
+    {
+        printError("[memory] CORRUPTION: Attempting to free Ref with invalid ref tracking record.");
+        return;
+    }
+
+    // Link this item out
+    if (__refAllocations == rec)
+        __refAllocations = rec->next;
+    if (rec->prev)
+        rec->prev->next = rec->next;
+    if (rec->next)
+        rec->next->prev = rec->prev;
+    free((void*)rec);
+    --__refAllocationCount;
+}
+
+#endif
+
 }

+ 14 - 0
gameplay/src/Ref.h

@@ -40,6 +40,13 @@ public:
      */
     void release();
 
+    /**
+     * Returns the current reference count of this object.
+     *
+     * @return This object's reference count.
+     */
+    unsigned int getRefCount() const;
+
 protected:
 
     /**
@@ -55,6 +62,13 @@ protected:
 private:
 
     unsigned int _refCount;
+
+    // Memory leak diagnostic data (only included when GAMEPLAY_MEM_LEAK_DETECTION is defined)
+#ifdef GAMEPLAY_MEM_LEAK_DETECTION
+    friend class Game;
+    static void printLeaks();
+    void* __record;
+#endif
 };
 
 }

+ 44 - 31
gameplay/src/RenderState.cpp

@@ -18,7 +18,7 @@
 namespace gameplay
 {
 
-RenderState::StateBlock RenderState::StateBlock::_defaultState;
+RenderState::StateBlock* RenderState::StateBlock::_defaultState = NULL;
 
 RenderState::RenderState()
     : _nodeBinding(NULL), _state(NULL), _parent(NULL)
@@ -44,6 +44,19 @@ RenderState::~RenderState()
     }
 }
 
+void RenderState::initialize()
+{
+    if (StateBlock::_defaultState == NULL)
+    {
+        StateBlock::_defaultState = StateBlock::create();
+    }
+}
+
+void RenderState::finalize()
+{
+    SAFE_RELEASE(StateBlock::_defaultState);
+}
+
 MaterialParameter* RenderState::getParameter(const char* name) const
 {
     assert(name);
@@ -305,75 +318,75 @@ void RenderState::StateBlock::bind()
 void RenderState::StateBlock::bindNoRestore()
 {
     // Update any state that differs from _defaultState and flip _defaultState bits
-    if ((_bits & RS_BLEND) && (_blendEnabled != _defaultState._blendEnabled))
+    if ((_bits & RS_BLEND) && (_blendEnabled != _defaultState->_blendEnabled))
     {
         _blendEnabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
-        _defaultState._blendEnabled = _blendEnabled;
+        _defaultState->_blendEnabled = _blendEnabled;
     }
-    if ((_bits & RS_BLEND_FUNC) && (_srcBlend != _defaultState._srcBlend || _dstBlend != _defaultState._dstBlend))
+    if ((_bits & RS_BLEND_FUNC) && (_srcBlend != _defaultState->_srcBlend || _dstBlend != _defaultState->_dstBlend))
     {
         glBlendFunc((GLenum)_srcBlend, (GLenum)_dstBlend);
-        _defaultState._srcBlend = _srcBlend;
-        _defaultState._dstBlend = _dstBlend;
+        _defaultState->_srcBlend = _srcBlend;
+        _defaultState->_dstBlend = _dstBlend;
     }
-    if ((_bits & RS_CULL_FACE) && (_cullFaceEnabled != _defaultState._cullFaceEnabled))
+    if ((_bits & RS_CULL_FACE) && (_cullFaceEnabled != _defaultState->_cullFaceEnabled))
     {
         _cullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
-        _defaultState._cullFaceEnabled = _cullFaceEnabled;
+        _defaultState->_cullFaceEnabled = _cullFaceEnabled;
     }
-    if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState._depthTestEnabled))
+    if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
     {
         _depthTestEnabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
-        _defaultState._depthTestEnabled = _depthTestEnabled;
+        _defaultState->_depthTestEnabled = _depthTestEnabled;
     }
-    if ((_bits & RS_DEPTH_WRITE) && (_depthWriteEnabled != _defaultState._depthWriteEnabled))
+    if ((_bits & RS_DEPTH_WRITE) && (_depthWriteEnabled != _defaultState->_depthWriteEnabled))
     {
         glDepthMask(_depthWriteEnabled);
-        _defaultState._depthWriteEnabled = _depthWriteEnabled;
+        _defaultState->_depthWriteEnabled = _depthWriteEnabled;
     }
 
-    _defaultState._bits |= _bits;
+    _defaultState->_bits |= _bits;
 }
 
 void RenderState::StateBlock::restore(long stateOverrideBits)
 {
     // If there is no state to restore (i.e. no non-default state), do nothing
-    if (_defaultState._bits == 0)
+    if (_defaultState->_bits == 0)
     {
         return;
     }
 
     // Restore any state that is not overridden and is not default
-    if (!(stateOverrideBits & RS_BLEND) && (_defaultState._bits & RS_BLEND))
+    if (!(stateOverrideBits & RS_BLEND) && (_defaultState->_bits & RS_BLEND))
     {
         glDisable(GL_BLEND);
-        _defaultState._bits &= ~RS_BLEND;
-        _defaultState._blendEnabled = false;
+        _defaultState->_bits &= ~RS_BLEND;
+        _defaultState->_blendEnabled = false;
     }
-    if (!(stateOverrideBits & RS_BLEND_FUNC) && (_defaultState._bits & RS_BLEND_FUNC))
+    if (!(stateOverrideBits & RS_BLEND_FUNC) && (_defaultState->_bits & RS_BLEND_FUNC))
     {
         glBlendFunc(GL_ONE, GL_ONE);
-        _defaultState._bits &= ~RS_BLEND_FUNC;
-        _defaultState._srcBlend = RenderState::BLEND_ONE;
-        _defaultState._dstBlend = RenderState::BLEND_ONE;
+        _defaultState->_bits &= ~RS_BLEND_FUNC;
+        _defaultState->_srcBlend = RenderState::BLEND_ONE;
+        _defaultState->_dstBlend = RenderState::BLEND_ONE;
     }
-    if (!(stateOverrideBits & RS_CULL_FACE) && (_defaultState._bits & RS_CULL_FACE))
+    if (!(stateOverrideBits & RS_CULL_FACE) && (_defaultState->_bits & RS_CULL_FACE))
     {
         glDisable(GL_CULL_FACE);
-        _defaultState._bits &= ~RS_CULL_FACE;
-        _defaultState._cullFaceEnabled = false;
+        _defaultState->_bits &= ~RS_CULL_FACE;
+        _defaultState->_cullFaceEnabled = false;
     }
-    if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState._bits & RS_DEPTH_TEST))
+    if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState->_bits & RS_DEPTH_TEST))
     {
         glDisable(GL_DEPTH_TEST);
-        _defaultState._bits &= ~RS_DEPTH_TEST;
-        _defaultState._depthTestEnabled = false;
+        _defaultState->_bits &= ~RS_DEPTH_TEST;
+        _defaultState->_depthTestEnabled = false;
     }
-    if (!(stateOverrideBits & RS_DEPTH_WRITE) && (_defaultState._bits & RS_DEPTH_WRITE))
+    if (!(stateOverrideBits & RS_DEPTH_WRITE) && (_defaultState->_bits & RS_DEPTH_WRITE))
     {
         glDepthMask(GL_TRUE);
-        _defaultState._bits &= ~RS_DEPTH_WRITE;
-        _defaultState._depthWriteEnabled = true;
+        _defaultState->_bits &= ~RS_DEPTH_WRITE;
+        _defaultState->_depthWriteEnabled = true;
     }
 }
 
@@ -395,7 +408,7 @@ RenderState::Blend parseBlend(const char* value)
 {
     // Conver the string to uppercase for comparison
     std::string upper(value);
-    std::transform(upper.begin(), upper.end(), upper.begin(), std::toupper);
+    transform(upper.begin(), upper.end(), upper.begin(), toupper);
     if (upper == "ZERO")
         return RenderState::BLEND_ZERO;
     if (upper == "ONE")

+ 12 - 3
gameplay/src/RenderState.h

@@ -16,6 +16,7 @@ class Pass;
 
 class RenderState : public Ref
 {
+    friend class Game;
     friend class Material;
     friend class Technique;
     friend class Pass;
@@ -198,7 +199,7 @@ public:
         // State bits
         long _bits;
 
-        static StateBlock _defaultState;
+        static StateBlock* _defaultState;
     };
 
     /**
@@ -279,6 +280,16 @@ protected:
      */
     virtual ~RenderState();
 
+    /**
+     * Static initializer that is called during game startup.
+     */
+    static void initialize();
+
+    /**
+     * Static finalizer that is called during game shutdown.
+     */
+    static void finalize();
+
     /**
      * Sets the node that this render state is bound to.
      *
@@ -311,8 +322,6 @@ protected:
     Node* _nodeBinding;
     mutable StateBlock* _state;
     RenderState* _parent;
-   
-    static StateBlock* _restoreState;
 };
 
 }

+ 34 - 4
gameplay/src/Scene.cpp

@@ -21,6 +21,19 @@ Scene::Scene(const Scene& copy)
 
 Scene::~Scene()
 {
+    // Unbind our active camera from the audio listener
+    if (_activeCamera)
+    {
+        AudioListener* audioListener = AudioListener::getInstance();
+        if (audioListener && (audioListener->getCamera() == _activeCamera))
+        {
+            audioListener->setCamera(NULL);
+        }
+
+        SAFE_RELEASE(_activeCamera);
+    }
+
+    // Remove all nodes from the scene
     removeAllNodes();
 }
 
@@ -116,6 +129,14 @@ void Scene::addNode(Node* node)
 {
     assert(node);
 
+    if (node->_scene == this)
+    {
+        // The node is already a member of this scene.
+        return;
+    }
+
+    node->addRef();
+
     // If the node is part of another scene, remove it.
     if (node->_scene && node->_scene != this)
     {
@@ -125,7 +146,7 @@ void Scene::addNode(Node* node)
     // If the node is part of another node hierarchy, remove it.
     if (node->getParent())
     {
-        node->remove();
+        node->getParent()->removeChild(node);
     }
 
     // Link the new node into our list.
@@ -142,8 +163,6 @@ void Scene::addNode(Node* node)
 
     node->_scene = this;
 
-    node->addRef();
-
     ++_nodeCount;
 
     // If we don't have an active camera set, then check for one and set it.
@@ -209,16 +228,26 @@ void Scene::setActiveCamera(Camera* camera)
     // Make sure we don't release the camera if the same camera is set twice.
     if (_activeCamera != camera)
     {
+        AudioListener* audioListener = AudioListener::getInstance();
+
         if (_activeCamera)
         {
+            // Unbind the active camera from the audio listener
+            if (audioListener && (audioListener->getCamera() == _activeCamera))
+            {
+                AudioListener::getInstance()->setCamera(NULL);
+            }
+
             SAFE_RELEASE(_activeCamera);
         }
 
         _activeCamera = camera;
+
         if (_activeCamera)
         {
             _activeCamera->addRef();
-            if (_bindAudioListenerToCamera && AudioListener::getInstance())
+
+            if (audioListener && _bindAudioListenerToCamera)
             {
                 AudioListener::getInstance()->setCamera(_activeCamera);
             }
@@ -231,6 +260,7 @@ void Scene::bindAudioListenerToCamera(bool bind)
     if (_bindAudioListenerToCamera != bind)
     {
         _bindAudioListenerToCamera = bind;
+
         if (AudioListener::getInstance())
         {
             AudioListener::getInstance()->setCamera(bind ? _activeCamera : NULL);

+ 24 - 22
gameplay/src/SpriteBatch.cpp

@@ -19,29 +19,31 @@
 
 // Default sprite vertex shader
 #define SPRITE_VSH \
-    "uniform mat4 sb_projection_matrix;" \
-    "attribute vec3 a_position;" \
-    "attribute vec2 a_texcoord;" \
-    "attribute vec4 a_color;" \
-    "varying vec2 vtexcoord;" \
-    "varying vec4 vcolor;" \
-    "void main()" \
-    "{" \
-        "gl_Position = sb_projection_matrix * vec4(a_position, 1);" \
-        "vtexcoord = a_texcoord;" \
-        "vcolor = a_color;" \
-    "}"
+    "uniform mat4 u_projectionMatrix;\n" \
+    "attribute vec3 a_position;\n" \
+    "attribute vec2 a_texcoord;\n" \
+    "attribute vec4 a_color;\n" \
+    "varying vec2 v_texcoord;\n" \
+    "varying vec4 v_color;\n" \
+    "void main()\n" \
+    "{\n" \
+        "gl_Position = u_projectionMatrix * vec4(a_position, 1);\n" \
+        "v_texcoord = a_texcoord;\n" \
+        "v_color = a_color;\n" \
+    "}\n"
 
 // Default sprite fragment shader
 #define SPRITE_FSH \
-    "precision mediump float;" \
-    "varying vec2 vtexcoord;" \
-    "varying vec4 vcolor;" \
-    "uniform sampler2D texture;" \
-    "void main()" \
-    "{" \
-        "gl_FragColor = vcolor * texture2D(texture, vtexcoord);" \
-    "}"
+    "#ifdef OPENGL_ES\n" \
+    "precision highp float;\n" \
+    "#endif\n" \
+    "varying vec2 v_texcoord;\n" \
+    "varying vec4 v_color;\n" \
+    "uniform sampler2D u_texture;\n" \
+    "void main()\n" \
+    "{\n" \
+        "gl_FragColor = v_color * texture2D(u_texture, v_texcoord);\n" \
+    "}\n"
 
 namespace gameplay
 {
@@ -147,8 +149,8 @@ SpriteBatch* SpriteBatch::create(Texture* texture, Effect* effect, unsigned int
     batch->_textureHeightRatio = 1.0f / (float)texture->getHeight();
     batch->resizeBatch(initialCapacity > 0 ? initialCapacity : SPRITE_BATCH_DEFAULT_SIZE);
 
-    // If there is a uniform named 'sb_projection_matrix', store it so that we can set our projection matrix to it
-    batch->_projectionUniform = effect->getUniform("sb_projection_matrix");
+    // If there is a uniform named 'u_projectionMatrix', store it so that we can set our projection matrix to it
+    batch->_projectionUniform = effect->getUniform("u_projectionMatrix");
     if (batch->_projectionUniform)
     {
         batch->_projectionMatrix = new Matrix();

+ 0 - 2
gameplay/src/Texture.h

@@ -27,8 +27,6 @@ public:
         ALPHA = GL_ALPHA,
         RGB888 = GL_RGB,
         RGBA8888 = GL_RGBA,
-        LUMINANCE = GL_LUMINANCE,
-        LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
         DEPTH = GL_DEPTH_COMPONENT
     };
 

+ 8 - 8
gameplay/src/Vector2.cpp

@@ -39,26 +39,26 @@ Vector2::~Vector2()
 
 const Vector2& Vector2::zero()
 {
-    static Vector2* value = new Vector2(0.0f, 0.0f);
-    return *value;
+    static Vector2 value(0.0f, 0.0f);
+    return value;
 }
 
 const Vector2& Vector2::one()
 {
-    static Vector2* value = new Vector2(1.0f, 1.0f);
-    return *value;
+    static Vector2 value(1.0f, 1.0f);
+    return value;
 }
 
 const Vector2& Vector2::unitX()
 {
-    static Vector2* value = new Vector2(1.0f, 0.0f);
-    return *value;
+    static Vector2 value(1.0f, 0.0f);
+    return value;
 }
 
 const Vector2& Vector2::unitY()
 {
-    static Vector2* value = new Vector2(0.0f, 1.0f);
-    return *value;
+    static Vector2 value(0.0f, 1.0f);
+    return value;
 }
 
 bool Vector2::isZero() const

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно