瀏覽代碼

Merge pull request #499 from blackberry/next

gameplay v1.5.0
Sean Paul Taylor 13 年之前
父節點
當前提交
c44a22146b
共有 100 個文件被更改,包括 5541 次插入1438 次删除
  1. 100 42
      .gitignore
  2. 1 0
      .kateconfig
  3. 29 0
      CHANGES.md
  4. 26 0
      CMakeLists.txt
  5. 6 6
      README.md
  6. 8 0
      cmake/README.md
  7. 145 0
      gameplay-encoder/CMakeLists.txt
  8. 37 23
      gameplay-encoder/README.md
  9. 1 1
      gameplay-encoder/gameplay-bundle.txt
  10. 7 5
      gameplay-encoder/gameplay-encoder.vcxproj
  11. 9 0
      gameplay-encoder/gameplay-encoder.vcxproj.filters
  12. 2 2
      gameplay-encoder/gameplay-encoder.vcxproj.user
  13. 28 0
      gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj
  14. 12 63
      gameplay-encoder/src/AnimationChannel.cpp
  15. 5 8
      gameplay-encoder/src/AnimationChannel.h
  16. 12 8
      gameplay-encoder/src/Base.h
  17. 9 0
      gameplay-encoder/src/BoundingVolume.cpp
  18. 1 0
      gameplay-encoder/src/Camera.cpp
  19. 1 1
      gameplay-encoder/src/Curve.cpp
  20. 1 1
      gameplay-encoder/src/DAEOptimizer.cpp
  21. 78 84
      gameplay-encoder/src/DAESceneEncoder.cpp
  22. 0 3
      gameplay-encoder/src/DAESceneEncoder.h
  23. 17 17
      gameplay-encoder/src/DAEUtil.cpp
  24. 93 39
      gameplay-encoder/src/EncoderArguments.cpp
  25. 11 8
      gameplay-encoder/src/EncoderArguments.h
  26. 321 159
      gameplay-encoder/src/FBXSceneEncoder.cpp
  27. 1 11
      gameplay-encoder/src/FBXSceneEncoder.h
  28. 2 0
      gameplay-encoder/src/FileIO.h
  29. 103 34
      gameplay-encoder/src/GPBFile.cpp
  30. 8 2
      gameplay-encoder/src/GPBFile.h
  31. 533 0
      gameplay-encoder/src/Heightmap.cpp
  32. 27 0
      gameplay-encoder/src/Heightmap.h
  33. 1 1
      gameplay-encoder/src/Light.cpp
  34. 4 228
      gameplay-encoder/src/Mesh.cpp
  35. 0 7
      gameplay-encoder/src/Mesh.h
  36. 19 19
      gameplay-encoder/src/MeshSkin.cpp
  37. 0 25
      gameplay-encoder/src/Node.cpp
  38. 0 6
      gameplay-encoder/src/Node.h
  39. 1 0
      gameplay-encoder/src/Object.h
  40. 3 3
      gameplay-encoder/src/Quaternion.cpp
  41. 12 12
      gameplay-encoder/src/TTFFontEncoder.cpp
  42. 99 0
      gameplay-encoder/src/Thread.h
  43. 11 32
      gameplay-encoder/src/Transform.cpp
  44. 10 9
      gameplay-encoder/src/Transform.h
  45. 1 1
      gameplay-encoder/src/Vector4.cpp
  46. 19 8
      gameplay-encoder/src/Vertex.cpp
  47. 21 12
      gameplay-encoder/src/Vertex.h
  48. 4 4
      gameplay-encoder/src/main.cpp
  49. 23 15
      gameplay-luagen/gameplay-luagen.doxyfile
  50. 4 2
      gameplay-luagen/gameplay-luagen.vcxproj
  51. 70 70
      gameplay-newproject.bat
  52. 54 36
      gameplay-newproject.sh
  53. 3 3
      gameplay-template/gameplay-template.vcxproj
  54. 3 3
      gameplay-template/gameplay-template.vcxproj.user
  55. 6 32
      gameplay-template/gameplay-template.xcodeproj/project.pbxproj
  56. 二進制
      gameplay-template/icon.png
  57. 0 2
      gameplay-template/template.bar-descriptor.xml
  58. 28 21
      gameplay-template/template.cproject
  59. 23 15
      gameplay.doxyfile
  60. 198 8
      gameplay.sln
  61. 30 0
      gameplay.workspace
  62. 6 0
      gameplay.xcworkspace/contents.xcworkspacedata
  63. 614 0
      gameplay/CMakeLists.txt
  64. 11 2
      gameplay/android/jni/Android.mk
  65. 591 0
      gameplay/gameplay.cbp
  66. 255 8
      gameplay/gameplay.vcxproj
  67. 74 20
      gameplay/gameplay.vcxproj.filters
  68. 996 3
      gameplay/gameplay.xcodeproj/project.pbxproj
  69. 58 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme
  70. 58 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme
  71. 4 1
      gameplay/res/shaders/colored-unlit.frag
  72. 16 2
      gameplay/res/shaders/colored-unlit.vert
  73. 11 4
      gameplay/res/shaders/textured-unlit.frag
  74. 14 5
      gameplay/res/shaders/textured-unlit.vert
  75. 24 23
      gameplay/src/Animation.cpp
  76. 30 29
      gameplay/src/Animation.h
  77. 5 5
      gameplay/src/AnimationClip.cpp
  78. 1 1
      gameplay/src/AnimationController.cpp
  79. 35 35
      gameplay/src/AnimationTarget.cpp
  80. 23 23
      gameplay/src/AnimationTarget.h
  81. 6 6
      gameplay/src/AnimationValue.cpp
  82. 10 10
      gameplay/src/AnimationValue.h
  83. 8 6
      gameplay/src/AudioBuffer.cpp
  84. 1 1
      gameplay/src/AudioBuffer.h
  85. 16 0
      gameplay/src/AudioListener.cpp
  86. 30 0
      gameplay/src/AudioListener.h
  87. 7 2
      gameplay/src/AudioSource.cpp
  88. 9 0
      gameplay/src/AudioSource.h
  89. 27 11
      gameplay/src/Base.h
  90. 11 0
      gameplay/src/BoundingBox.cpp
  91. 24 0
      gameplay/src/BoundingBox.h
  92. 18 19
      gameplay/src/Bundle.cpp
  93. 1 1
      gameplay/src/Bundle.h
  94. 27 26
      gameplay/src/Button.cpp
  95. 1 0
      gameplay/src/Button.h
  96. 10 9
      gameplay/src/CheckBox.cpp
  97. 159 81
      gameplay/src/Container.cpp
  98. 9 0
      gameplay/src/Container.h
  99. 39 14
      gameplay/src/Control.cpp
  100. 21 0
      gameplay/src/Control.h

+ 100 - 42
.gitignore

@@ -1,13 +1,16 @@
 *.suo
 *.suo
 *.sdf
 *.sdf
-*.opensdf
-.DS_Store*
-ehthumbs.db
-Icon?
+*.opensdf
+*.layout
+*.depend
+.DS_Store*
+ehthumbs.db
+Icon?
 Thumbs.db
 Thumbs.db
 /.metadata
 /.metadata
 /169.254.0.1
 /169.254.0.1
 /ipch
 /ipch
+/cmake
 /Debug
 /Debug
 /Release
 /Release
 /Simulator
 /Simulator
@@ -17,6 +20,18 @@ Thumbs.db
 /Device-Coverage
 /Device-Coverage
 /Device-Profile
 /Device-Profile
 /Device-Release
 /Device-Release
+/gameplay-internal
+/gameplay-api/xml
+
+/gameplay-encoder/Debug
+/gameplay-encoder/Release
+/gameplay-encoder/gameplay-encoder.xcodeproj/xcuserdata
+
+/gameplay-luagen/Release
+/gameplay-luagen/Debug
+/gameplay-luagen/doxygen_entrydb_680.tmp
+/gameplay-luagen/doxygen_objdb_680.tmp
+/gameplay-luagen/xml
 
 
 /gameplay/Debug
 /gameplay/Debug
 /gameplay/DebugMem
 /gameplay/DebugMem
@@ -27,26 +42,39 @@ Thumbs.db
 /gameplay/Device-Debug
 /gameplay/Device-Debug
 /gameplay/Device-Coverage
 /gameplay/Device-Coverage
 /gameplay/Device-Profile
 /gameplay/Device-Profile
-/gameplay/Device-Release
+/gameplay/Device-Release
 /gameplay.xcworkspace/xcuserdata
 /gameplay.xcworkspace/xcuserdata
-/gameplay/gameplay.xcodeproj/xcuserdata
+/gameplay/gameplay.xcodeproj/xcuserdata
 /gameplay/android/NUL
 /gameplay/android/NUL
 /gameplay/android/proguard.cfg
 /gameplay/android/proguard.cfg
+/gameplay/android/proguard-project.txt
 /gameplay/android/local.properties
 /gameplay/android/local.properties
 /gameplay/android/project.properties
 /gameplay/android/project.properties
-/gameplay/android/obj
-
-/gameplay-api/xml
-
-/gameplay-encoder/Debug
-/gameplay-encoder/Release
-/gameplay-encoder/gameplay-encoder.xcodeproj/xcuserdata
+/gameplay/android/obj
 
 
-/gameplay-luagen/Release
-/gameplay-luagen/Debug
-/gameplay-luagen/doxygen_entrydb_680.tmp
-/gameplay-luagen/doxygen_objdb_680.tmp
-/gameplay-luagen/xml
+/gameplay-tests/Debug
+/gameplay-tests/DebugMem
+/gameplay-tests/Release
+/gameplay-tests/Simulator
+/gameplay-tests/Simulator-Coverage
+/gameplay-tests/Simulator-Profile
+/gameplay-tests/Device-Debug
+/gameplay-tests/Device-Coverage
+/gameplay-tests/Device-Profile
+/gameplay-tests/Device-Release
+/gameplay-tests/res/shaders
+/gameplay-tests/res/logo_powered_white.png
+/gameplay-tests/gameplay-tests.xcodeproj/xcuserdata
+/gameplay-tests/android/src
+/gameplay-tests/android/assets
+/gameplay-tests/android/bin
+/gameplay-tests/android/gen
+/gameplay-tests/android/libs
+/gameplay-tests/android/obj
+/gameplay-tests/android/NUL
+/gameplay-tests/android/local.properties
+/gameplay-tests/android/proguard-project.txt
+/gameplay-tests/android/project.properties
 
 
 /gameplay-samples/sample00-mesh/Debug
 /gameplay-samples/sample00-mesh/Debug
 /gameplay-samples/sample00-mesh/DebugMem
 /gameplay-samples/sample00-mesh/DebugMem
@@ -58,9 +86,9 @@ Thumbs.db
 /gameplay-samples/sample00-mesh/Device-Coverage
 /gameplay-samples/sample00-mesh/Device-Coverage
 /gameplay-samples/sample00-mesh/Device-Profile
 /gameplay-samples/sample00-mesh/Device-Profile
 /gameplay-samples/sample00-mesh/Device-Release
 /gameplay-samples/sample00-mesh/Device-Release
-/gameplay-samples/sample00-mesh/res/shaders
+/gameplay-samples/sample00-mesh/res/shaders
 /gameplay-samples/sample00-mesh/res/logo_powered_white.png
 /gameplay-samples/sample00-mesh/res/logo_powered_white.png
-/gameplay-samples/sample00-mesh/sample00-mesh.xcodeproj/xcuserdata
+/gameplay-samples/sample00-mesh/sample00-mesh.xcodeproj/xcuserdata
 /gameplay-samples/sample00-mesh/android/src
 /gameplay-samples/sample00-mesh/android/src
 /gameplay-samples/sample00-mesh/android/assets
 /gameplay-samples/sample00-mesh/android/assets
 /gameplay-samples/sample00-mesh/android/bin
 /gameplay-samples/sample00-mesh/android/bin
@@ -70,7 +98,7 @@ Thumbs.db
 /gameplay-samples/sample00-mesh/android/NUL
 /gameplay-samples/sample00-mesh/android/NUL
 /gameplay-samples/sample00-mesh/android/local.properties
 /gameplay-samples/sample00-mesh/android/local.properties
 /gameplay-samples/sample00-mesh/android/proguard.cfg
 /gameplay-samples/sample00-mesh/android/proguard.cfg
-/gameplay-samples/sample00-mesh/android/project.properties
+/gameplay-samples/sample00-mesh/android/project.properties
 
 
 /gameplay-samples/sample01-longboard/Debug
 /gameplay-samples/sample01-longboard/Debug
 /gameplay-samples/sample01-longboard/DebugMem
 /gameplay-samples/sample01-longboard/DebugMem
@@ -82,9 +110,9 @@ Thumbs.db
 /gameplay-samples/sample01-longboard/Device-Coverage
 /gameplay-samples/sample01-longboard/Device-Coverage
 /gameplay-samples/sample01-longboard/Device-Profile
 /gameplay-samples/sample01-longboard/Device-Profile
 /gameplay-samples/sample01-longboard/Device-Release
 /gameplay-samples/sample01-longboard/Device-Release
-/gameplay-samples/sample01-longboard/res/shaders
+/gameplay-samples/sample01-longboard/res/shaders
 /gameplay-samples/sample01-longboard/res/logo_powered_white.png
 /gameplay-samples/sample01-longboard/res/logo_powered_white.png
-/gameplay-samples/sample01-longboard/sample01-longboard.xcodeproj/xcuserdata
+/gameplay-samples/sample01-longboard/sample01-longboard.xcodeproj/xcuserdata
 /gameplay-samples/sample01-longboard/NUL
 /gameplay-samples/sample01-longboard/NUL
 /gameplay-samples/sample01-longboard/android/NUL
 /gameplay-samples/sample01-longboard/android/NUL
 /gameplay-samples/sample01-longboard/android/src
 /gameplay-samples/sample01-longboard/android/src
@@ -92,10 +120,10 @@ Thumbs.db
 /gameplay-samples/sample01-longboard/android/bin
 /gameplay-samples/sample01-longboard/android/bin
 /gameplay-samples/sample01-longboard/android/gen
 /gameplay-samples/sample01-longboard/android/gen
 /gameplay-samples/sample01-longboard/android/libs
 /gameplay-samples/sample01-longboard/android/libs
-/gameplay-samples/sample01-longboard/android/obj
+/gameplay-samples/sample01-longboard/android/obj
 /gameplay-samples/sample01-longboard/android/proguard.cfg
 /gameplay-samples/sample01-longboard/android/proguard.cfg
 /gameplay-samples/sample01-longboard/android/project.properties
 /gameplay-samples/sample01-longboard/android/project.properties
-/gameplay-samples/sample01-longboard/android/local.properties
+/gameplay-samples/sample01-longboard/android/local.properties
 
 
 /gameplay-samples/sample02-spaceship/Debug
 /gameplay-samples/sample02-spaceship/Debug
 /gameplay-samples/sample02-spaceship/DebugMem
 /gameplay-samples/sample02-spaceship/DebugMem
@@ -107,9 +135,9 @@ Thumbs.db
 /gameplay-samples/sample02-spaceship/Device-Coverage
 /gameplay-samples/sample02-spaceship/Device-Coverage
 /gameplay-samples/sample02-spaceship/Device-Profile
 /gameplay-samples/sample02-spaceship/Device-Profile
 /gameplay-samples/sample02-spaceship/Device-Release
 /gameplay-samples/sample02-spaceship/Device-Release
-/gameplay-samples/sample02-spaceship/res/shaders
+/gameplay-samples/sample02-spaceship/res/shaders
 /gameplay-samples/sample02-spaceship/res/logo_powered_white.png
 /gameplay-samples/sample02-spaceship/res/logo_powered_white.png
-/gameplay-samples/sample02-spaceship/sample02-spaceship.xcodeproj/xcuserdata
+/gameplay-samples/sample02-spaceship/sample02-spaceship.xcodeproj/xcuserdata
 /gameplay-samples/sample02-spaceship/android/NUL
 /gameplay-samples/sample02-spaceship/android/NUL
 /gameplay-samples/sample02-spaceship/android/project.properties
 /gameplay-samples/sample02-spaceship/android/project.properties
 /gameplay-samples/sample02-spaceship/android/assets
 /gameplay-samples/sample02-spaceship/android/assets
@@ -119,7 +147,7 @@ Thumbs.db
 /gameplay-samples/sample02-spaceship/android/obj
 /gameplay-samples/sample02-spaceship/android/obj
 /gameplay-samples/sample02-spaceship/android/src
 /gameplay-samples/sample02-spaceship/android/src
 /gameplay-samples/sample02-spaceship/android/proguard.cfg
 /gameplay-samples/sample02-spaceship/android/proguard.cfg
-/gameplay-samples/sample02-spaceship/android/local.properties
+/gameplay-samples/sample02-spaceship/android/local.properties
 
 
 /gameplay-samples/sample03-character/Debug
 /gameplay-samples/sample03-character/Debug
 /gameplay-samples/sample03-character/DebugMem
 /gameplay-samples/sample03-character/DebugMem
@@ -131,9 +159,10 @@ Thumbs.db
 /gameplay-samples/sample03-character/Device-Coverage
 /gameplay-samples/sample03-character/Device-Coverage
 /gameplay-samples/sample03-character/Device-Profile
 /gameplay-samples/sample03-character/Device-Profile
 /gameplay-samples/sample03-character/Device-Release
 /gameplay-samples/sample03-character/Device-Release
-/gameplay-samples/sample03-character/res/shaders
+/gameplay-samples/sample03-character/game.config
+/gameplay-samples/sample03-character/res/shaders
 /gameplay-samples/sample03-character/res/logo_powered_white.png
 /gameplay-samples/sample03-character/res/logo_powered_white.png
-/gameplay-samples/sample03-character/sample03-character.xcodeproj/xcuserdata
+/gameplay-samples/sample03-character/sample03-character.xcodeproj/xcuserdata
 /gameplay-samples/sample03-character/android/project.properties
 /gameplay-samples/sample03-character/android/project.properties
 /gameplay-samples/sample03-character/android/proguard.cfg
 /gameplay-samples/sample03-character/android/proguard.cfg
 /gameplay-samples/sample03-character/android/local.properties
 /gameplay-samples/sample03-character/android/local.properties
@@ -143,8 +172,8 @@ Thumbs.db
 /gameplay-samples/sample03-character/android/gen
 /gameplay-samples/sample03-character/android/gen
 /gameplay-samples/sample03-character/android/libs
 /gameplay-samples/sample03-character/android/libs
 /gameplay-samples/sample03-character/android/obj
 /gameplay-samples/sample03-character/android/obj
-/gameplay-samples/sample03-character/android/NUL
-/gameplay-samples/sample03-character/res/gamepad.xcf
+/gameplay-samples/sample03-character/android/NUL
+/gameplay-samples/sample03-character/res/gamepad.xcf
 
 
 /gameplay-samples/sample04-particles/Debug
 /gameplay-samples/sample04-particles/Debug
 /gameplay-samples/sample04-particles/DebugMem
 /gameplay-samples/sample04-particles/DebugMem
@@ -156,9 +185,9 @@ Thumbs.db
 /gameplay-samples/sample04-particles/Device-Coverage
 /gameplay-samples/sample04-particles/Device-Coverage
 /gameplay-samples/sample04-particles/Device-Profile
 /gameplay-samples/sample04-particles/Device-Profile
 /gameplay-samples/sample04-particles/Device-Release
 /gameplay-samples/sample04-particles/Device-Release
-/gameplay-samples/sample04-particles/res/shaders
+/gameplay-samples/sample04-particles/res/shaders
 /gameplay-samples/sample04-particles/res/logo_powered_white.png
 /gameplay-samples/sample04-particles/res/logo_powered_white.png
-/gameplay-samples/sample04-particles/sample04-particles.xcodeproj/xcuserdata
+/gameplay-samples/sample04-particles/sample04-particles.xcodeproj/xcuserdata
 /gameplay-samples/sample04-particles/Device-Debug
 /gameplay-samples/sample04-particles/Device-Debug
 /gameplay-samples/sample04-particles/Debug
 /gameplay-samples/sample04-particles/Debug
 /gameplay-samples/sample04-particles/DebugMem
 /gameplay-samples/sample04-particles/DebugMem
@@ -170,8 +199,8 @@ Thumbs.db
 /gameplay-samples/sample04-particles/android/obj
 /gameplay-samples/sample04-particles/android/obj
 /gameplay-samples/sample04-particles/android/proguard.cfg
 /gameplay-samples/sample04-particles/android/proguard.cfg
 /gameplay-samples/sample04-particles/android/local.properties
 /gameplay-samples/sample04-particles/android/local.properties
-/gameplay-samples/sample04-particles/android/project.properties
-
+/gameplay-samples/sample04-particles/android/project.properties
+
 /gameplay-samples/sample05-lua/Debug
 /gameplay-samples/sample05-lua/Debug
 /gameplay-samples/sample05-lua/DebugMem
 /gameplay-samples/sample05-lua/DebugMem
 /gameplay-samples/sample05-lua/Release
 /gameplay-samples/sample05-lua/Release
@@ -182,9 +211,9 @@ Thumbs.db
 /gameplay-samples/sample05-lua/Device-Coverage
 /gameplay-samples/sample05-lua/Device-Coverage
 /gameplay-samples/sample05-lua/Device-Profile
 /gameplay-samples/sample05-lua/Device-Profile
 /gameplay-samples/sample05-lua/Device-Release
 /gameplay-samples/sample05-lua/Device-Release
-/gameplay-samples/sample05-lua/res/shaders
+/gameplay-samples/sample05-lua/res/shaders
 /gameplay-samples/sample05-lua/res/logo_powered_white.png
 /gameplay-samples/sample05-lua/res/logo_powered_white.png
-/gameplay-samples/sample05-lua/sample05-lua.xcodeproj/xcuserdata
+/gameplay-samples/sample05-lua/sample05-lua.xcodeproj/xcuserdata
 /gameplay-samples/sample05-lua/android/src
 /gameplay-samples/sample05-lua/android/src
 /gameplay-samples/sample05-lua/android/assets
 /gameplay-samples/sample05-lua/android/assets
 /gameplay-samples/sample05-lua/android/bin
 /gameplay-samples/sample05-lua/android/bin
@@ -194,7 +223,36 @@ Thumbs.db
 /gameplay-samples/sample05-lua/android/NUL
 /gameplay-samples/sample05-lua/android/NUL
 /gameplay-samples/sample05-lua/android/local.properties
 /gameplay-samples/sample05-lua/android/local.properties
 /gameplay-samples/sample05-lua/android/proguard.cfg
 /gameplay-samples/sample05-lua/android/proguard.cfg
-/gameplay-samples/sample05-lua/android/project.properties
-
-/gameplay-internal
-/gameplay\android/proguard-project.txt
+/gameplay-samples/sample05-lua/android/project.properties
+
+/gameplay-samples/sample06-racer/Debug
+/gameplay-samples/sample06-racer/DebugMem
+/gameplay-samples/sample06-racer/Release
+/gameplay-samples/sample06-racer/Simulator
+/gameplay-samples/sample06-racer/Simulator-Coverage
+/gameplay-samples/sample06-racer/Simulator-Profile
+/gameplay-samples/sample06-racer/Device-Debug
+/gameplay-samples/sample06-racer/Device-Debug-IMG
+/gameplay-samples/sample06-racer/Device-Coverage
+/gameplay-samples/sample06-racer/Device-Profile
+/gameplay-samples/sample06-racer/Device-Release
+/gameplay-samples/sample06-racer/game.config
+/gameplay-samples/sample06-racer/res/shaders
+/gameplay-samples/sample06-racer/res/logo_powered_white.png
+/gameplay-samples/sample06-racer/sample06-racer.xcodeproj/xcuserdata
+/gameplay-samples/sample06-racer/android/project.properties
+/gameplay-samples/sample06-racer/android/proguard.cfg
+/gameplay-samples/sample06-racer/android/local.properties
+/gameplay-samples/sample06-racer/android/src
+/gameplay-samples/sample06-racer/android/assets
+/gameplay-samples/sample06-racer/android/bin
+/gameplay-samples/sample06-racer/android/gen
+/gameplay-samples/sample06-racer/android/libs
+/gameplay-samples/sample06-racer/android/obj
+/gameplay-samples/sample06-racer/android/NUL
+/gameplay-samples/sample06-racer/android/local.properties
+/gameplay-samples/sample06-racer/android/proguard.cfg
+/gameplay-samples/sample06-racer/android/project.properties
+
+
+

+ 1 - 0
.kateconfig

@@ -0,0 +1 @@
+kate: space-indent on; tab-width 4; indent-width 4; replace-tabs on; show-tabs: on; replace-tabs-save: off; replace-trailing-space-save: off;

+ 29 - 0
CHANGES.md

@@ -1,3 +1,32 @@
+## v1.5.0
+
+- Linux support. (tested on Ubuntu 12)
+- CMake support for makefile generation for Linux.
+- CodeBlocks 10 IDE support for Linux.
+- Gamepad controllers support for desktops.
+- Touch gesture support for tap, swipe and pinch.
+- Vehicle phyics support via new PhysicsVehicle and PhysicsVehicleWheel classes.
+- Adds new racer sample (sample06-racer).
+- Adds gameplay-tests project as a test app for various basic engine features with some initial tests.
+- Adds support for Scene files for wildcard identifiers.
+- Adds Visual Studio Plug-in support for BlackBerry PlayBook and BlackBerry 10.
+- Adds configurable multi-sampling anti-aliasing support. 
+- Adds updates to latest FBX SDK 2013.3.
+- Adds file formats documenation for game.config .scene, .material, .animation, .physics, .particle
+- Adds Game/Platform::canExit for testing device capabilities to quit. (only ios)
+- Web community forums at http://www.gameplay3d.org/forums.
+- Changed keyTimes from unsigned long[]  to unsigned int[]. (breaks compat. in AnimationTarget and Animation::Channel)
+- Fixed inconsistencies from Bundle::getObjectID() to Bundle::getObjectId() (breaks compat. in Bundle)
+- Fixes the texture coordinates of Mesh::createQuad(float x, float y, float width, float height).
+- Fixes line-wise distortion when loading RGB png's into texture that are non-power of two.
+- Fixes inconsitencies in createXXXX methods.  (breaks compat. in Scene)
+- Fixes Rectanngle::contains.
+- Fixes Lua print logging.
+- Fixes Lua errors to be treated as runtime warnings.
+- Fixes setVertexData to pointers instead of constant data.
+- Fixed AudioSource so that it doesn't loop by default.
+- Fixes minor UI scrolling issues.
+
 ## v1.4.0
 ## v1.4.0
 
 
 - Lua script bindings for all gameplay interfaces.
 - Lua script bindings for all gameplay interfaces.

+ 26 - 0
CMakeLists.txt

@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.6)
+
+project(GamePlay)
+
+set(GAMEPLAY_VERSION 1.5.0)
+set(CMAKE_C_COMPILER_INIT g++)
+
+# debug
+message( "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}" )
+if( "${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" )
+    add_definitions(-D_DEBUG)
+endif()
+
+# gameplay library
+add_subdirectory(gameplay)
+
+# gameplay samples
+add_subdirectory(gameplay-samples)
+
+# gameplay samples
+add_subdirectory(gameplay-tests)
+
+# gameplay encoder (See gameplay/bin)
+#add_subdirectory(gameplay-encoder)
+
+

+ 6 - 6
README.md

@@ -1,20 +1,20 @@
-## gameplay v1.4.0
+## gameplay v1.5.0
 An open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
 An open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
 
 
 ## Supported Mobile Platforms
 ## Supported Mobile Platforms
 - BlackBerry 10 and PlayBook 2.0 (using BlackBerry Native SDK)
 - BlackBerry 10 and PlayBook 2.0 (using BlackBerry Native SDK)
-- Google Android 2.3+ (using Google Android NDK, SDK API level 9+)
 - Apple iOS 5.1 (using Apple XCode 4.3.2)
 - Apple iOS 5.1 (using Apple XCode 4.3.2)
+- Google Android 2.3+ (using Google Android NDK, SDK API level 9+)
 
 
 ## Supported Desktop Platforms
 ## Supported Desktop Platforms
 - Microsoft Windows 7 (using Microsoft Visual Studio 2010)
 - Microsoft Windows 7 (using Microsoft Visual Studio 2010)
 - Apple MacOS X (using Apple XCode 4.3.2)
 - Apple MacOS X (using Apple XCode 4.3.2)
+- Linux (using CMake or CodeBlocks 10)
 
 
 ## Roadmap for 'next' branch
 ## Roadmap for 'next' branch
-- Linux support
-- Vehicle physics
-- Shadows
-- AI pathfinding
+- AI Pathfinding
+- Terrain and Water
+- Asset Pipeline improvements
 
 
 ## Licence
 ## Licence
 The project is open sourced under the Apache 2.0 license.
 The project is open sourced under the Apache 2.0 license.

+ 8 - 0
cmake/README.md

@@ -0,0 +1,8 @@
+## Building with CMake
+Run the following command lines from this directory:
+* cmake ..
+* make
+
+
+
+

+ 145 - 0
gameplay-encoder/CMakeLists.txt

@@ -0,0 +1,145 @@
+
+include_directories( 
+    ${CMAKE_SOURCE_DIR}/external-deps/zlib/include
+    ${CMAKE_SOURCE_DIR}/external-deps/libpng/include
+    ${CMAKE_SOURCE_DIR}/external-deps/freetype2/include
+    ${CMAKE_SOURCE_DIR}/external-deps/collada-dom/include
+    ${CMAKE_SOURCE_DIR}/external-deps/collada-dom/include/1.4
+    /usr/include/libxml2
+    /usr/include
+)
+
+add_definitions(-D__linux__ -DNO_BOOST -DNO_ZAE)
+
+link_directories(
+    ${CMAKE_SOURCE_DIR}/external-deps/zlib/lib/linux
+    ${CMAKE_SOURCE_DIR}/external-deps/libpng/lib/linux
+    ${CMAKE_SOURCE_DIR}/external-deps/freetype2/lib/linux
+    ${CMAKE_SOURCE_DIR}/external-deps/collada-dom/lib/linux
+    /usr/lib
+)
+
+set(APP_LIBRARIES
+    collada14dom
+    pcre
+    pcrecpp
+    xml2
+    png
+    z   
+    freetype
+    pthread
+) 
+
+add_definitions(-lstdc++ -lcollada14dom -lpcre -lpcrecpp -lxml2 -lpng -lz -lfreetype -lpthread)
+
+set( APP_NAME gameplay-encoder )
+
+set(APP_SRC
+	src/AnimationChannel.cpp
+	src/AnimationChannel.h
+	src/Animation.cpp
+	src/Animation.h
+	src/Animations.cpp
+	src/Animations.h
+	src/Base.cpp
+	src/Base.h
+	src/BoundingVolume.cpp
+	src/BoundingVolume.h
+	src/Camera.cpp
+	src/Camera.h
+	src/Curve.cpp
+	src/Curve.h
+	src/Curve.inl
+	src/DAEChannelTarget.cpp
+	src/DAEChannelTarget.h
+	src/DAEOptimizer.cpp
+	src/DAEOptimizer.h
+	src/DAESceneEncoder.cpp
+	src/DAESceneEncoder.h
+	src/DAEUtil.cpp
+	src/DAEUtil.h
+	src/Effect.cpp
+	src/Effect.h
+	src/EncoderArguments.cpp
+	src/EncoderArguments.h
+	src/FBXSceneEncoder.cpp
+	src/FBXSceneEncoder.h
+	src/FileIO.cpp
+	src/FileIO.h
+	src/Font.cpp
+	src/Font.h
+	src/Glyph.cpp
+	src/Glyph.h
+	src/GPBDecoder.cpp
+	src/GPBDecoder.h
+	src/GPBFile.cpp
+	src/GPBFile.h
+	src/Heightmap.cpp
+	src/Heightmap.h
+	src/Light.cpp
+	src/Light.h
+	src/main.cpp
+	src/Material.cpp
+	src/Material.h
+	src/MaterialParameter.cpp
+	src/MaterialParameter.h
+	src/Matrix.cpp
+	src/Matrix.h
+	src/Mesh.cpp
+	src/Mesh.h
+	src/MeshPart.cpp
+	src/MeshPart.h
+	src/MeshSkin.cpp
+	src/MeshSkin.h
+	src/MeshSubSet.cpp
+	src/MeshSubSet.h
+	src/Model.cpp
+	src/Model.h
+	src/Node.cpp
+	src/Node.h
+	src/Object.cpp
+	src/Object.h
+	src/Quaternion.cpp
+	src/Quaternion.h
+	src/Quaternion.inl
+	src/Reference.cpp
+	src/Reference.h
+	src/ReferenceTable.cpp
+	src/ReferenceTable.h
+	src/Scene.cpp
+	src/Scene.h
+	src/StringUtil.cpp
+	src/StringUtil.h
+	src/Thread.h
+	src/Transform.cpp
+	src/Transform.h
+	src/TTFFontEncoder.cpp
+	src/TTFFontEncoder.h
+	src/Vector2.cpp
+	src/Vector2.h
+	src/Vector2.inl
+	src/Vector3.cpp
+	src/Vector3.h
+	src/Vector3.inl
+	src/Vector4.cpp
+	src/Vector4.h
+	src/Vector4.inl
+	src/Vertex.cpp
+	src/VertexElement.cpp
+	src/VertexElement.h
+	src/Vertex.h
+)
+
+add_executable(${APP_NAME}
+    ${APP_SRC}
+)
+
+target_link_libraries(${APP_NAME} ${APP_LIBRARIES})
+
+set_target_properties(${APP_NAME} PROPERTIES
+    OUTPUT_NAME "${APP_NAME}"
+    CLEAN_DIRECT_OUTPUT 1
+)
+
+source_group(src FILES ${APP_SRC})
+

+ 37 - 23
gameplay-encoder/README.md

@@ -1,41 +1,42 @@
 ## gameplay-encoder
 ## gameplay-encoder
 Command-line tool for encoding games assets like true-type fonts and 3D scene files
 Command-line tool for encoding games assets like true-type fonts and 3D scene files
 into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
 into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
-The 'bin' folder contains pre-built versions of the gameplay-encoder executables for both 
-Windows 7 and MacOS X with support built-in support for:
+The 'bin' folder contains pre-built versions of the gameplay-encoder executables for 
+Windows 7, MacOS X and Linux (tested on Ubuntu 12) with support built-in support for:
 
 
 ## TrueType Font
 ## TrueType Font
-TrueType Fonts represent a standard in defining outline fonts and has become the 
-most common format for fonts. The gameplay-encoder reads these fonts and binary encodes 
-them into a texture mapped base representation using a texture atlas and 8-bit alpha
+TrueType Fonts represent a standard in defining outline fonts and has become the 
+most common format for fonts. The gameplay-encoder reads these fonts and binary encodes 
+them into a texture mapped base representation using a texture atlas and 8-bit alpha
 representation.
 representation.
 
 
-## COLLADA Scene
-COLLADA is a royalty-free XML schema that enables digital asset exchange 
+## COLLADA Scene
+COLLADA is a royalty-free XML schema that enables digital asset exchange 
 within the interactive 3D industry. Most major 3D DCC tools support export to COLLADA 1.4.
 within the interactive 3D industry. Most major 3D DCC tools support export to COLLADA 1.4.
 
 
 ## FBX Scene
 ## FBX Scene
-Autodesk® FBX® asset exchange technology facilitates higher-fidelity data exchange 
-between several Autodesk content creation packages
-Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
-For more information goto "http://www.autodesk.com/fbx".
-
-## Building gameplay-encoder
-The gameplay-encoder comes pre-built for both Windows 7 and MacOS X in the 'bin' folder.
-However, to build the gameplay-ecoder yourself just open either the 
-Visual Studio 2010 project "gameplay-encoder.vccproj" on Windows 7 or
+Autodesk® FBX® asset exchange technology facilitates higher-fidelity data exchange 
+between several Autodesk content creation packages
+Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
+For more information goto "http://www.autodesk.com/fbx".
+
+## Building gameplay-encoder
+The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux x64 in the 'bin' folder.
+However, to build the gameplay-ecoder yourself just open either the 
+Visual Studio 2010 project "gameplay-encoder.vccproj" on Windows 7 or
 XCode project "gameplay-encoder.xcodeproj" on MacOSX.
 XCode project "gameplay-encoder.xcodeproj" on MacOSX.
+Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake .. from build then make.
 
 
 ### Building with FBX Support on Windows 7 using Visual Studio 2010
 ### Building with FBX Support on Windows 7 using Visual Studio 2010
 - Download and install the FBX SDK for Window VS2010. (http://www.autodesk.com/fbx)
 - Download and install the FBX SDK for Window VS2010. (http://www.autodesk.com/fbx)
 - Edit the project properties of "gameplay-encoder" for Debug
 - Edit the project properties of "gameplay-encoder" for Debug
 - Add Preprocessor Definition "USE_FBX" (C++/Preprocessor)
 - Add Preprocessor Definition "USE_FBX" (C++/Preprocessor)
 - Add the FBX SDK include directory to Additional Include Directories (C++/General)
 - Add the FBX SDK include directory to Additional Include Directories (C++/General)
-  * Example: C:/Program Files/Autodesk/FBX/FbxSdk/2013.2/include
+  * Example: C:/Program Files/Autodesk/FBX/FBX SDK/2013.3/include
 - Add the FBX lib directory to the Additional Library Directories (Linker/General)
 - Add the FBX lib directory to the Additional Library Directories (Linker/General)
-  * Example: C:/Program Files/Autodesk/FBX/FbxSdk/2013.2/lib/vs2010/x86
-- Add "fbxsdk-2013.2-mdd.lib"(Release) to the Additional Dependencies (Linker/Input)
-  * Example: fbxsdk-2013.2-mdd.lib
+  * Example: C:/Program Files/Autodesk/FBX/FBX SDK/2013.3/lib/vs2010/x86
+- Add "fbxsdk-2013.3-mdd.lib"(Release) to the Additional Dependencies (Linker/Input)
+  * Example: fbxsdk-2013.3-mdd.lib
 - Build gameplay-encoder
 - Build gameplay-encoder
 
 
 ### Building with FBX Support on Mac OS X using XCode 4.3.2+
 ### Building with FBX Support on Mac OS X using XCode 4.3.2+
@@ -43,12 +44,25 @@ XCode project "gameplay-encoder.xcodeproj" on MacOSX.
 - Edit the project properties of target "gameplay-encoder".
 - Edit the project properties of target "gameplay-encoder".
 - Add Preprocessor Macro "USE_FBX" to both Debug/Release sections. (Build Settings)
 - Add Preprocessor Macro "USE_FBX" to both Debug/Release sections. (Build Settings)
 - Add the FBX include directory to Header Search Paths: (Build Settings)
 - Add the FBX include directory to Header Search Paths: (Build Settings)
-  * Example: "/Applications/Autodesk/FBX SDK/2013.2/include" (Use quotes due to additional space in path)
+  * Example: "/Applications/Autodesk/FBX SDK/2013.3/include" (Use quotes due to additional space in path)
 - Add the FBX library and dependency Library/Frameworks: (Build Phases -> Link Binary with Libraries)
 - Add the FBX library and dependency Library/Frameworks: (Build Phases -> Link Binary with Libraries)
-  * Example: /Applications/Autodesk/FBX SDK/2013.2/lib/gcc4/ub/libfbxsdk-2013.2-static.a  (Add Other)
-  * Example: libiconv.dylib, Cocoa.framework, SystemConfiguration.framework
+  * Example: /Applications/Autodesk/FBX SDK/2013.3/lib/gcc4/ub/libfbxsdk-2013.3-static.a  (Add Other)
 - Build gameplay-encoder
 - Build gameplay-encoder
 
 
+### Building with FBX Support on Linux
+- Download and install the FBX SDK for Mac OS X (http://www.autodesk.com/fbx)
+- Edit the gameplay-encoder/CMakeLists.txt adding the following:
+- Add the FBX include directory to Header Search Paths: (Build Settings)
+  * Example: /usr/include/fbxsdk
+- Add Preprocessor Macro to the add"-DUSE_FBX" to the end of the add_definitions(...) section of the CMakeLists.txt
+- Add the FBX library path to the link_directories(...) section of the CMakeLists.txt
+  * Example: /usr/lib/gcc4
+- Add the FBX library to the set(APP_LIBRARIES {...} )
+  * Example: fbxsdk-2013.3-static
+- Add the FBX library to the library to the add_definitions(-l...) section of the CMakeLists.txt
+  * Example -lfbxsdk-2013.3-static
+- Build gameplay-encoder via main cmake .. in build then make.
+
 ## Bundle File Format
 ## Bundle File Format
 The gameplay bundle file format is well defined in the gameplay-encoder/gameplay-bundle.txt file.
 The gameplay bundle file format is well defined in the gameplay-encoder/gameplay-bundle.txt file.
 
 

+ 1 - 1
gameplay-encoder/gameplay-bundle.txt

@@ -153,7 +153,7 @@ Reference
 5->AnimationChannel
 5->AnimationChannel
                 targetId                string
                 targetId                string
                 targetAttribute         uint
                 targetAttribute         uint
-                keyTimes                unsigned long[]  (milliseconds)
+                keyTimes                uint[]  (milliseconds)
                 values                  float[]
                 values                  float[]
                 tangents_in             float[]
                 tangents_in             float[]
                 tangents_out            float[]
                 tangents_out            float[]

+ 7 - 5
gameplay-encoder/gameplay-encoder.vcxproj

@@ -30,6 +30,7 @@
     <ClCompile Include="src\Glyph.cpp" />
     <ClCompile Include="src\Glyph.cpp" />
     <ClCompile Include="src\GPBDecoder.cpp" />
     <ClCompile Include="src\GPBDecoder.cpp" />
     <ClCompile Include="src\Animations.cpp" />
     <ClCompile Include="src\Animations.cpp" />
+    <ClCompile Include="src\Heightmap.cpp" />
     <ClCompile Include="src\Light.cpp" />
     <ClCompile Include="src\Light.cpp" />
     <ClCompile Include="src\main.cpp" />
     <ClCompile Include="src\main.cpp" />
     <ClCompile Include="src\Material.cpp" />
     <ClCompile Include="src\Material.cpp" />
@@ -74,6 +75,7 @@
     <ClInclude Include="src\Glyph.h" />
     <ClInclude Include="src\Glyph.h" />
     <ClInclude Include="src\GPBDecoder.h" />
     <ClInclude Include="src\GPBDecoder.h" />
     <ClInclude Include="src\Animations.h" />
     <ClInclude Include="src\Animations.h" />
+    <ClInclude Include="src\Heightmap.h" />
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\Material.h" />
     <ClInclude Include="src\Material.h" />
     <ClInclude Include="src\MaterialParameter.h" />
     <ClInclude Include="src\MaterialParameter.h" />
@@ -89,6 +91,7 @@
     <ClInclude Include="src\ReferenceTable.h" />
     <ClInclude Include="src\ReferenceTable.h" />
     <ClInclude Include="src\Scene.h" />
     <ClInclude Include="src\Scene.h" />
     <ClInclude Include="src\StringUtil.h" />
     <ClInclude Include="src\StringUtil.h" />
+    <ClInclude Include="src\Thread.h" />
     <ClInclude Include="src\Transform.h" />
     <ClInclude Include="src\Transform.h" />
     <ClInclude Include="src\TTFFontEncoder.h" />
     <ClInclude Include="src\TTFFontEncoder.h" />
     <ClInclude Include="src\Vector2.h" />
     <ClInclude Include="src\Vector2.h" />
@@ -156,12 +159,12 @@
     <Link>
     <Link>
       <SubSystem>Console</SubSystem>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32;../external-deps/libpng/lib/win32;../external-deps/zlib/lib/win32</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows;../external-deps/collada-dom/lib/windows;../external-deps/libpng/lib/windows;../external-deps/zlib/lib/windows</AdditionalLibraryDirectories>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
       <IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
     </Link>
     </Link>
     <PostBuildEvent>
     <PostBuildEvent>
-      <Command>copy /Y "$(ProjectDir)..\bin\win32\*.dll" "$(TargetDir)"</Command>
+      <Command>copy /Y "$(ProjectDir)..\bin\windows\*.dll" "$(TargetDir)"</Command>
     </PostBuildEvent>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -181,13 +184,12 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32;../external-deps/libpng/lib/win32;../external-deps/zlib/lib/win32</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows;../external-deps/collada-dom/lib/windows;../external-deps/libpng/lib/windows;../external-deps/zlib/lib/windows</AdditionalLibraryDirectories>
       <IgnoreSpecificDefaultLibraries>
       <IgnoreSpecificDefaultLibraries>
       </IgnoreSpecificDefaultLibraries>
       </IgnoreSpecificDefaultLibraries>
     </Link>
     </Link>
     <PostBuildEvent>
     <PostBuildEvent>
-      <Command>copy /Y "$(ProjectDir)..\bin\win32\*.dll" "$(TargetDir)"
-</Command>
+      <Command>copy /Y "$(ProjectDir)..\bin\windows\*.dll" "$(TargetDir)"</Command>
     </PostBuildEvent>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 9 - 0
gameplay-encoder/gameplay-encoder.vcxproj.filters

@@ -127,6 +127,9 @@
     <ClCompile Include="src\Curve.cpp">
     <ClCompile Include="src\Curve.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\Heightmap.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\VertexElement.h">
     <ClInclude Include="src\VertexElement.h">
@@ -252,6 +255,12 @@
     <ClInclude Include="src\Curve.h">
     <ClInclude Include="src\Curve.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\Thread.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Heightmap.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="src\Vector2.inl">
     <None Include="src\Vector2.inl">

+ 2 - 2
gameplay-encoder/gameplay-encoder.vcxproj.user

@@ -4,10 +4,10 @@
     <LocalDebuggerCommandArguments>
     <LocalDebuggerCommandArguments>
     </LocalDebuggerCommandArguments>
     </LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/win32;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/windows;</LocalDebuggerEnvironment>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/win32;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/windows;</LocalDebuggerEnvironment>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   </PropertyGroup>
 </Project>
 </Project>

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

@@ -7,6 +7,9 @@
 	objects = {
 	objects = {
 
 
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
+		4228A3FF1620A5A300955433 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4228A3FE1620A5A300955433 /* Cocoa.framework */; };
+		4228A4011620A5EC00955433 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4228A4001620A5EC00955433 /* SystemConfiguration.framework */; };
+		4228A4031620A63F00955433 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4228A4021620A63F00955433 /* libiconv.dylib */; };
 		42475D7C14720ECE00610A6A /* libdom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42475D7B14720ECE00610A6A /* libdom.a */; };
 		42475D7C14720ECE00610A6A /* libdom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42475D7B14720ECE00610A6A /* libdom.a */; };
 		4251B12C152D044B002F6199 /* Curve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4251B128152D044B002F6199 /* Curve.cpp */; };
 		4251B12C152D044B002F6199 /* Curve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4251B128152D044B002F6199 /* Curve.cpp */; };
 		42783423148D6F7500A6E27F /* FBXSceneEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4278341E148D6F7500A6E27F /* FBXSceneEncoder.cpp */; };
 		42783423148D6F7500A6E27F /* FBXSceneEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4278341E148D6F7500A6E27F /* FBXSceneEncoder.cpp */; };
@@ -58,6 +61,7 @@
 		42D277591472EFA700D867A4 /* libpcre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277571472EFA700D867A4 /* libpcre.a */; };
 		42D277591472EFA700D867A4 /* libpcre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277571472EFA700D867A4 /* libpcre.a */; };
 		42D2775A1472EFA700D867A4 /* libpcrecpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277581472EFA700D867A4 /* libpcrecpp.a */; };
 		42D2775A1472EFA700D867A4 /* libpcrecpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277581472EFA700D867A4 /* libpcrecpp.a */; };
 		5BCD0643152CFC3C0071FAB5 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BCD0642152CFC3C0071FAB5 /* libpng.a */; };
 		5BCD0643152CFC3C0071FAB5 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BCD0642152CFC3C0071FAB5 /* libpng.a */; };
+		F18DCD0615D554B800DB35DB /* Heightmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F18DCD0315D554B800DB35DB /* Heightmap.cpp */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXCopyFilesBuildPhase section */
 /* Begin PBXCopyFilesBuildPhase section */
@@ -73,6 +77,9 @@
 /* End PBXCopyFilesBuildPhase section */
 /* End PBXCopyFilesBuildPhase section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
+		4228A3FE1620A5A300955433 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		4228A4001620A5EC00955433 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+		4228A4021620A63F00955433 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = ../../../../../usr/lib/libiconv.dylib; sourceTree = "<group>"; };
 		42475CE6147208A000610A6A /* gameplay-encoder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gameplay-encoder"; sourceTree = BUILT_PRODUCTS_DIR; };
 		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>"; };
 		42475D7B14720ECE00610A6A /* libdom.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdom.a; path = "../external-deps/collada-dom/lib/macosx/libdom.a"; sourceTree = "<group>"; };
 		4251B128152D044B002F6199 /* Curve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Curve.cpp; path = src/Curve.cpp; sourceTree = SOURCE_ROOT; };
 		4251B128152D044B002F6199 /* Curve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Curve.cpp; path = src/Curve.cpp; sourceTree = SOURCE_ROOT; };
@@ -172,6 +179,9 @@
 		42D277571472EFA700D867A4 /* libpcre.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcre.a; path = "../external-deps/pcre/lib/macosx/libpcre.a"; sourceTree = "<group>"; };
 		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>"; };
 		42D277581472EFA700D867A4 /* libpcrecpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcrecpp.a; path = "../external-deps/pcre/lib/macosx/libpcrecpp.a"; sourceTree = "<group>"; };
 		5BCD0642152CFC3C0071FAB5 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
 		5BCD0642152CFC3C0071FAB5 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+		F18DCD0315D554B800DB35DB /* Heightmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Heightmap.cpp; path = src/Heightmap.cpp; sourceTree = SOURCE_ROOT; };
+		F18DCD0415D554B800DB35DB /* Heightmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Heightmap.h; path = src/Heightmap.h; sourceTree = SOURCE_ROOT; };
+		F18DCD0515D554B800DB35DB /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Thread.h; path = src/Thread.h; sourceTree = SOURCE_ROOT; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -187,17 +197,30 @@
 				42C8EE391472DAA300E43619 /* libz.dylib in Frameworks */,
 				42C8EE391472DAA300E43619 /* libz.dylib in Frameworks */,
 				42C8EE371472D7E700E43619 /* libxml2.dylib in Frameworks */,
 				42C8EE371472D7E700E43619 /* libxml2.dylib in Frameworks */,
 				5BCD0643152CFC3C0071FAB5 /* libpng.a in Frameworks */,
 				5BCD0643152CFC3C0071FAB5 /* libpng.a in Frameworks */,
+				4228A3FF1620A5A300955433 /* Cocoa.framework in Frameworks */,
+				4228A4011620A5EC00955433 /* SystemConfiguration.framework in Frameworks */,
+				4228A4031620A63F00955433 /* libiconv.dylib in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
 /* End PBXFrameworksBuildPhase section */
 /* End PBXFrameworksBuildPhase section */
 
 
 /* Begin PBXGroup section */
 /* Begin PBXGroup section */
+		4228A3FD1620A58000955433 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				4228A4001620A5EC00955433 /* SystemConfiguration.framework */,
+				4228A3FE1620A5A300955433 /* Cocoa.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
 		42475CDB147208A000610A6A = {
 		42475CDB147208A000610A6A = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				42475CE9147208A000610A6A /* src */,
 				42475CE9147208A000610A6A /* src */,
 				427D4F44147DC9080076760E /* Libraries */,
 				427D4F44147DC9080076760E /* Libraries */,
+				4228A3FD1620A58000955433 /* Frameworks */,
 				42475CE7147208A000610A6A /* Products */,
 				42475CE7147208A000610A6A /* Products */,
 			);
 			);
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -213,6 +236,9 @@
 		42475CE9147208A000610A6A /* src */ = {
 		42475CE9147208A000610A6A /* src */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				F18DCD0315D554B800DB35DB /* Heightmap.cpp */,
+				F18DCD0415D554B800DB35DB /* Heightmap.h */,
+				F18DCD0515D554B800DB35DB /* Thread.h */,
 				42C8EDB714724CD700E43619 /* Animation.cpp */,
 				42C8EDB714724CD700E43619 /* Animation.cpp */,
 				42C8EDB814724CD700E43619 /* Animation.h */,
 				42C8EDB814724CD700E43619 /* Animation.h */,
 				42C8EDB914724CD700E43619 /* AnimationChannel.cpp */,
 				42C8EDB914724CD700E43619 /* AnimationChannel.cpp */,
@@ -319,6 +345,7 @@
 				42C8EE361472D7E700E43619 /* libxml2.dylib */,
 				42C8EE361472D7E700E43619 /* libxml2.dylib */,
 				42C8EE341472B60100E43619 /* libfreetype.a */,
 				42C8EE341472B60100E43619 /* libfreetype.a */,
 				42475D7B14720ECE00610A6A /* libdom.a */,
 				42475D7B14720ECE00610A6A /* libdom.a */,
+				4228A4021620A63F00955433 /* libiconv.dylib */,
 			);
 			);
 			name = Libraries;
 			name = Libraries;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -416,6 +443,7 @@
 				4283905914896E6C00E2B2F5 /* BoundingVolume.cpp in Sources */,
 				4283905914896E6C00E2B2F5 /* BoundingVolume.cpp in Sources */,
 				42783423148D6F7500A6E27F /* FBXSceneEncoder.cpp in Sources */,
 				42783423148D6F7500A6E27F /* FBXSceneEncoder.cpp in Sources */,
 				4251B12C152D044B002F6199 /* Curve.cpp in Sources */,
 				4251B12C152D044B002F6199 /* Curve.cpp in Sources */,
+				F18DCD0615D554B800DB35DB /* Heightmap.cpp in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};

+ 12 - 63
gameplay-encoder/src/AnimationChannel.cpp

@@ -68,27 +68,27 @@ unsigned int AnimationChannel::getTargetAttribute() const
     return _targetAttrib;
     return _targetAttrib;
 }
 }
 
 
-const std::vector<float>& AnimationChannel::getKeyValues() const
+std::vector<float>& AnimationChannel::getKeyValues()
 {
 {
     return _keyValues;
     return _keyValues;
 }
 }
 
 
-const std::vector<float>& AnimationChannel::getKeyTimes() const
+std::vector<float>& AnimationChannel::getKeyTimes()
 {
 {
     return _keytimes;
     return _keytimes;
 }
 }
 
 
-const std::vector<float>& AnimationChannel::getTangentsIn() const
+std::vector<float>& AnimationChannel::getTangentsIn()
 {
 {
     return _tangentsIn;
     return _tangentsIn;
 }
 }
 
 
-const std::vector<float>& AnimationChannel::getTangentsOut() const
+std::vector<float>& AnimationChannel::getTangentsOut()
 {
 {
     return _tangentsOut;
     return _tangentsOut;
 }
 }
 
 
-const std::vector<unsigned int>& AnimationChannel::getInterpolationTypes() const
+std::vector<unsigned int>& AnimationChannel::getInterpolationTypes()
 {
 {
     return _interpolations;
     return _interpolations;
 }
 }
@@ -130,6 +130,10 @@ void AnimationChannel::setInterpolations(const std::vector<unsigned int>& values
 
 
 void AnimationChannel::removeDuplicates()
 void AnimationChannel::removeDuplicates()
 {
 {
+    LOG(3, "      Removing duplicates for channel with target attribute: %u.\n", _targetAttrib);
+
+    int startCount = _keytimes.size();
+
     size_t propSize = Transform::getPropertySize(_targetAttrib);
     size_t propSize = Transform::getPropertySize(_targetAttrib);
 
 
     if (propSize > 1 && !_interpolations.empty() && _interpolations[0] == LINEAR)
     if (propSize > 1 && !_interpolations.empty() && _interpolations[0] == LINEAR)
@@ -167,64 +171,8 @@ void AnimationChannel::removeDuplicates()
             deleteRange(prevIndex+1, i, propSize);
             deleteRange(prevIndex+1, i, propSize);
         }
         }
     }
     }
-}
-
-void AnimationChannel::convertToQuaternion()
-{
-    if (_targetAttrib == Transform::ANIMATE_ROTATE_X ||
-        _targetAttrib == Transform::ANIMATE_ROTATE_Y ||
-        _targetAttrib == Transform::ANIMATE_ROTATE_Z)
-    {
-        std::vector<float> newKeyValues;
-        newKeyValues.resize(_keyValues.size() * 4);
-        const size_t count = _keyValues.size();
-
-        float x = _targetAttrib == Transform::ANIMATE_ROTATE_X ? 1.0f : 0.0f;
-        float y = _targetAttrib == Transform::ANIMATE_ROTATE_Y ? 1.0f : 0.0f;
-        float z = _targetAttrib == Transform::ANIMATE_ROTATE_Z ? 1.0f : 0.0f;
-        for (size_t i = 0; i < count; ++i)
-        {
-            size_t j = i << 2;
-            newKeyValues[j] = x;
-            newKeyValues[j+1] = y;
-            newKeyValues[j+2] = z;
-            newKeyValues[j+3] = _keyValues[i];
-        }
-        setKeyValues(newKeyValues);
-        setTargetAttribute(Transform::ANIMATE_ROTATE);
-    }
-}
 
 
-void AnimationChannel::convertToTransform()
-{
-    if (_targetAttrib == Transform::ANIMATE_ROTATE_X ||
-        _targetAttrib == Transform::ANIMATE_ROTATE_Y ||
-        _targetAttrib == Transform::ANIMATE_ROTATE_Z)
-    {
-        std::vector<float> newKeyValues;
-        newKeyValues.resize(_keyValues.size() * 10);
-        const size_t count = _keyValues.size();
-
-        float x = _targetAttrib == Transform::ANIMATE_ROTATE_X ? 1.0f : 0.0f;
-        float y = _targetAttrib == Transform::ANIMATE_ROTATE_Y ? 1.0f : 0.0f;
-        float z = _targetAttrib == Transform::ANIMATE_ROTATE_Z ? 1.0f : 0.0f;
-        for (size_t i = 0; i < count; ++i)
-        {
-            size_t j = i << 2;
-            newKeyValues[j+0] = 1.0f;
-            newKeyValues[j+1] = 1.0f;
-            newKeyValues[j+2] = 1.0f;
-            newKeyValues[j+3] = x;
-            newKeyValues[j+4] = y;
-            newKeyValues[j+5] = z;
-            newKeyValues[j+6] = _keyValues[i];
-            newKeyValues[j+7] = 0.0f;
-            newKeyValues[j+8] = 0.0f;
-            newKeyValues[j+9] = 0.0f;
-        }
-        setKeyValues(newKeyValues);
-        setTargetAttribute(Transform::ANIMATE_SCALE_ROTATE_TRANSLATE);
-    }
+    LOG(3, "      Removed %d duplicate keyframes from channel.\n", startCount- _keytimes.size());
 }
 }
 
 
 unsigned int AnimationChannel::getInterpolationType(const char* str)
 unsigned int AnimationChannel::getInterpolationType(const char* str)
@@ -275,8 +223,9 @@ unsigned int AnimationChannel::getInterpolationType(const char* str)
 void AnimationChannel::deleteRange(size_t begin, size_t end, size_t propSize)
 void AnimationChannel::deleteRange(size_t begin, size_t end, size_t propSize)
 {
 {
     assert(end > begin);
     assert(end > begin);
+
     // delete range
     // delete range
-    printf("delete %lu to %lu\n", begin, end - 1);
+    LOG(4, "        delete %lu to %lu\n", begin, end - 1);
 
 
     std::vector<float>::iterator a = _keyValues.begin() + begin * propSize;
     std::vector<float>::iterator a = _keyValues.begin() + begin * propSize;
     std::vector<float>::iterator b = _keyValues.begin() + end * propSize;
     std::vector<float>::iterator b = _keyValues.begin() + end * propSize;

+ 5 - 8
gameplay-encoder/src/AnimationChannel.h

@@ -54,20 +54,17 @@ public:
     void setInterpolations(const std::vector<unsigned int>& values);
     void setInterpolations(const std::vector<unsigned int>& values);
 
 
     unsigned int getTargetAttribute() const;
     unsigned int getTargetAttribute() const;
-    const std::vector<float>& getKeyValues() const;
-    const std::vector<float>& getKeyTimes() const;
-    const std::vector<float>& getTangentsIn() const;
-    const std::vector<float>& getTangentsOut() const;
-    const std::vector<unsigned int>& getInterpolationTypes() const;
+    std::vector<float>& getKeyValues();
+    std::vector<float>& getKeyTimes();
+    std::vector<float>& getTangentsIn();
+    std::vector<float>& getTangentsOut();
+    std::vector<unsigned int>& getInterpolationTypes();
 
 
     /**
     /**
      * Removes duplicate key frames from the animation channel.
      * Removes duplicate key frames from the animation channel.
      */
      */
     void removeDuplicates();
     void removeDuplicates();
 
 
-    void convertToQuaternion();
-    void convertToTransform();
-
     /**
     /**
      * Returns the interpolation type value for the given string or zero if not valid.
      * Returns the interpolation type value for the given string or zero if not valid.
      * Example: "LINEAR" returns AnimationChannel::LINEAR
      * Example: "LINEAR" returns AnimationChannel::LINEAR

+ 12 - 8
gameplay-encoder/src/Base.h

@@ -10,6 +10,7 @@
 #include <cmath>
 #include <cmath>
 #include <cfloat>
 #include <cfloat>
 #include <ctime>
 #include <ctime>
+#include <cstring>
 #include <iostream>
 #include <iostream>
 #include <fstream>
 #include <fstream>
 #include <string>
 #include <string>
@@ -24,6 +25,7 @@
 
 
 // Collada includes
 // Collada includes
 #include <dae.h>
 #include <dae.h>
+#include <dom.h>
 #include <dae/daeSIDResolver.h>
 #include <dae/daeSIDResolver.h>
 #include <dae/domAny.h>
 #include <dae/domAny.h>
 #include <dom/domCOLLADA.h>
 #include <dom/domCOLLADA.h>
@@ -86,7 +88,8 @@ void fillArray(float values[], float value, size_t length);
  */
  */
 std::string getBaseName(const std::string& filepath);
 std::string getBaseName(const std::string& filepath);
 
 
-#define ISZERO(x) (fabs(x) < 0.000001f)
+#define ISZERO(x) (fabs(x) < MATH_EPSILON)
+#define ISONE(x) ((x - 1.0f) < MATH_EPSILON)
 
 
 // Object deletion macro
 // Object deletion macro
 #define SAFE_DELETE(x) \
 #define SAFE_DELETE(x) \
@@ -96,13 +99,14 @@ std::string getBaseName(const std::string& filepath);
         x = NULL; \
         x = NULL; \
     }
     }
 
 
-#ifdef NDEBUG
-#define DEBUGPRINT(x)
-#define DEBUGPRINT_VARG(x, ...)
-#else
-#define DEBUGPRINT(x)  printf(x)
-#define DEBUGPRINT_VARG(x, ...) printf(x, __VA_ARGS__)
-#endif
+extern int __logVerbosity;
+
+// Logging macro (level is verbosity level, 1-4).
+#define LOG(level, ...) \
+    { \
+        if (level <= __logVerbosity) \
+            printf(__VA_ARGS__); \
+    }
 
 
 }
 }
 
 

+ 9 - 0
gameplay-encoder/src/BoundingVolume.cpp

@@ -92,6 +92,15 @@ void BoundingVolume::transform(const Matrix& m)
 
 
 void BoundingVolume::merge(const BoundingVolume& v)
 void BoundingVolume::merge(const BoundingVolume& v)
 {
 {
+    // Merge the box portion
+    min.x = std::min(min.x, v.min.x);
+    min.y = std::min(min.y, v.min.y);
+    min.z = std::min(min.z, v.min.z);
+    max.x = std::max(max.x, v.max.x);
+    max.y = std::max(max.y, v.max.y);
+    max.z = std::max(max.z, v.max.z);
+
+    // Merge the sphere portion
     // Calculate the distance between the two centers.
     // Calculate the distance between the two centers.
     float vx = center.x - v.center.x;
     float vx = center.x - v.center.x;
     float vy = center.y - v.center.y;
     float vy = center.y - v.center.y;

+ 1 - 0
gameplay-encoder/src/Camera.cpp

@@ -5,6 +5,7 @@ namespace gameplay
 {
 {
 
 
 Camera::Camera(void) :
 Camera::Camera(void) :
+    _cameraType(CameraPerspective), 
     _fieldOfView(0.0f),
     _fieldOfView(0.0f),
     _aspectRatio(0.0f),
     _aspectRatio(0.0f),
     _nearPlane(0.0f),
     _nearPlane(0.0f),

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

@@ -1343,4 +1343,4 @@ int Curve::getInterpolationType(const char* curveId)
     return -1;
     return -1;
 }
 }
 
 
-}
+}

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

@@ -19,7 +19,7 @@ void DAEOptimizer::combineAnimations(const std::string& nodeId, const std::strin
 
 
     daeSIDResolver resolver(_dom, nodeId.c_str());
     daeSIDResolver resolver(_dom, nodeId.c_str());
     daeElement* element = resolver.getElement();
     daeElement* element = resolver.getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == COLLADA_TYPE::NODE)
     {
     {
         domNodeRef node = daeSafeCast<domNode>(resolver.getElement());
         domNodeRef node = daeSafeCast<domNode>(resolver.getElement());
         getAnimationChannels(node, channels);
         getAnimationChannels(node, channels);

+ 78 - 84
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -63,7 +63,7 @@ void DAESceneEncoder::optimizeCOLLADA(const EncoderArguments& arguments, domCOLL
             // Ask the user if they want to group animations automatically.
             // Ask the user if they want to group animations automatically.
             if (promptUserGroupAnimations())
             if (promptUserGroupAnimations())
             {
             {
-                printf("Grouping animations...\n");
+                LOG(2, "Grouping animations...\n");
 
 
                 DAEOptimizer optimizer(dom);
                 DAEOptimizer optimizer(dom);
                 begin();
                 begin();
@@ -87,7 +87,7 @@ void DAESceneEncoder::optimizeCOLLADA(const EncoderArguments& arguments, domCOLL
     {
     {
         if (!_collada->writeTo(arguments.getFilePath(), arguments.getDAEOutputPath()))
         if (!_collada->writeTo(arguments.getFilePath(), arguments.getDAEOutputPath()))
         {
         {
-            fprintf(stderr,"Error: COLLADA failed to write the dom for file: %s\n", arguments.getDAEOutputPath().c_str());
+            LOG(1, "Error: COLLADA failed to write the dom for file: %s\n", arguments.getDAEOutputPath().c_str());
         }
         }
     }
     }
 }
 }
@@ -264,11 +264,11 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
     // Load the collada document
     // Load the collada document
     _collada = new DAE();
     _collada = new DAE();
     begin();
     begin();
-    _dom = _collada->open(filepath);
+    _dom = (domCOLLADA*)_collada->open(filepath);
     end("Open file");
     end("Open file");
     if (!_dom)
     if (!_dom)
     {
     {
-        fprintf(stderr,"Error: COLLADA failed to open file: %s\n", filepath.c_str());
+        LOG(1, "Error: COLLADA failed to open file: %s\n", filepath.c_str());
         if (_collada)
         if (_collada)
         {
         {
             delete _collada;
             delete _collada;
@@ -287,10 +287,9 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
 
 
     // Find the <visual_scene> element within the <scene>
     // Find the <visual_scene> element within the <scene>
     const domCOLLADA::domSceneRef& domScene = _dom->getScene();
     const domCOLLADA::domSceneRef& domScene = _dom->getScene();
-    daeElement* scene = NULL;
     if (domScene && domScene->getInstance_visual_scene())
     if (domScene && domScene->getInstance_visual_scene())
     {
     {
-        scene = getVisualScene(domScene);
+        daeElement* scene = getVisualScene(domScene);
         if (scene)
         if (scene)
         {
         {
             if (nodeId == NULL)
             if (nodeId == NULL)
@@ -314,23 +313,23 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
                     }
                     }
                     else
                     else
                     {
                     {
-                        fprintf(stderr,"COLLADA File loaded to the dom, but failed to load node %s.\n", nodeId);
+                        LOG(1, "COLLADA File loaded to the dom, but failed to load node %s.\n", nodeId);
                     }
                     }
                 }
                 }
                 else
                 else
                 {
                 {
-                    fprintf(stderr,"COLLADA File loaded to the dom, but node was not found with node ID %s.\n", nodeId);
+                    LOG(1, "COLLADA File loaded to the dom, but node was not found with node ID %s.\n", nodeId);
                 }
                 }
             }
             }
         }
         }
         else
         else
         {
         {
-             fprintf(stderr,"COLLADA File loaded to the dom, but query for the dom assets failed.\n");
+             LOG(1, "COLLADA File loaded to the dom, but query for the dom assets failed.\n");
         }
         }
     }
     }
     else
     else
     {
     {
-        fprintf(stderr, "COLLADA File loaded to the dom, but missing <visual_scene>.\n");
+        LOG(1, "COLLADA File loaded to the dom, but missing <visual_scene>.\n");
     }
     }
     
     
     // The animations should be loaded last
     // The animations should be loaded last
@@ -350,20 +349,20 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
         {
         {
             std::string path = outputFilePath.substr(0, pos);
             std::string path = outputFilePath.substr(0, pos);
             path.append(".xml");
             path.append(".xml");
-            fprintf(stderr, "Saving debug file: %s\n", path.c_str());
+            LOG(1, "Saving debug file: %s\n", path.c_str());
             if (!_gamePlayFile.saveText(path))
             if (!_gamePlayFile.saveText(path))
             {
             {
-                fprintf(stderr,"Error writing text file: %s\n", path.c_str());
+                LOG(1, "Error writing text file: %s\n", path.c_str());
             }
             }
         }
         }
     }
     }
     else
     else
     {
     {
-        fprintf(stderr, "Saving binary file: %s\n", outputFilePath.c_str());
+        LOG(1, "Saving binary file: %s\n", outputFilePath.c_str());
         begin();
         begin();
         if (!_gamePlayFile.saveBinary(outputFilePath))
         if (!_gamePlayFile.saveBinary(outputFilePath))
         {
         {
-            fprintf(stderr,"Error writing binary file: %s\n", outputFilePath.c_str());
+            LOG(1, "Error writing binary file: %s\n", outputFilePath.c_str());
         }
         }
         end("save binary");
         end("save binary");
     }
     }
@@ -569,7 +568,7 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
             daeInt type = attributeElement->typeID();
             daeInt type = attributeElement->typeID();
             if (type == domRotate::ID())
             if (type == domRotate::ID())
             {
             {
-                printf(TRANSFORM_WARNING_FORMAT, targetId, "Rotate", TRANSFORM_MESSAGE);
+                LOG(1, TRANSFORM_WARNING_FORMAT, targetId, "Rotate", TRANSFORM_MESSAGE);
                 return false;
                 return false;
                 /*
                 /*
                 // <rotate>
                 // <rotate>
@@ -610,7 +609,7 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
             }
             }
             else if (type == domScale::ID())
             else if (type == domScale::ID())
             {
             {
-                printf(TRANSFORM_WARNING_FORMAT, targetId, "Scale", TRANSFORM_MESSAGE);
+                LOG(1, TRANSFORM_WARNING_FORMAT, targetId, "Scale", TRANSFORM_MESSAGE);
                 return false;
                 return false;
                 /*
                 /*
                 // <scale>
                 // <scale>
@@ -635,7 +634,7 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
             }
             }
             else if (type == domTranslate::ID())
             else if (type == domTranslate::ID())
             {
             {
-                printf(TRANSFORM_WARNING_FORMAT, targetId, "Translate", TRANSFORM_MESSAGE);
+                LOG(1, TRANSFORM_WARNING_FORMAT, targetId, "Translate", TRANSFORM_MESSAGE);
                 return false;
                 return false;
                 /*
                 /*
                 // <translate>
                 // <translate>
@@ -719,7 +718,7 @@ void DAESceneEncoder::end(const char* str)
 {
 {
     #ifdef ENCODER_PRINT_TIME
     #ifdef ENCODER_PRINT_TIME
     clock_t time = clock() - _begin;
     clock_t time = clock() - _begin;
-    fprintf(stderr,"%5d %s\n", time, str);
+    LOG(1, "%5d %s\n", time, str);
     #endif
     #endif
 }
 }
 
 
@@ -890,7 +889,7 @@ void DAESceneEncoder::calcTransform(domNode* domNode, Matrix& dstTransform)
     for (size_t i = 0; i < childCount; ++i)
     for (size_t i = 0; i < childCount; ++i)
     {
     {
         daeElementRef childElement = children[i];
         daeElementRef childElement = children[i];
-        switch (childElement->getElementType())
+        switch (childElement->typeID())
         {
         {
             case COLLADA_TYPE::TRANSLATE:
             case COLLADA_TYPE::TRANSLATE:
             {
             {
@@ -936,10 +935,10 @@ void DAESceneEncoder::calcTransform(domNode* domNode, Matrix& dstTransform)
                 break;
                 break;
             }
             }
             case COLLADA_TYPE::SKEW:
             case COLLADA_TYPE::SKEW:
-                warning("Skew transform found but not supported.");
+                LOG(1, "Warning: Skew transform found but not supported.\n");
                 break;
                 break;
             case COLLADA_TYPE::LOOKAT:
             case COLLADA_TYPE::LOOKAT:
-                warning("Lookat transform found but not supported.");
+                LOG(1, "Warning: Lookat transform found but not supported.\n");
                 break;
                 break;
             default:
             default:
                 break;
                 break;
@@ -1024,7 +1023,7 @@ void DAESceneEncoder::loadGeometryInstance(const domNode* n, Node* node)
         }
         }
         else
         else
         {
         {
-            warning(std::string("Failed to resolve geometry url: ") + geometryURI.getURI());
+            LOG(1, "Failed to resolve geometry url: %s\n", geometryURI.getURI());
         }
         }
     }
     }
 }
 }
@@ -1287,7 +1286,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
         domNode* topLevelParent = rootNode;
         domNode* topLevelParent = rootNode;
         while (
         while (
             topLevelParent->getParent() &&
             topLevelParent->getParent() &&
-            topLevelParent->getParent()->getElementType() == COLLADA_TYPE::NODE &&
+            topLevelParent->getParent()->typeID() == COLLADA_TYPE::NODE &&
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) == NULL)
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) == NULL)
         {
         {
             topLevelParent = (domNode*)topLevelParent->getParent();
             topLevelParent = (domNode*)topLevelParent->getParent();
@@ -1296,7 +1295,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
         // Is the parent of this node loaded yet?
         // Is the parent of this node loaded yet?
         Node* parentNode = NULL;
         Node* parentNode = NULL;
         if (topLevelParent->getParent() &&
         if (topLevelParent->getParent() &&
-            topLevelParent->getParent()->getElementType() == COLLADA_TYPE::NODE &&
+            topLevelParent->getParent()->typeID() == COLLADA_TYPE::NODE &&
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) != NULL)
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) != NULL)
         {
         {
             parentNode = (Node*)_gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID());
             parentNode = (Node*)_gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID());
@@ -1317,7 +1316,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
     // Resolve and set joints array for skin
     // Resolve and set joints array for skin
     std::vector<Node*> _joints;
     std::vector<Node*> _joints;
     const std::vector<std::string>& jointNames = skin->getJointNames();
     const std::vector<std::string>& jointNames = skin->getJointNames();
-    for (std::vector<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); i++)
+    for (std::vector<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); ++i)
     {
     {
         Object* obj = _gamePlayFile.getFromRefTable(*i);
         Object* obj = _gamePlayFile.getFromRefTable(*i);
         if (obj && obj->getTypeId() == Object::NODE_ID)
         if (obj && obj->getTypeId() == Object::NODE_ID)
@@ -1369,11 +1368,11 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
 
 
             // Go through the joint list and convert them from sid to id because the sid information is
             // Go through the joint list and convert them from sid to id because the sid information is
             // lost when converting to the gameplay binary format.
             // lost when converting to the gameplay binary format.
-            for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i)
             {
             {
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeElement* element = resolver.getElement();
                 daeElement* element = resolver.getElement();
-                if (element && element->getElementType() == COLLADA_TYPE::NODE)
+                if (element && element->typeID() == COLLADA_TYPE::NODE)
                 {
                 {
                     domNodeRef node = daeSafeCast<domNode>(element);
                     domNodeRef node = daeSafeCast<domNode>(element);
                     const char* nodeId = node->getId();
                     const char* nodeId = node->getId();
@@ -1388,7 +1387,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
             jointCount = list.size();
             jointCount = list.size();
             _jointInverseBindPoseMatrices.reserve(jointCount);
             _jointInverseBindPoseMatrices.reserve(jointCount);
             unsigned int j = 0;
             unsigned int j = 0;
-            for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
             {
             {
                 _jointLookupTable[*i] = j++;
                 _jointLookupTable[*i] = j++;
             }
             }
@@ -1399,7 +1398,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
     // Make sure we have some joints
     // Make sure we have some joints
     if (jointCount == 0)
     if (jointCount == 0)
     {
     {
-        warning("No joints found for skin: ");
+        LOG(1, "Warning: No joints found for skin: %s\n", skinElement->getID());
         return NULL;
         return NULL;
     }
     }
 
 
@@ -1572,7 +1571,7 @@ Model* DAESceneEncoder::loadGeometry(const domGeometry* geometry, const domBind_
     const domMesh* meshElement = geometry->getMesh();
     const domMesh* meshElement = geometry->getMesh();
     if (meshElement == NULL)
     if (meshElement == NULL)
     {
     {
-        warning(std::string("No mesh found for geometry: ") + geometry->getId());
+        LOG(1, "Warning: No mesh found for geometry: %s\n", geometry->getId());
         return NULL;
         return NULL;
     }
     }
 
 
@@ -1599,7 +1598,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     // Ensure the data is exported as triangles.
     // Ensure the data is exported as triangles.
     if (trianglesArrayCount == 0)
     if (trianglesArrayCount == 0)
     {
     {
-        warning(std::string("Geometry mesh has no triangles: ") + geometryId);
+        LOG(1, "Warning: Geometry mesh has no triangles: %s\n", geometryId.c_str());
         return NULL;
         return NULL;
     }
     }
 
 
@@ -1611,7 +1610,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     }
     }
     mesh = new Mesh();
     mesh = new Mesh();
     mesh->setId(geometryId.c_str());
     mesh->setId(geometryId.c_str());
-    
+
     std::vector<DAEPolygonInput*> polygonInputs;
     std::vector<DAEPolygonInput*> polygonInputs;
 
 
     // Quickly just go through each triangles array and make sure they have the same number of inputs
     // Quickly just go through each triangles array and make sure they have the same number of inputs
@@ -1650,7 +1649,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                         int type = getVertexUsageType(semantic);
                         int type = getVertexUsageType(semantic);
                         if (type == -1)
                         if (type == -1)
                         {
                         {
-                            warning(std::string("Vertex semantic (") + semantic + ") is invalid/unsupported for geometry mesh: " + geometryId);
+                            LOG(1, "Warning: Vertex semantic (%s) is invalid/unsupported for geometry mesh: %s\n", semantic.c_str(), geometryId.c_str());
                         }
                         }
 
 
                         DAEPolygonInput* polygonInput = new DAEPolygonInput();
                         DAEPolygonInput* polygonInput = new DAEPolygonInput();
@@ -1669,7 +1668,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                     int type = getVertexUsageType(semantic);
                     int type = getVertexUsageType(semantic);
                     if (type == -1)
                     if (type == -1)
                     {
                     {
-                        warning(std::string("Semantic (") + semantic + ") is invalid/unsupported for geometry mesh: " + geometryId);
+                        LOG(1, "Warning: Semantic (%s) is invalid/unsupported for geometry mesh: %s\n", semantic.c_str(), geometryId.c_str());
                         break;
                         break;
                     }
                     }
                     if (type == TEXCOORD0)
                     if (type == TEXCOORD0)
@@ -1709,7 +1708,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                 {
                 {
                     delete polygonInputs[j];
                     delete polygonInputs[j];
                 }
                 }
-                warning(std::string("Triangles do not all have the same number of input sources for geometry mesh: ") + geometryId);
+                LOG(1, "Warning: Triangles do not all have the same number of input sources for geometry mesh: %s\n", geometryId.c_str());
                 return NULL;
                 return NULL;
             }
             }
             else
             else
@@ -1819,7 +1818,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                                 break;
                                 break;
                             case 'b':
                             case 'b':
                             case 'B':
                             case 'B':
-                                vertex.diffuse.z = (float)source.get(index + i); // blue
+                                vertex.diffuse.z = (float)source.get(index+ i ); // blue
                                 break;
                                 break;
                             case 'a':
                             case 'a':
                             case 'A':
                             case 'A':
@@ -1849,34 +1848,43 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                 break;
                 break;
 
 
             case TEXCOORD0:
             case TEXCOORD0:
-                vertex.hasTexCoord = true;
-                if (polygonInputs[k]->accessor)
-                {
-                    // TODO: This assumes (s, t) are first
-                    unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
-                    if (polyIndexInt < 0)
-                    {
-                        unsigned int i = (unsigned int)((int)polygonInputs[k]->accessor->getCount()) + polyIndexInt;
-                        vertex.texCoord.x = (float)source.get(i * stride);
-                        vertex.texCoord.y = (float)source.get(i * stride + 1);
-                    }
-                    else
-                    {
-                        vertex.texCoord.x = (float)source.get(polyIndex * stride);
-                        vertex.texCoord.y = (float)source.get(polyIndex * stride + 1);
-                    }
-                }
-                else
+            case TEXCOORD1:
+            case TEXCOORD2:
+            case TEXCOORD3:
+            case TEXCOORD4:
+            case TEXCOORD5:
+            case TEXCOORD6:
+            case TEXCOORD7:
                 {
                 {
-                    vertex.texCoord.x = (float)source.get(polyIndex * 2);
-                    vertex.texCoord.y = (float)source.get(polyIndex * 2 + 1);
+                    unsigned int index = polygonInputs[k]->type - TEXCOORD0;
+                    //for (unsigned int i = 0; i < uvSetCount; ++i)
+                    //{
+                        vertex.hasTexCoord[index] = true;
+                        if (polygonInputs[k]->accessor)
+                        {
+                            // TODO: This assumes (s, t) are first
+                            unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
+                            if (polyIndexInt < 0)
+                            {
+                                unsigned int i = (unsigned int)((int)polygonInputs[k]->accessor->getCount()) + polyIndexInt;
+                                vertex.texCoord[index].x = (float)source.get(i * stride);
+                                vertex.texCoord[index].y = (float)source.get(i * stride + 1);
+                            }
+                            else
+                            {
+                                vertex.texCoord[index].x = (float)source.get(polyIndex * stride);
+                                vertex.texCoord[index].y = (float)source.get(polyIndex * stride + 1);
+                            }
+                        }
+                        else
+                        {
+                            vertex.texCoord[index].x = (float)source.get(polyIndex * 2);
+                            vertex.texCoord[index].y = (float)source.get(polyIndex * 2 + 1);
+                        }
+                    //}
                 }
                 }
                 break;
                 break;
 
 
-            case TEXCOORD1:
-                // TODO
-                break;
-
             default:
             default:
                 break;
                 break;
             }
             }
@@ -1909,13 +1917,6 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
         // Add our new subset for the mesh.
         // Add our new subset for the mesh.
         mesh->addMeshPart(subset);
         mesh->addMeshPart(subset);
     }
     }
-    
-    bool hasNormals = mesh->vertices[0].hasNormal;
-    bool hasDiffuses = mesh->vertices[0].hasDiffuse;
-    bool hasTangents = mesh->vertices[0].hasTangent;
-    bool hasBinormals = mesh->vertices[0].hasBinormal;
-    bool hasTexCoords = mesh->vertices[0].hasTexCoord;
-    bool hasWeights = mesh->vertices[0].hasWeights;
 
 
     // The order that the vertex elements are add to the list matters.
     // The order that the vertex elements are add to the list matters.
     // It should be the same order as how the Vertex data is written.
     // It should be the same order as how the Vertex data is written.
@@ -1924,32 +1925,35 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     mesh->addVetexAttribute(POSITION, Vertex::POSITION_COUNT);
     mesh->addVetexAttribute(POSITION, Vertex::POSITION_COUNT);
     
     
     // Normals
     // Normals
-    if (hasNormals)
+    if (mesh->vertices[0].hasNormal)
     {
     {
         mesh->addVetexAttribute(NORMAL, Vertex::NORMAL_COUNT);
         mesh->addVetexAttribute(NORMAL, Vertex::NORMAL_COUNT);
     }
     }
     // Tangents
     // Tangents
-    if (hasTangents)
+    if (mesh->vertices[0].hasTangent)
     {
     {
         mesh->addVetexAttribute(TANGENT, Vertex::TANGENT_COUNT);
         mesh->addVetexAttribute(TANGENT, Vertex::TANGENT_COUNT);
     }
     }
     // Binormals
     // Binormals
-    if (hasBinormals)
+    if (mesh->vertices[0].hasBinormal)
     {
     {
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
     }
     }
     // Texture Coordinates
     // Texture Coordinates
-    if (hasTexCoords)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
     {
-        mesh->addVetexAttribute(TEXCOORD0, Vertex::TEXCOORD_COUNT);
+        if (mesh->vertices[0].hasTexCoord[i])
+        {
+            mesh->addVetexAttribute(TEXCOORD0 + i, Vertex::TEXCOORD_COUNT);
+        }
     }
     }
     // Diffuse Color
     // Diffuse Color
-    if (hasDiffuses)
+    if (mesh->vertices[0].hasDiffuse)
     {
     {
         mesh->addVetexAttribute(COLOR, Vertex::DIFFUSE_COUNT);
         mesh->addVetexAttribute(COLOR, Vertex::DIFFUSE_COUNT);
     }
     }
     // Skinning BlendWeights BlendIndices
     // Skinning BlendWeights BlendIndices
-    if (hasWeights)
+    if (mesh->vertices[0].hasWeights)
     {
     {
         mesh->addVetexAttribute(BLENDWEIGHTS, Vertex::BLEND_WEIGHTS_COUNT);
         mesh->addVetexAttribute(BLENDWEIGHTS, Vertex::BLEND_WEIGHTS_COUNT);
         mesh->addVetexAttribute(BLENDINDICES, Vertex::BLEND_INDICES_COUNT);
         mesh->addVetexAttribute(BLENDINDICES, Vertex::BLEND_INDICES_COUNT);
@@ -1959,16 +1963,6 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
     return mesh;
     return mesh;
 }
 }
 
 
-void DAESceneEncoder::warning(const std::string& message)
-{
-    printf("Warning: %s\n", message.c_str());
-}
-
-void DAESceneEncoder::warning(const char* message)
-{
-    printf("Warning: %s\n", message);
-}
-
 int DAESceneEncoder::getVertexUsageType(const std::string& semantic)
 int DAESceneEncoder::getVertexUsageType(const std::string& semantic)
 {
 {
     if (semantic.length() > 0)
     if (semantic.length() > 0)

+ 0 - 3
gameplay-encoder/src/DAESceneEncoder.h

@@ -156,9 +156,6 @@ private:
      */
      */
     void calcTransform(domNode* domNode, Matrix& dstTransform);
     void calcTransform(domNode* domNode, Matrix& dstTransform);
 
 
-    void warning(const std::string& message);
-    void warning(const char* message);
-
     /**
     /**
      * Loads the target data into the animation from the given channel's target.
      * Loads the target data into the animation from the given channel's target.
      * Example: <channel target="Cube/location.X" />
      * Example: <channel target="Cube/location.X" />

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

@@ -54,7 +54,7 @@ void getAnimationChannels(const domNodeRef& node, std::list<domChannelRef>& chan
     for (size_t i = 0; i < childCount; ++i)
     for (size_t i = 0; i < childCount; ++i)
     {
     {
         daeElementRef childElement = children[i];
         daeElementRef childElement = children[i];
-        if (childElement->getElementType() == COLLADA_TYPE::NODE)
+        if (childElement->typeID() == COLLADA_TYPE::NODE)
         {
         {
             domNodeRef childNode = daeSafeCast<domNode>(childElement);
             domNodeRef childNode = daeSafeCast<domNode>(childElement);
             getAnimationChannels(childNode, channels);
             getAnimationChannels(childNode, channels);
@@ -115,7 +115,7 @@ void getJointNames(const domSkin* skin, std::vector<std::string>& list)
 domSource* getInputSource(const domChannelRef& channel)
 domSource* getInputSource(const domChannelRef& channel)
 {
 {
     daeElement* element = channel->getSource().getElement();
     daeElement* element = channel->getSource().getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
     {
     {
         domSampler* sampler = daeSafeCast<domSampler>(element);
         domSampler* sampler = daeSafeCast<domSampler>(element);
         const domInputLocal_Array& inputArray = sampler->getInput_array();
         const domInputLocal_Array& inputArray = sampler->getInput_array();
@@ -126,7 +126,7 @@ domSource* getInputSource(const domChannelRef& channel)
             if (strcmp(input->getSemantic(), "INPUT") == 0)
             if (strcmp(input->getSemantic(), "INPUT") == 0)
             {
             {
                 daeElement* e = input->getSource().getElement();
                 daeElement* e = input->getSource().getElement();
-                if (e && e->getElementType() == COLLADA_TYPE::SOURCE)
+                if (e && e->typeID() == COLLADA_TYPE::SOURCE)
                 {
                 {
                     domSource* source = daeSafeCast<domSource>(e);
                     domSource* source = daeSafeCast<domSource>(e);
                     assert(source);
                     assert(source);
@@ -142,7 +142,7 @@ const domSamplerRef getSampler(const domChannelRef& channel)
 {
 {
     const domURIFragmentType& uri = channel->getSource();
     const domURIFragmentType& uri = channel->getSource();
     daeElementRef element = uri.getElement();
     daeElementRef element = uri.getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
     {
     {
         const domSamplerRef sampler = daeSafeCast<domSampler>(element);
         const domSamplerRef sampler = daeSafeCast<domSampler>(element);
         return sampler;
         return sampler;
@@ -150,7 +150,7 @@ const domSamplerRef getSampler(const domChannelRef& channel)
     // resolve the source manually by searching for the sampler in the animation that the channel is a child of.
     // resolve the source manually by searching for the sampler in the animation that the channel is a child of.
     const std::string& id = uri.id();
     const std::string& id = uri.id();
     const daeElementRef& parent = channel->getParent();
     const daeElementRef& parent = channel->getParent();
-    if (parent && parent->getElementType() == COLLADA_TYPE::ANIMATION)
+    if (parent && parent->typeID() == COLLADA_TYPE::ANIMATION)
     {
     {
         const domAnimationRef animation = daeSafeCast<domAnimation>(parent);
         const domAnimationRef animation = daeSafeCast<domAnimation>(parent);
         
         
@@ -172,7 +172,7 @@ const domSourceRef getSource(const domInputLocalRef& inputLocal, const domAnimat
 {
 {
     const domURIFragmentType& uri = inputLocal->getSource();
     const domURIFragmentType& uri = inputLocal->getSource();
     daeElementRef element = uri.getElement();
     daeElementRef element = uri.getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
     {
     {
         const domSourceRef source = daeSafeCast<domSource>(element);
         const domSourceRef source = daeSafeCast<domSource>(element);
         return source;
         return source;
@@ -205,7 +205,7 @@ const domName_arrayRef getSourceNameArray(const domSourceRef& source)
     for (size_t i = 0; i < childCount; ++i)
     for (size_t i = 0; i < childCount; ++i)
     {
     {
         const daeElementRef element = children.get(i);
         const daeElementRef element = children.get(i);
-        if (element->getElementType() == COLLADA_TYPE::NAME_ARRAY)
+        if (element->typeID() == COLLADA_TYPE::NAME_ARRAY)
         {
         {
             return daeSafeCast<domName_array>(element);
             return daeSafeCast<domName_array>(element);
         }
         }
@@ -229,7 +229,7 @@ const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_contr
     // Find the skeleton element that points to the root most node.
     // Find the skeleton element that points to the root most node.
     const domInstance_controller::domSkeletonRef& currentSkeleton = skeletonArray.get(0);
     const domInstance_controller::domSkeletonRef& currentSkeleton = skeletonArray.get(0);
     const daeElementRef element = currentSkeleton->getValue().getElement();
     const daeElementRef element = currentSkeleton->getValue().getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == COLLADA_TYPE::NODE)
     {
     {
         domNode* node = daeSafeCast<domNode>(element);
         domNode* node = daeSafeCast<domNode>(element);
         int index = 0;
         int index = 0;
@@ -237,7 +237,7 @@ const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_contr
         do
         do
         {
         {
             daeElementRef parent = node->getParent();
             daeElementRef parent = node->getParent();
-            if (parent && parent->getElementType() == COLLADA_TYPE::NODE)
+            if (parent && parent->typeID() == COLLADA_TYPE::NODE)
             {
             {
                 domNodeRef parentNode = daeSafeCast<domNode>(parent);
                 domNodeRef parentNode = daeSafeCast<domNode>(parent);
                 int result = getIndex(skeletonArray, parentNode);
                 int result = getIndex(skeletonArray, parentNode);
@@ -266,7 +266,7 @@ domNode* getRootJointNode(const domSkin* skin)
     getJointNames(skin, names);
     getJointNames(skin, names);
     daeSIDResolver resolver(const_cast<domSkin*>(skin)->getDocument()->getDomRoot(), names[0].c_str());
     daeSIDResolver resolver(const_cast<domSkin*>(skin)->getDocument()->getDomRoot(), names[0].c_str());
     daeElement* element = resolver.getElement();
     daeElement* element = resolver.getElement();
-    if (element && element->getElementType() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == COLLADA_TYPE::NODE)
     {
     {
         domNode* node = daeSafeCast<domNode>(resolver.getElement());
         domNode* node = daeSafeCast<domNode>(resolver.getElement());
         return node;
         return node;
@@ -326,7 +326,7 @@ void moveChannelAndSouresToAnimation(domChannelRef& channel, domAnimationRef& an
             inputArray = sampler->getInput_array();
             inputArray = sampler->getInput_array();
             const domInputLocalRef& input = inputArray.get(i);
             const domInputLocalRef& input = inputArray.get(i);
             daeElementRef element = input->getSource().getElement();
             daeElementRef element = input->getSource().getElement();
-            if (element && element->getElementType() == COLLADA_TYPE::SOURCE)
+            if (element && element->typeID() == COLLADA_TYPE::SOURCE)
             {
             {
                 domSourceRef source = daeSafeCast<domSource>(element);
                 domSourceRef source = daeSafeCast<domSource>(element);
                 assert(source);
                 assert(source);
@@ -355,7 +355,7 @@ int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, con
     {
     {
         const domInstance_controller::domSkeletonRef& skeleton = skeletonArray.get(i);
         const domInstance_controller::domSkeletonRef& skeleton = skeletonArray.get(i);
         daeElementRef element = skeleton->getValue().getElement();
         daeElementRef element = skeleton->getValue().getElement();
-        if (element->getElementType() == COLLADA_TYPE::NODE)
+        if (element->typeID() == COLLADA_TYPE::NODE)
         {
         {
             domNodeRef targetNode = daeSafeCast<domNode>(element);
             domNodeRef targetNode = daeSafeCast<domNode>(element);
             if (nodeId.compare(targetNode->getId()) == 0)
             if (nodeId.compare(targetNode->getId()) == 0)
@@ -395,7 +395,7 @@ void getAnimationChannels(const domAnimationRef& animationRef, const std::string
 domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
 domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
 {
 {
     daeElement* scene = domScene->getInstance_visual_scene()->getUrl().getElement();
     daeElement* scene = domScene->getInstance_visual_scene()->getUrl().getElement();
-    if (scene->getElementType() == COLLADA_TYPE::VISUAL_SCENE)
+    if (scene->typeID() == COLLADA_TYPE::VISUAL_SCENE)
     {
     {
         return static_cast<domVisual_scene*>(scene);
         return static_cast<domVisual_scene*>(scene);
     }
     }
@@ -425,7 +425,7 @@ domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
 domNode* getParent(domNodeRef node)
 domNode* getParent(domNodeRef node)
 {
 {
     daeElement* parent = node->getParent();
     daeElement* parent = node->getParent();
-    if (parent && parent->getElementType() == COLLADA_TYPE::NODE)
+    if (parent && parent->typeID() == COLLADA_TYPE::NODE)
     {
     {
         domNodeRef parentNode = daeSafeCast<domNode>(parent);
         domNodeRef parentNode = daeSafeCast<domNode>(parent);
         return parentNode.cast();
         return parentNode.cast();
@@ -436,7 +436,7 @@ domNode* getParent(domNodeRef node)
 domAnimation* getAnimation(domChannelRef channel)
 domAnimation* getAnimation(domChannelRef channel)
 {
 {
     daeElement* parent = channel->getParent();
     daeElement* parent = channel->getParent();
-    if (parent && parent->getElementType() == COLLADA_TYPE::ANIMATION)
+    if (parent && parent->typeID() == COLLADA_TYPE::ANIMATION)
     {
     {
         domAnimationRef parentNode = daeSafeCast<domAnimation>(parent);
         domAnimationRef parentNode = daeSafeCast<domAnimation>(parent);
         return parentNode.cast();
         return parentNode.cast();
@@ -538,11 +538,11 @@ void findChannelsTargetingJoints(const domSourceRef& source, std::list<domChanne
 {
 {
     std::vector<std::string> jointNames;
     std::vector<std::string> jointNames;
     getJointNames(source, jointNames);
     getJointNames(source, jointNames);
-    for (std::vector<std::string>::iterator i = jointNames.begin(); i != jointNames.end(); i++)
+    for (std::vector<std::string>::iterator i = jointNames.begin(); i != jointNames.end(); ++i)
     {
     {
         daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
         daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
         daeElement* element = resolver.getElement();
         daeElement* element = resolver.getElement();
-        if (element && element->getElementType() == COLLADA_TYPE::NODE)
+        if (element && element->typeID() == COLLADA_TYPE::NODE)
         {
         {
             domNodeRef node = daeSafeCast<domNode>(element);
             domNodeRef node = daeSafeCast<domNode>(element);
             nodes.push_back(node);
             nodes.push_back(node);

+ 93 - 39
gameplay-encoder/src/EncoderArguments.cpp

@@ -13,13 +13,15 @@ namespace gameplay
 
 
 static EncoderArguments* __instance;
 static EncoderArguments* __instance;
 
 
+extern int __logVerbosity = 1;
+
 EncoderArguments::EncoderArguments(size_t argc, const char** argv) :
 EncoderArguments::EncoderArguments(size_t argc, const char** argv) :
     _fontSize(0),
     _fontSize(0),
     _parseError(false),
     _parseError(false),
     _fontPreview(false),
     _fontPreview(false),
     _textOutput(false),
     _textOutput(false),
     _daeOutput(false),
     _daeOutput(false),
-    _isHeightmapHighP(false)
+    _optimizeAnimations(false)
 {
 {
     __instance = this;
     __instance = this;
 
 
@@ -135,7 +137,6 @@ bool EncoderArguments::containsGroupNodeId(const std::string& nodeId) const
 
 
 const std::string EncoderArguments::getAnimationId(const std::string& nodeId) const
 const std::string EncoderArguments::getAnimationId(const std::string& nodeId) const
 {
 {
-    std::vector<std::string>::const_iterator it = find(_groupAnimationNodeId.begin(), _groupAnimationNodeId.end(), nodeId);
     for (size_t i = 0, size = _groupAnimationNodeId.size(); i < size; ++i)
     for (size_t i = 0, size = _groupAnimationNodeId.size(); i < size; ++i)
     {
     {
         if (_groupAnimationNodeId[i].compare(nodeId) == 0)
         if (_groupAnimationNodeId[i].compare(nodeId) == 0)
@@ -146,14 +147,9 @@ const std::string EncoderArguments::getAnimationId(const std::string& nodeId) co
     return "";
     return "";
 }
 }
 
 
-const std::vector<std::string>& EncoderArguments::getHeightmapNodeIds() const
-{
-    return _heightmapNodeIds;
-}
-
-bool EncoderArguments::isHeightmapHighP() const
+const std::vector<EncoderArguments::HeightmapOption>& EncoderArguments::getHeightmapOptions() const
 {
 {
-    return _isHeightmapHighP;
+    return _heightmaps;
 }
 }
 
 
 bool EncoderArguments::parseErrorOccured() const
 bool EncoderArguments::parseErrorOccured() const
@@ -176,26 +172,36 @@ bool EncoderArguments::fileExists() const
 
 
 void EncoderArguments::printUsage() const
 void EncoderArguments::printUsage() const
 {
 {
-    fprintf(stderr,"Usage: gameplay-encoder [options] <input filepath> <output filepath>\n\n");
-    fprintf(stderr,"Supported file extensions:\n");
-    fprintf(stderr,"  .dae\t(COLLADA)\n");
-    fprintf(stderr,"  .fbx\t(FBX)\n");
-    fprintf(stderr,"  .ttf\t(TrueType Font)\n");
-    fprintf(stderr,"\n");
-    fprintf(stderr,"COLLADA and FBX file options:\n");
-    fprintf(stderr,"  -i <id>\t\tFilter by node ID.\n");
-    fprintf(stderr,"  -t\t\t\tWrite text/xml.\n");
-    fprintf(stderr,"  -g <node id> <animation id>\n" \
-        "\t\t\tGroup all animation channels targeting the nodes into a new animation.\n");
-    fprintf(stderr,"  -h \"<node ids>\"\n" \
-        "\t\t\tList of nodes to generate heightmaps for.\n" \
-        "\t\t\tNode id list should be in quotes with a space between each id.\n" \
-        "\t\t\tHeightmaps will be saved in files named <nodeid>.png.\n" \
-        "\t\t\tFor 24-bit packed height data use -hp instead of -h.\n");
-    fprintf(stderr,"\n");
-    fprintf(stderr,"TTF file options:\n");
-    fprintf(stderr,"  -s <size of font>\tSize of the font.\n");
-    fprintf(stderr,"  -p\t\t\tOutput font preview.\n");
+    LOG(1, "Usage: gameplay-encoder [options] <input filepath> <output filepath>\n\n");
+    LOG(1, "Supported file extensions:\n");
+    LOG(1, "  .dae\t(COLLADA)\n");
+    LOG(1, "  .fbx\t(FBX)\n");
+    LOG(1, "  .ttf\t(TrueType Font)\n");
+    LOG(1, "\n");
+    LOG(1, "General Options:\n");
+    LOG(1, "  -v <verbosity>\tVerbosity level (0-4).\n");
+    LOG(1, "\n");
+    LOG(1, "COLLADA and FBX file options:\n");
+    LOG(1, "  -i <id>\tFilter by node ID.\n");
+    LOG(1, "  -t\t\tWrite text/xml.\n");
+    LOG(1, "  -g <node id> <animation id>\n" \
+        "\t\tGroup all animation channels targeting the nodes into a new animation.\n");
+    LOG(1, "  -oa\n" \
+        "\t\tOptimizes animations by analyzing animation channel data and\n" \
+        "\t\tremoving any channels that contain default/identity values\n" \
+        "\t\tand removing any duplicate contiguous keyframes, which are common\n" \
+        "\t\twhen exporting baked animation data.\n");
+    LOG(1, "  -h \"<node ids>\" <filename>\n" \
+        "\t\tGenerates a single heightmap image using meshes from the specified\n" \
+        "\t\tnodes. Node id list should be in quotes with a space between each id.\n" \
+        "\t\tFilename is the name of the image (PNG) to be saved.\n" \
+        "\t\tMultiple -h arguments can be supplied to generate more than one heightmap.\n" \
+        "\t\tFor 24-bit packed height data use -hp instead of -h.\n");
+    LOG(1, "\n");
+    LOG(1, "TTF file options:\n");
+    LOG(1, "  -s <size>\tSize of the font.\n");
+    LOG(1, "  -p\t\tOutput font preview.\n");
+    LOG(1, "\n");
     exit(8);
     exit(8);
 }
 }
 
 
@@ -214,6 +220,11 @@ bool EncoderArguments::DAEOutputEnabled() const
     return _daeOutput;
     return _daeOutput;
 }
 }
 
 
+bool EncoderArguments::optimizeAnimationsEnabled() const
+{
+    return _optimizeAnimations;
+}
+
 const char* EncoderArguments::getNodeId() const
 const char* EncoderArguments::getNodeId() const
 {
 {
     if (_nodeId.length() == 0)
     if (_nodeId.length() == 0)
@@ -278,7 +289,7 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
             // read one string, make sure not to go out of bounds
             // read one string, make sure not to go out of bounds
             if ((*index + 1) >= options.size())
             if ((*index + 1) >= options.size())
             {
             {
-                fprintf(stderr, "Error: -dae requires 1 argument.\n");
+                LOG(1, "Error: -dae requires 1 argument.\n");
                 _parseError = true;
                 _parseError = true;
                 return;
                 return;
             }
             }
@@ -293,7 +304,7 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
             // read two strings, make sure not to go out of bounds
             // read two strings, make sure not to go out of bounds
             if ((*index + 2) >= options.size())
             if ((*index + 2) >= options.size())
             {
             {
-                fprintf(stderr, "Error: -g requires 2 arguments.\n");
+                LOG(1, "Error: -g requires 2 arguments.\n");
                 _parseError = true;
                 _parseError = true;
                 return;
                 return;
             }
             }
@@ -304,7 +315,6 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
         }
         }
         break;
         break;
     case 'i':
     case 'i':
-    case 'o':
         // Node ID
         // Node ID
         (*index)++;
         (*index)++;
         if (*index < options.size())
         if (*index < options.size())
@@ -313,20 +323,32 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
         }
         }
         else
         else
         {
         {
-            fprintf(stderr, "Error: missing arguemnt for -%c.\n", str[1]);
+            LOG(1, "Error: missing arguemnt for -%c.\n", str[1]);
             _parseError = true;
             _parseError = true;
             return;
             return;
         }
         }
         break;
         break;
+    case 'o':
+        // Optimization flag
+        if (str == "-oa")
+        {
+            // Optimize animations
+            _optimizeAnimations = true;
+        }
+        break;
     case 'h':
     case 'h':
         {
         {
             bool isHighPrecision = str.compare("-hp") == 0;
             bool isHighPrecision = str.compare("-hp") == 0;
-            if (str.compare("-heightmaps") == 0 || str.compare("-h") == 0 || isHighPrecision)
+            if (str.compare("-heightmap") == 0 || str.compare("-h") == 0 || isHighPrecision)
             {
             {
-                _isHeightmapHighP = isHighPrecision;
                 (*index)++;
                 (*index)++;
-                if (*index < options.size())
+                if (*index < (options.size() + 1))
                 {
                 {
+                    _heightmaps.resize(_heightmaps.size() + 1);
+                    HeightmapOption& heightmap = _heightmaps.back();
+                    
+                    heightmap.isHighPrecision = isHighPrecision;
+
                     // Split node id list into tokens
                     // Split node id list into tokens
                     unsigned int length = options[*index].size() + 1;
                     unsigned int length = options[*index].size() + 1;
                     char* nodeIds = new char[length];
                     char* nodeIds = new char[length];
@@ -335,14 +357,36 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
                     char* id = strtok(nodeIds, " ");
                     char* id = strtok(nodeIds, " ");
                     while (id)
                     while (id)
                     {
                     {
-                        _heightmapNodeIds.push_back(id);
+                        heightmap.nodeIds.push_back(id);
                         id = strtok(NULL, " ");
                         id = strtok(NULL, " ");
                     }
                     }
                     delete[] nodeIds;
                     delete[] nodeIds;
+
+                    // Store output filename
+                    (*index)++;
+                    heightmap.filename = options[*index];
+                    if (heightmap.filename.empty())
+                    {
+                        LOG(1, "Error: missing filename argument for -h|-heightmap.\n");
+                        _parseError = true;
+                        return;
+                    }
+                    
+                    // Ensure the output filename has a .png extention
+                    if (heightmap.filename.length() > 5)
+                    {
+                        const char* ext = heightmap.filename.c_str() + (heightmap.filename.length() - 4);
+                        if (ext[0] != '.' || tolower(ext[1]) != 'p' || tolower(ext[2]) != 'n' || tolower(ext[3]) != 'g')
+                            heightmap.filename += ".png";
+                    }
+                    else
+                        heightmap.filename += ".png";
                 }
                 }
                 else
                 else
                 {
                 {
-                    fprintf(stderr, "Error: missing argument for -heightmaps.\n");
+                    LOG(1, "Error: missing argument for -h|-heightmap.\n");
+                    _parseError = true;
+                    return;
                 }
                 }
             }
             }
         }
         }
@@ -372,7 +416,7 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
         }
         }
         else
         else
         {
         {
-            fprintf(stderr, "Error: missing arguemnt for -%c.\n", str[1]);
+            LOG(1, "Error: missing arguemnt for -%c.\n", str[1]);
             _parseError = true;
             _parseError = true;
             return;
             return;
         }
         }
@@ -380,6 +424,16 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
     case 't':
     case 't':
         _textOutput = true;
         _textOutput = true;
         break;
         break;
+    case 'v':
+        (*index)++;
+        if (*index < options.size())
+        {
+            __logVerbosity = atoi(options[*index].c_str());
+            if (__logVerbosity < 0)
+                __logVerbosity = 0;
+            else if (__logVerbosity > 4)
+                __logVerbosity = 4;
+        }
     default:
     default:
         break;
         break;
     }
     }

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

@@ -20,6 +20,13 @@ public:
         FILEFORMAT_GPB
         FILEFORMAT_GPB
     };
     };
 
 
+    struct HeightmapOption
+    {
+        std::vector<std::string> nodeIds;
+        std::string filename;
+        bool isHighPrecision;
+    };
+
     /**
     /**
      * Constructor.
      * Constructor.
      */
      */
@@ -73,12 +80,7 @@ public:
     bool containsGroupNodeId(const std::string& nodeId) const;
     bool containsGroupNodeId(const std::string& nodeId) const;
     const std::string getAnimationId(const std::string& nodeId) const;
     const std::string getAnimationId(const std::string& nodeId) const;
 
 
-    const std::vector<std::string>& getHeightmapNodeIds() const;
-    
-    /**
-     * Returns true if the heightmap is to be high precision (24-bit packed).
-     */
-    bool isHeightmapHighP() const;
+    const std::vector<HeightmapOption>& getHeightmapOptions() const;
 
 
     /**
     /**
      * Returns true if an error occurred while parsing the command line arguments.
      * Returns true if an error occurred while parsing the command line arguments.
@@ -100,6 +102,7 @@ public:
     bool fontPreviewEnabled() const;
     bool fontPreviewEnabled() const;
     bool textOutputEnabled() const;
     bool textOutputEnabled() const;
     bool DAEOutputEnabled() const;
     bool DAEOutputEnabled() const;
+    bool optimizeAnimationsEnabled() const;
 
 
     const char* getNodeId() const;
     const char* getNodeId() const;
     unsigned int getFontSize() const;
     unsigned int getFontSize() const;
@@ -144,11 +147,11 @@ private:
     bool _fontPreview;
     bool _fontPreview;
     bool _textOutput;
     bool _textOutput;
     bool _daeOutput;
     bool _daeOutput;
-    bool _isHeightmapHighP;
+    bool _optimizeAnimations;
 
 
     std::vector<std::string> _groupAnimationNodeId;
     std::vector<std::string> _groupAnimationNodeId;
     std::vector<std::string> _groupAnimationAnimationId;
     std::vector<std::string> _groupAnimationAnimationId;
-    std::vector<std::string> _heightmapNodeIds;
+    std::vector<HeightmapOption> _heightmaps;
 
 
 };
 };
 
 

+ 321 - 159
gameplay-encoder/src/FBXSceneEncoder.cpp

@@ -30,11 +30,14 @@ static float getFieldOfView(FbxCamera* fbxCamera);
  * Loads the texture coordinates from given mesh's polygon part into the vertex.
  * Loads the texture coordinates from given mesh's polygon part into the vertex.
  * 
  * 
  * @param fbxMesh The mesh to get the polygon from.
  * @param fbxMesh The mesh to get the polygon from.
- * @param polyIndex The index of the polygon.
- * @param posInPoly The position in the polygon.
+ * @param uvs The UV list to load tex coords from.
+ * @param uvSetIndex The UV set index of the uvs.
+ * @param polyIndex The index of the polygon in the mesh.
+ * @param posInPoly The position of the vertex in the polygon.
+ * @param meshVertexIndex The index of the vertex in the mesh.
  * @param vertex The vertex to copy the texture coordinates to.
  * @param vertex The vertex to copy the texture coordinates to.
  */
  */
-static void loadTextureCoords(FbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex);
+static void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex);
 
 
 /**
 /**
  * Loads the normal from the mesh and adds it to the given vertex.
  * Loads the normal from the mesh and adds it to the given vertex.
@@ -118,14 +121,17 @@ static void copyMatrix(const FbxMatrix& fbxMatrix, Matrix& matrix);
 static void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate);
 static void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime, float* frameRate);
 
 
 /**
 /**
- * Appends a key frame of the given node's transform at the given time.
+ * Appends key frame data to the given node for the specified animation target attribute.
  * 
  * 
  * @param fbxNode The node to get the matrix transform from.
  * @param fbxNode The node to get the matrix transform from.
- * @param time The key time to add and the time to get the transform from.
- * @param keyTimes The list of key times to append to.
- * @param keyValues The list of key values to append to.
+ * @param channel The aniamtion channel to write values into.
+ * @param time The time of the keyframe.
+ * @param scale The evaluated scale for the keyframe.
+ * @param rotation The evalulated rotation for the keyframe.
+ * @param translation The evalulated translation for the keyframe.
+
  */
  */
-static void appendKeyFrame(FbxNode* fbxNode, float time, std::vector<float>* keyTimes, std::vector<float>* keyValues);
+static void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation);
 
 
 /**
 /**
  * Decomposes the given node's matrix transform at the given time and copies to scale, rotation and translation.
  * Decomposes the given node's matrix transform at the given time and copies to scale, rotation and translation.
@@ -196,8 +202,8 @@ void FBXSceneEncoder::write(const std::string& filepath, const EncoderArguments&
     
     
     if (!importer->Initialize(filepath.c_str(), -1, sdkManager->GetIOSettings()))
     if (!importer->Initialize(filepath.c_str(), -1, sdkManager->GetIOSettings()))
     {
     {
-        printf("Call to FbxImporter::Initialize() failed.\n");
-        printf("Error returned: %s\n\n", importer->GetLastErrorString());
+        LOG(1, "Call to FbxImporter::Initialize() failed.\n");
+        LOG(1, "Error returned: %s\n\n", importer->GetLastErrorString());
         exit(-1);
         exit(-1);
     }
     }
     
     
@@ -238,19 +244,19 @@ void FBXSceneEncoder::write(const std::string& filepath, const EncoderArguments&
         {
         {
             std::string path = outputFilePath.substr(0, pos);
             std::string path = outputFilePath.substr(0, pos);
             path.append(".xml");
             path.append(".xml");
-            fprintf(stderr, "Saving debug file: %s\n", path.c_str());
+            LOG(1, "Saving debug file: %s\n", path.c_str());
             if (!_gamePlayFile.saveText(path))
             if (!_gamePlayFile.saveText(path))
             {
             {
-                fprintf(stderr,"Error writing text file: %s\n", path.c_str());
+                LOG(1, "Error writing text file: %s\n", path.c_str());
             }
             }
         }
         }
     }
     }
     else
     else
     {
     {
-        fprintf(stderr, "Saving binary file: %s\n", outputFilePath.c_str());
+        LOG(1, "Saving binary file: %s\n", outputFilePath.c_str());
         if (!_gamePlayFile.saveBinary(outputFilePath))
         if (!_gamePlayFile.saveBinary(outputFilePath))
         {
         {
-            fprintf(stderr,"Error writing binary file: %s\n", outputFilePath.c_str());
+            LOG(1, "Error writing binary file: %s\n", outputFilePath.c_str());
         }
         }
     }
     }
 }
 }
@@ -302,14 +308,8 @@ void FBXSceneEncoder::loadScene(FbxScene* fbxScene)
 
 
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 {
 {
-    const std::string* targetId = NULL;
-
     const char* name = fbxNode->GetName();
     const char* name = fbxNode->GetName();
     Node* node = _gamePlayFile.getNode(name);
     Node* node = _gamePlayFile.getNode(name);
-    if (node)
-    {
-        targetId = &node->getId();
-    }
     
     
     // Determine which properties are animated on this node
     // Determine which properties are animated on this node
     // Find the transform at each key frame
     // Find the transform at each key frame
@@ -374,78 +374,142 @@ void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fb
         findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
         findMinMaxTime(animCurve, &startTime, &stopTime, &frameRate);
     }
     }
 
 
-    bool translate = tx | ty | tz;
-    bool scale = sx | sy | sz;
-    bool rotate = rx | ry | rz;
+    if (!(sx || sy || sz || rx || ry || rz || tx || ty || tz))
+        return; // no animation channels
 
 
-    if (translate || rotate || scale)
-    {
-        assert(startTime != FLT_MAX);
-        assert(stopTime >= 0.0f);
-        AnimationChannel* channel = new AnimationChannel();
-        channel->setTargetId(name);
-        channel->setTargetAttribute(Transform::ANIMATE_SCALE_ROTATE_TRANSLATE);
-        
-        float increment = 1000.0f / frameRate;
-        std::vector<float> keyTimes;
-        std::vector<float> keyValues;
-        for (float time = startTime; time < stopTime; time += increment)
-        {
-            appendKeyFrame(fbxNode, time, &keyTimes, &keyValues);
-        }
-        // Add the last key frame at exactly stopTime
-        appendKeyFrame(fbxNode, stopTime, &keyTimes, &keyValues);
+    assert(startTime != FLT_MAX);
+    assert(stopTime >= 0.0f);
 
 
-        channel->setKeyTimes(keyTimes);
-        /*
-        std::vector<float> newKeyValues;
-        for (size_t i = 0, size = keyValues.size(); i < size; i += 10)
+    // Determine which animation channels to create
+    std::vector<unsigned int> channelAttribs;
+    if (sx && sy && sz)
+    {
+        if (rx || ry || rz)
         {
         {
-            if (translate)
+            if (tx && ty && tz)
             {
             {
-                newKeyValues.push_back(keyValues[i+0]);
-                newKeyValues.push_back(keyValues[i+1]);
-                newKeyValues.push_back(keyValues[i+2]);
+                channelAttribs.push_back(Transform::ANIMATE_SCALE_ROTATE_TRANSLATE);
             }
             }
-            if (rotate)
-            {
-                newKeyValues.push_back(keyValues[i+3]);
-                newKeyValues.push_back(keyValues[i+4]);
-                newKeyValues.push_back(keyValues[i+5]);
-                newKeyValues.push_back(keyValues[i+6]);
-            }
-            if (scale)
+            else
             {
             {
-                newKeyValues.push_back(keyValues[i+7]);
-                newKeyValues.push_back(keyValues[i+8]);
-                newKeyValues.push_back(keyValues[i+9]);
+                channelAttribs.push_back(Transform::ANIMATE_SCALE_ROTATE);
+                if (tx)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_X);
+                if (ty)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Y);
+                if (tz)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Z);
             }
             }
         }
         }
-        channel->setKeyValues(newKeyValues);
-        */
-        channel->setKeyValues(keyValues);
-        channel->setInterpolation(AnimationChannel::LINEAR);
-        animation->add(channel);
-        /*
-        if (!translate)
+        else
         {
         {
-            addTranslateChannel(animation, fbxNode, startTime, stopTime);
+            if (tx && ty && tz)
+            {
+                channelAttribs.push_back(Transform::ANIMATE_SCALE_TRANSLATE);
+            }
+            else
+            {
+                channelAttribs.push_back(Transform::ANIMATE_SCALE);
+                if (tx)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_X);
+                if (ty)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Y);
+                if (tz)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Z);
+            }
         }
         }
-        if (!rotate)
+    }
+    else
+    {
+        if (rx || ry || rz)
         {
         {
-            printf("rotate?\n"); // TODO
+            if (tx && ty && tz)
+            {
+                channelAttribs.push_back(Transform::ANIMATE_ROTATE_TRANSLATE);
+            }
+            else
+            {
+                channelAttribs.push_back(Transform::ANIMATE_ROTATE);
+                if (tx)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_X);
+                if (ty)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Y);
+                if (tz)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Z);
+            }
         }
         }
-        if (!scale)
+        else
         {
         {
-            addScaleChannel(animation, fbxNode, startTime, stopTime);
+            if (tx && ty && tz)
+            {
+                channelAttribs.push_back(Transform::ANIMATE_TRANSLATE);
+            }
+            else
+            {
+                if (tx)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_X);
+                if (ty)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Y);
+                if (tz)
+                    channelAttribs.push_back(Transform::ANIMATE_TRANSLATE_Z);
+            }
         }
         }
-        */
-        if (_groupAnimation != animation)
+
+        if (sx)
+            channelAttribs.push_back(Transform::ANIMATE_SCALE_X);
+        if (sy)
+            channelAttribs.push_back(Transform::ANIMATE_SCALE_Y);
+        if (sz)
+            channelAttribs.push_back(Transform::ANIMATE_SCALE_Z);
+    }
+    unsigned int channelCount = channelAttribs.size();
+    assert(channelCount > 0);
+
+    // Allocate channel list
+    for (unsigned int i = 0; i < channelCount; ++i)
+    {
+        AnimationChannel* channel = new AnimationChannel();
+        channel->setTargetId(name);
+        channel->setInterpolation(AnimationChannel::LINEAR);
+        channel->setTargetAttribute(channelAttribs[i]);
+        animation->add(channel);
+    }
+
+    // Evaulate animation curve in increments of frameRate and populate channel data.
+    FbxAMatrix fbxMatrix;
+    Matrix matrix;
+    float increment = 1000.0f / frameRate;
+    for (float time = startTime; time <= stopTime; time += increment)
+    {
+        // Clamp time to stopTime
+        time = std::min(time, stopTime);
+
+        // Evalulate the animation at this time
+        FbxTime kTime;
+        kTime.SetMilliSeconds((FbxLongLong)time);
+        fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
+        copyMatrix(fbxMatrix, matrix);
+
+        // Decompose the evalulated transformation matrix into separate
+        // scale, rotation and translation.
+        Vector3 scale;
+        Quaternion rotation;
+        Vector3 translation;
+        matrix.decompose(&scale, &rotation, &translation);
+        rotation.normalize();
+
+        // Append keyframe data to all channels
+        for (unsigned int i = 0; i < channelCount; ++i)
         {
         {
-            // TODO explains
-            _gamePlayFile.addAnimation(animation);
+            appendKeyFrame(fbxNode, animation->getAnimationChannel(i), time, scale, rotation, translation);
         }
         }
     }
     }
+
+    if (_groupAnimation != animation)
+    {
+        // TODO explain
+        _gamePlayFile.addAnimation(animation);
+    }
 }
 }
 
 
 void FBXSceneEncoder::loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fbxNode, const EncoderArguments& arguments)
 void FBXSceneEncoder::loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fbxNode, const EncoderArguments& arguments)
@@ -573,7 +637,7 @@ void FBXSceneEncoder::saveMesh(FbxUInt64 meshId, Mesh* mesh)
 
 
 void FBXSceneEncoder::print(const char* str)
 void FBXSceneEncoder::print(const char* str)
 {
 {
-    fprintf(stderr,"%s\n", str);
+    LOG(1, "%s\n", str);
 }
 }
 
 
 void FBXSceneEncoder::transformNode(FbxNode* fbxNode, Node* node)
 void FBXSceneEncoder::transformNode(FbxNode* fbxNode, Node* node)
@@ -656,7 +720,7 @@ void FBXSceneEncoder::loadCamera(FbxNode* fbxNode, Node* node)
     }
     }
     else
     else
     {
     {
-        warning("Unknown camera type in node");
+        LOG(2, "Warning: Unknown camera type in node.\n");
         return;
         return;
     }
     }
     _gamePlayFile.addCamera(camera);
     _gamePlayFile.addCamera(camera);
@@ -740,7 +804,7 @@ void FBXSceneEncoder::loadLight(FbxNode* fbxNode, Node* node)
     }
     }
     default:
     default:
     {
     {
-        warning("Unknown light type in node.");
+        LOG(2, "Warning: Unknown light type in node.\n");
         return;
         return;
     }
     }
     }
     }
@@ -851,6 +915,11 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
     std::vector<std::vector<Vector2> > weights;
     std::vector<std::vector<Vector2> > weights;
     bool hasSkin = loadBlendWeights(fbxMesh, weights);
     bool hasSkin = loadBlendWeights(fbxMesh, weights);
     
     
+    // Get list of uv sets for mesh
+    FbxStringList uvSetNameList;
+    fbxMesh->GetUVSetNames(uvSetNameList);
+    const int uvSetCount = uvSetNameList.GetCount();
+
     int vertexIndex = 0;
     int vertexIndex = 0;
     FbxVector4* controlPoints = fbxMesh->GetControlPoints();
     FbxVector4* controlPoints = fbxMesh->GetControlPoints();
     const int polygonCount = fbxMesh->GetPolygonCount();
     const int polygonCount = fbxMesh->GetPolygonCount();
@@ -867,7 +936,15 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
             vertex.position.y = (float)position[1];
             vertex.position.y = (float)position[1];
             vertex.position.z = (float)position[2];
             vertex.position.z = (float)position[2];
 
 
-            loadTextureCoords(fbxMesh, polyIndex, posInPoly, &vertex);
+            // Load tex coords for all uv sets
+            for (int uvSetIndex = 0; uvSetIndex < uvSetCount; ++uvSetIndex)
+            {
+                const FbxGeometryElementUV* uvElement = fbxMesh->GetElementUV(uvSetNameList.GetStringAt(uvSetIndex));
+                if (uvElement)
+                    loadTextureCoords(fbxMesh, uvElement, uvSetIndex, polyIndex, posInPoly, vertexIndex, &vertex);
+            }
+
+            // Load other data
             loadNormal(fbxMesh, vertexIndex, controlPointIndex, &vertex);
             loadNormal(fbxMesh, vertexIndex, controlPointIndex, &vertex);
             loadTangent(fbxMesh, vertexIndex, &vertex);
             loadTangent(fbxMesh, vertexIndex, &vertex);
             loadBinormal(fbxMesh, vertexIndex, &vertex);
             loadBinormal(fbxMesh, vertexIndex, &vertex);
@@ -931,9 +1008,12 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
         mesh->addVetexAttribute(BINORMAL, Vertex::BINORMAL_COUNT);
     }
     }
     // Texture Coordinates
     // Texture Coordinates
-    if (vertex.hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
     {
-        mesh->addVetexAttribute(TEXCOORD0, Vertex::TEXCOORD_COUNT);
+        if (vertex.hasTexCoord[i])
+        {
+            mesh->addVetexAttribute(TEXCOORD0 + i, Vertex::TEXCOORD_COUNT);
+        }
     }
     }
     // Diffuse Color
     // Diffuse Color
     if (vertex.hasDiffuse)
     if (vertex.hasDiffuse)
@@ -976,16 +1056,6 @@ void FBXSceneEncoder::triangulateRecursive(FbxNode* fbxNode)
     }
     }
 }
 }
 
 
-void FBXSceneEncoder::warning(const std::string& message)
-{
-    printf("Warning: %s\n", message.c_str());
-}
-
-void FBXSceneEncoder::warning(const char* message)
-{
-    printf("Warning: %s\n", message);
-}
-
 ////////////////////////////////////
 ////////////////////////////////////
 // Functions
 // Functions
 ////////////////////////////////////
 ////////////////////////////////////
@@ -1061,54 +1131,46 @@ float getFieldOfView(FbxCamera* fbxCamera)
     return (float)fieldOfViewY;
     return (float)fieldOfViewY;
 }
 }
 
 
-void loadTextureCoords(FbxMesh* fbxMesh, int polyIndex, int posInPoly, Vertex* vertex)
+void loadTextureCoords(FbxMesh* fbxMesh, const FbxGeometryElementUV* uvs, int uvSetIndex, int polyIndex, int posInPoly, int meshVertexIndex, Vertex* vertex)
 {
 {
     assert(fbxMesh && polyIndex >=0 && posInPoly >= 0);
     assert(fbxMesh && polyIndex >=0 && posInPoly >= 0);
-    if (fbxMesh->GetElementUVCount() > 0)
+
+    const bool useIndex = uvs->GetReferenceMode() != FbxGeometryElement::eDirect;
+    const int indexCount = useIndex ? uvs->GetIndexArray().GetCount() : 0;
+    int uvIndex = -1;
+
+    switch (uvs->GetMappingMode())
     {
     {
-        // Get only the first UV coordinates.
-        FbxGeometryElementUV* uv = fbxMesh->GetElementUV(0);
-        switch (uv->GetMappingMode())
+    case FbxGeometryElement::eByControlPoint:
         {
         {
-        case FbxGeometryElement::eByControlPoint:
-            switch (uv->GetReferenceMode())
-            {
-            case FbxGeometryElement::eDirect:
-                vertex->hasTexCoord = true;
-                vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(polyIndex)[0];
-                vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(polyIndex)[1];
-                break;
-            case FbxGeometryElement::eIndexToDirect:
-                {
-                    int id = uv->GetIndexArray().GetAt(polyIndex);
-                    vertex->hasTexCoord = true;
-                    vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(id)[0];
-                    vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(id)[1];
-                }
-                break;
-            default:
-                break;
-            }
-            break;
-        case FbxGeometryElement::eByPolygonVertex:
-            {
-                int lTextureUVIndex = fbxMesh->GetTextureUVIndex(polyIndex, posInPoly);
-                switch (uv->GetReferenceMode())
-                {
-                case FbxGeometryElement::eDirect:
-                case FbxGeometryElement::eIndexToDirect:
-                    vertex->hasTexCoord = true;
-                    vertex->texCoord.x = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[0];
-                    vertex->texCoord.y = (float)uv->GetDirectArray().GetAt(lTextureUVIndex)[1];
-                    break;
-                default:
-                    break;
-                }
-            }
-            break;
-        default:
-            break;
+            // Get the index of the current vertex in control points array
+            int polyVertIndex = fbxMesh->GetPolygonVertex(polyIndex, posInPoly);
+
+            // The UV index depends on the reference mode
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(polyVertIndex) : polyVertIndex;
         }
         }
+        break;
+
+    case FbxGeometryElement::eByPolygonVertex:
+        if (meshVertexIndex < indexCount)
+        {
+            uvIndex = useIndex ? uvs->GetIndexArray().GetAt(meshVertexIndex) : meshVertexIndex;
+        }
+        break;
+
+    default:
+        // Only support eByPolygonVertex and eByControlPoint mappings
+        break;
+    }
+
+    vertex->hasTexCoord[uvSetIndex] = true;
+
+    // Store UV information in vertex
+    if (uvIndex != -1)
+    {
+        FbxVector2 uvValue = uvs->GetDirectArray().GetAt(uvIndex);
+        vertex->texCoord[uvSetIndex].x = (float)uvValue[0];
+        vertex->texCoord[uvSetIndex].y = (float)uvValue[1];
     }
     }
 }
 }
 
 
@@ -1376,32 +1438,132 @@ void findMinMaxTime(FbxAnimCurve* animCurve, float* startTime, float* stopTime,
     *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(FbxTime::eDefaultMode));
     *frameRate = std::max(*frameRate, (float)stop.GetFrameRate(FbxTime::eDefaultMode));
 }
 }
 
 
-void appendKeyFrame(FbxNode* fbxNode, float time, std::vector<float>* keyTimes, std::vector<float>* keyValues)
+void appendKeyFrame(FbxNode* fbxNode, AnimationChannel* channel, float time, const Vector3& scale, const Quaternion& rotation, const Vector3& translation)
 {
 {
-    FbxAMatrix fbxMatrix;
-    Matrix matrix;
-    FbxTime kTime;
-    kTime.SetMilliSeconds((FbxLongLong)time);
-    fbxMatrix = fbxNode->EvaluateLocalTransform(kTime);
-    copyMatrix(fbxMatrix, matrix);
+    // Write key time
+    channel->getKeyTimes().push_back(time);
 
 
-    Vector3 scale;
-    Quaternion rotation;
-    Vector3 translation;
-    matrix.decompose(&scale, &rotation, &translation);
-    rotation.normalize();
-
-    keyTimes->push_back(time);
-    keyValues->push_back(scale.x);
-    keyValues->push_back(scale.y);
-    keyValues->push_back(scale.z);
-    keyValues->push_back(rotation.x);
-    keyValues->push_back(rotation.y);
-    keyValues->push_back(rotation.z);
-    keyValues->push_back(rotation.w);
-    keyValues->push_back(translation.x);
-    keyValues->push_back(translation.y);
-    keyValues->push_back(translation.z);
+    // Write key values
+    std::vector<float>& keyValues = channel->getKeyValues();
+    switch (channel->getTargetAttribute())
+    {
+        case Transform::ANIMATE_SCALE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_X:
+        {
+            keyValues.push_back(scale.x);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_Y:
+        {
+            keyValues.push_back(scale.y);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_Z:
+        {
+            keyValues.push_back(scale.z);
+        }
+        break;
+
+        case Transform::ANIMATE_ROTATE:
+        {
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE:
+        {
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_X:
+        {
+            keyValues.push_back(translation.x);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_Y:
+        {
+            keyValues.push_back(translation.y);
+        }
+        break;
+
+        case Transform::ANIMATE_TRANSLATE_Z:
+        {
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_ROTATE_TRANSLATE:
+        {
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_TRANSLATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(translation.x);
+            keyValues.push_back(translation.y);
+            keyValues.push_back(translation.z);
+        }
+        break;
+
+        case Transform::ANIMATE_SCALE_ROTATE:
+        {
+            keyValues.push_back(scale.x);
+            keyValues.push_back(scale.y);
+            keyValues.push_back(scale.z);
+            keyValues.push_back(rotation.x);
+            keyValues.push_back(rotation.y);
+            keyValues.push_back(rotation.z);
+            keyValues.push_back(rotation.w);
+        }
+        break;
+
+        default:
+        {
+            LOG(1, "Warning: Invalid animatoin target (%d) attribute for node: %s.\n", channel->getTargetAttribute(), fbxNode->GetName());
+        }
+        return;
+    }
 }
 }
 
 
 void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
 void decompose(FbxNode* fbxNode, float time, Vector3* scale, Quaternion* rotation, Vector3* translation)
@@ -1547,4 +1709,4 @@ bool isGroupAnimationPossible(FbxMesh* fbxMesh)
     return false;
     return false;
 }
 }
 
 
-#endif
+#endif

+ 1 - 11
gameplay-encoder/src/FBXSceneEncoder.h

@@ -192,16 +192,6 @@ private:
      */
      */
     static void triangulateRecursive(FbxNode* fbxNode);
     static void triangulateRecursive(FbxNode* fbxNode);
 
 
-    /**
-     * Prints a warning message.
-     */
-    static void warning(const std::string& message);
-
-    /**
-     * Prints a warning message.
-     */
-    static void warning(const char* message);
-
 private:
 private:
 
 
     /**
     /**
@@ -226,4 +216,4 @@ private:
 };
 };
 
 
 #endif
 #endif
-#endif
+#endif

+ 2 - 0
gameplay-encoder/src/FileIO.h

@@ -4,6 +4,8 @@
 #include <cstdio>
 #include <cstdio>
 #include <list>
 #include <list>
 #include <vector>
 #include <vector>
+#include <cstring>
+#include <string>
 
 
 #include "Vector2.h"
 #include "Vector2.h"
 #include "Vector3.h"
 #include "Vector3.h"

+ 103 - 34
gameplay-encoder/src/GPBFile.cpp

@@ -2,6 +2,8 @@
 #include "GPBFile.h"
 #include "GPBFile.h"
 #include "Transform.h"
 #include "Transform.h"
 #include "StringUtil.h"
 #include "StringUtil.h"
+#include "EncoderArguments.h"
+#include "Heightmap.h"
 
 
 #define EPSILON 1.2e-7f;
 #define EPSILON 1.2e-7f;
 
 
@@ -15,6 +17,11 @@ static GPBFile* __instance = NULL;
  */
  */
 static bool isAlmostOne(float value);
 static bool isAlmostOne(float value);
 
 
+/**
+ * Returns true if the given value is close to zero.
+ */
+static bool isAlmostZero(float value);
+
 /**
 /**
  * Gets the common node ancestor for the given list of nodes.
  * Gets the common node ancestor for the given list of nodes.
  * This function assumes that the nodes share a common ancestor.
  * This function assumes that the nodes share a common ancestor.
@@ -60,7 +67,7 @@ bool GPBFile::saveBinary(const std::string& filepath)
     size_t n = 0;
     size_t n = 0;
 
 
     // identifier
     // identifier
-    char identifier[] = { '«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n' };
+    char identifier[] = { '�', 'G', 'P', 'B', '�', '\r', '\n', '\x1A', '\n' };
     n = fwrite(identifier, 1, sizeof(identifier), _file);
     n = fwrite(identifier, 1, sizeof(identifier), _file);
     if (n != sizeof(identifier))
     if (n != sizeof(identifier))
     {
     {
@@ -308,8 +315,11 @@ void GPBFile::adjust()
         computeBounds(*i);
         computeBounds(*i);
     }
     }
 
 
-    // try to convert joint transform animations into rotation animations
-    //optimizeTransformAnimations();
+    if (EncoderArguments::getInstance()->optimizeAnimationsEnabled())
+    {
+        LOG(1, "Optimizing animations.\n");
+        optimizeAnimations();
+    }
 
 
     // TODO:
     // TODO:
     // remove ambient _lights
     // remove ambient _lights
@@ -323,6 +333,13 @@ void GPBFile::adjust()
     //   Search for animations that have the same target and key times and see if they can be merged.
     //   Search for animations that have the same target and key times and see if they can be merged.
     //   Blender will output a simple translation animation to 3 separate animations with the same key times but targeting X, Y and Z.
     //   Blender will output a simple translation animation to 3 separate animations with the same key times but targeting X, Y and Z.
     //   This can be merged into one animation. Same for scale animations.
     //   This can be merged into one animation. Same for scale animations.
+
+    // Generate heightmaps
+    const std::vector<EncoderArguments::HeightmapOption>& heightmaps = EncoderArguments::getInstance()->getHeightmapOptions();
+    for (unsigned int i = 0, count = heightmaps.size(); i < count; ++i)
+    {
+        Heightmap::generate(heightmaps[i].nodeIds, heightmaps[i].filename.c_str(), heightmaps[i].isHighPrecision);
+    }
 }
 }
 
 
 void GPBFile::groupMeshSkinAnimations()
 void GPBFile::groupMeshSkinAnimations()
@@ -376,27 +393,31 @@ void GPBFile::computeBounds(Node* node)
     }
     }
 }
 }
 
 
-void GPBFile::optimizeTransformAnimations()
+void GPBFile::optimizeAnimations()
 {
 {
     const unsigned int animationCount = _animations.getAnimationCount();
     const unsigned int animationCount = _animations.getAnimationCount();
     for (unsigned int animationIndex = 0; animationIndex < animationCount; ++animationIndex)
     for (unsigned int animationIndex = 0; animationIndex < animationCount; ++animationIndex)
     {
     {
         Animation* animation = _animations.getAnimation(animationIndex);
         Animation* animation = _animations.getAnimation(animationIndex);
         assert(animation);
         assert(animation);
+
         const int channelCount = animation->getAnimationChannelCount();
         const int channelCount = animation->getAnimationChannelCount();
+
+        LOG(2, "Optimizing %d channel(s) in animation '%s'.\n", channelCount, animation->getId().c_str());
+
         // loop backwards because we will be adding and removing channels
         // loop backwards because we will be adding and removing channels
         for (int channelIndex = channelCount -1; channelIndex >= 0 ; --channelIndex)
         for (int channelIndex = channelCount -1; channelIndex >= 0 ; --channelIndex)
         {
         {
             AnimationChannel* channel = animation->getAnimationChannel(channelIndex);
             AnimationChannel* channel = animation->getAnimationChannel(channelIndex);
             assert(channel);
             assert(channel);
-            // get target node
+
+            // Optimize node animation channels
             const Object* obj = _refTable.get(channel->getTargetId());
             const Object* obj = _refTable.get(channel->getTargetId());
             if (obj && obj->getTypeId() == Object::NODE_ID)
             if (obj && obj->getTypeId() == Object::NODE_ID)
             {
             {
-                const Node* node = static_cast<const Node*>(obj);
-                if (node->isJoint() && channel->getTargetAttribute() == Transform::ANIMATE_SCALE_ROTATE_TRANSLATE)
+                if (channel->getTargetAttribute() == Transform::ANIMATE_SCALE_ROTATE_TRANSLATE)
                 {
                 {
-                    decomposeTransformAnimationChannel(animation, channel);
+                    decomposeTransformAnimationChannel(animation, channel, channelIndex);
 
 
                     animation->remove(channel);
                     animation->remove(channel);
                     SAFE_DELETE(channel);
                     SAFE_DELETE(channel);
@@ -406,9 +427,10 @@ void GPBFile::optimizeTransformAnimations()
     }
     }
 }
 }
 
 
-
-void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const AnimationChannel* channel)
+void GPBFile::decomposeTransformAnimationChannel(Animation* animation, AnimationChannel* channel, int channelIndex)
 {
 {
+    LOG(2, "  Optimizing animaton channel %s:%d.\n", animation->getId().c_str(), channelIndex+1);
+
     const std::vector<float>& keyTimes = channel->getKeyTimes();
     const std::vector<float>& keyTimes = channel->getKeyTimes();
     const std::vector<float>& keyValues = channel->getKeyValues();
     const std::vector<float>& keyValues = channel->getKeyValues();
     const size_t keyTimesSize = keyTimes.size();
     const size_t keyTimesSize = keyTimes.size();
@@ -417,7 +439,7 @@ void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const Ani
     std::vector<float> scaleKeyValues;
     std::vector<float> scaleKeyValues;
     std::vector<float> rotateKeyValues;
     std::vector<float> rotateKeyValues;
     std::vector<float> translateKeyValues;
     std::vector<float> translateKeyValues;
-                    
+
     scaleKeyValues.reserve(keyTimesSize * 3);
     scaleKeyValues.reserve(keyTimesSize * 3);
     rotateKeyValues.reserve(keyTimesSize * 4);
     rotateKeyValues.reserve(keyTimesSize * 4);
     translateKeyValues.reserve(keyTimesSize * 3);
     translateKeyValues.reserve(keyTimesSize * 3);
@@ -442,8 +464,13 @@ void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const Ani
 
 
     // Don't add the scale channel if all the key values are close to 1.0
     // Don't add the scale channel if all the key values are close to 1.0
     size_t oneCount = (size_t)std::count_if(scaleKeyValues.begin(), scaleKeyValues.end(), isAlmostOne);
     size_t oneCount = (size_t)std::count_if(scaleKeyValues.begin(), scaleKeyValues.end(), isAlmostOne);
-    if (scaleKeyValues.size() != oneCount)
+    if (scaleKeyValues.size() == oneCount)
+    {
+        LOG(2, "    Discarding scale channel.\n");
+    }
+    else
     {
     {
+        LOG(3, "    Keeping scale channel.\n");
         AnimationChannel* scaleChannel = new AnimationChannel();
         AnimationChannel* scaleChannel = new AnimationChannel();
         scaleChannel->setTargetId(channel->getTargetId());
         scaleChannel->setTargetId(channel->getTargetId());
         scaleChannel->setKeyTimes(channel->getKeyTimes());
         scaleChannel->setKeyTimes(channel->getKeyTimes());
@@ -456,27 +483,64 @@ void GPBFile::decomposeTransformAnimationChannel(Animation* animation, const Ani
         animation->add(scaleChannel);
         animation->add(scaleChannel);
     }
     }
 
 
-    AnimationChannel* rotateChannel = new AnimationChannel();
-    rotateChannel->setTargetId(channel->getTargetId());
-    rotateChannel->setKeyTimes(channel->getKeyTimes());
-    rotateChannel->setTangentsIn(channel->getTangentsIn());
-    rotateChannel->setTangentsOut(channel->getTangentsOut());
-    rotateChannel->setInterpolations(channel->getInterpolationTypes());
-    rotateChannel->setTargetAttribute(Transform::ANIMATE_ROTATE);
-    rotateChannel->setKeyValues(rotateKeyValues);
-    rotateChannel->removeDuplicates();
-    animation->add(rotateChannel);
-
-    AnimationChannel* translateChannel = new AnimationChannel();
-    translateChannel->setTargetId(channel->getTargetId());
-    translateChannel->setKeyTimes(channel->getKeyTimes());
-    translateChannel->setTangentsIn(channel->getTangentsIn());
-    translateChannel->setTangentsOut(channel->getTangentsOut());
-    translateChannel->setInterpolations(channel->getInterpolationTypes());
-    translateChannel->setTargetAttribute(Transform::ANIMATE_TRANSLATE);
-    translateChannel->setKeyValues(translateKeyValues);
-    translateChannel->removeDuplicates();
-    animation->add(translateChannel);
+    // Don't add the rotation channel if all quaternions are close to identity
+    oneCount = 0;
+    for (unsigned int i = 0, count = rotateKeyValues.size(); i < count; i += 4)
+    {
+        float x = rotateKeyValues[i];
+        float y = rotateKeyValues[i+1];
+        float z = rotateKeyValues[i+2];
+        float w = rotateKeyValues[i+3];
+        if (ISZERO(x) && ISZERO(y) && ISZERO(z) && ISONE(w))
+            ++oneCount;
+        else
+        {
+            LOG(4, "Rotation not identity: %u\n", i);
+            Quaternion q(x, y, z, w);
+            Vector3 axis;
+            float angle = q.toAxisAngle(&axis);
+            angle = 0;
+        }
+    }
+    if ((rotateKeyValues.size()>>2) == oneCount)
+    {
+        LOG(2, "    Discarding rotation channel.\n");
+    }
+    else
+    {
+        LOG(3, "    Keeping rotation channel.\n");
+        AnimationChannel* rotateChannel = new AnimationChannel();
+        rotateChannel->setTargetId(channel->getTargetId());
+        rotateChannel->setKeyTimes(channel->getKeyTimes());
+        rotateChannel->setTangentsIn(channel->getTangentsIn());
+        rotateChannel->setTangentsOut(channel->getTangentsOut());
+        rotateChannel->setInterpolations(channel->getInterpolationTypes());
+        rotateChannel->setTargetAttribute(Transform::ANIMATE_ROTATE);
+        rotateChannel->setKeyValues(rotateKeyValues);
+        rotateChannel->removeDuplicates();
+        animation->add(rotateChannel);
+    }
+
+    // Don't add the translation channel if all values are close to zero
+    oneCount = (size_t)std::count_if(translateKeyValues.begin(), translateKeyValues.end(), isAlmostZero);
+    if (translateKeyValues.size() == oneCount)
+    {
+        LOG(2, "    Discarding translation channel.\n");
+    }
+    else
+    {
+        LOG(3, "    Keeping translation channel.\n");
+        AnimationChannel* translateChannel = new AnimationChannel();
+        translateChannel->setTargetId(channel->getTargetId());
+        translateChannel->setKeyTimes(channel->getKeyTimes());
+        translateChannel->setTangentsIn(channel->getTangentsIn());
+        translateChannel->setTangentsOut(channel->getTangentsOut());
+        translateChannel->setInterpolations(channel->getInterpolationTypes());
+        translateChannel->setTargetAttribute(Transform::ANIMATE_TRANSLATE);
+        translateChannel->setKeyValues(translateKeyValues);
+        translateChannel->removeDuplicates();
+        animation->add(translateChannel);
+    }
 }
 }
 
 
 void GPBFile::moveAnimationChannels(Node* node, Animation* dstAnimation)
 void GPBFile::moveAnimationChannels(Node* node, Animation* dstAnimation)
@@ -509,7 +573,12 @@ void GPBFile::moveAnimationChannels(Node* node, Animation* dstAnimation)
 
 
 bool isAlmostOne(float value)
 bool isAlmostOne(float value)
 {
 {
-    return std::fabs(value - 1.0f) < EPSILON;
+    return (value - 1.0f) < EPSILON;
+}
+
+bool isAlmostZero(float value)
+{
+    return std::fabs(value) < EPSILON;
 }
 }
 
 
 Node* getCommonNodeAncestor(const std::vector<Node*>& nodes)
 Node* getCommonNodeAncestor(const std::vector<Node*>& nodes)

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

@@ -116,19 +116,25 @@ public:
     void renameAnimations(std::vector<std::string>& animationIds, const char* newId);
     void renameAnimations(std::vector<std::string>& animationIds, const char* newId);
 
 
 private:
 private:
+
     /**
     /**
      * Computes the bounds of all meshes in the node hierarchy.
      * Computes the bounds of all meshes in the node hierarchy.
      */
      */
     void computeBounds(Node* node);
     void computeBounds(Node* node);
-    void optimizeTransformAnimations();
+
+    /**
+     * Optimizes animation data by removing unneccessary channels and keyframes.
+     */
+    void optimizeAnimations();
 
 
     /**
     /**
      * Decomposes an ANIMATE_SCALE_ROTATE_TRANSLATE channel into 3 new channels. (Scale, Rotate and Translate)
      * Decomposes an ANIMATE_SCALE_ROTATE_TRANSLATE channel into 3 new channels. (Scale, Rotate and Translate)
      * 
      * 
      * @param animation The animation that the channel belongs to.
      * @param animation The animation that the channel belongs to.
      * @param channel The animation channel to decompose.
      * @param channel The animation channel to decompose.
+     * @param channelIndex Index of the channel.
      */
      */
-    void decomposeTransformAnimationChannel(Animation* animation, const AnimationChannel* channel);
+    void decomposeTransformAnimationChannel(Animation* animation, AnimationChannel* channel, int channelIndex);
 
 
     /**
     /**
      * Moves the animation channels that target the given node and its children to be under the given animation.
      * Moves the animation channels that target the given node and its children to be under the given animation.

+ 533 - 0
gameplay-encoder/src/Heightmap.cpp

@@ -0,0 +1,533 @@
+#include "Heightmap.h"
+#include "GPBFile.h"
+#include "Thread.h"
+
+namespace gameplay
+{
+
+// Number of threads to spawn for the heightmap generator
+#define THREAD_COUNT 8
+
+// Thread data structure
+struct HeightmapThreadData
+{
+    float rayHeight;                    // [in]
+    const Vector3* rayDirection;        // [in]
+    const std::vector<Mesh*>* meshes;   // [in]
+    const BoundingVolume* bounds;       // [in]
+    int minX;                           // [in]
+    int maxX;                           // [in]
+    int minZ;                           // [in]
+    int maxZ;                           // [in]
+    float minHeight;                    // [out]
+    float maxHeight;                    // [out]
+    float* heights;                     // [in][out]
+    int heightIndex;                    // [in]
+};
+
+// Globals used by thread
+int __processedHeightmapScanLines = 0;
+int __totalHeightmapScanlines = 0;
+int __failedRayCasts = 0;
+
+// Forward declarations
+int generateHeightmapChunk(void* threadData);
+bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const Vector3& boxMin, const Vector3& boxMax, float* distance = NULL);
+int intersect_triangle(const float orig[3], const float dir[3], const float vert0[3], const float vert1[3], const float vert2[3], float *t, float *u, float *v);
+bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const std::vector<Vertex>& vertices, const std::vector<MeshPart*>& parts, Vector3* point);
+
+void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* filename, bool highP)
+{
+    LOG(1, "Generating heightmap: %s...\n", filename);
+
+    // Initialize state variables
+    __processedHeightmapScanLines = 0;
+    __totalHeightmapScanlines = 0;
+    __failedRayCasts = 0;
+
+    GPBFile* gpbFile = GPBFile::getInstance();
+
+    // Lookup nodes in GPB file and compute a single bounding volume that encapsulates all meshes
+    // to be included in the heightmap generation.
+    BoundingVolume bounds;
+    bounds.min.set(FLT_MAX, FLT_MAX, FLT_MAX);
+    bounds.max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+    std::vector<Mesh*> meshes;
+    for (unsigned int j = 0, ncount = nodeIds.size(); j < ncount; ++j)
+    {
+        Node* node = gpbFile->getNode(nodeIds[j].c_str());
+        if (node)
+        {
+            Mesh* mesh = node->getModel() ? node->getModel()->getMesh() : NULL;
+            if (mesh)
+            {
+                // Add this mesh and update our bounding volume
+                if (meshes.size() == 0)
+                    bounds = mesh->bounds;
+                else
+                    bounds.merge(mesh->bounds);
+
+                meshes.push_back(mesh);
+            }
+            else
+            {
+                LOG(1, "WARNING: Node passed to heightmap argument does not have a mesh: %s\n", nodeIds[j].c_str());
+            }
+        }
+        else
+        {
+            LOG(1, "WARNING: Failed to locate node for heightmap argument: %s\n", nodeIds[j].c_str());
+        }
+    }
+
+    if (meshes.size() == 0)
+    {
+        LOG(1, "WARNING: Skipping generation of heightmap '%s'. No nodes found.\n", filename);
+        return;
+    }
+
+    // Shoot rays down from a point just above the max Y position of the mesh.
+    // Compute ray-triangle intersection tests against the ray and this mesh to 
+    // generate heightmap data.
+    Vector3 rayOrigin(0, bounds.max.y + 10, 0);
+    Vector3 rayDirection(0, -1, 0);
+
+    int minX = (int)ceil(bounds.min.x);
+    int maxX = (int)floor(bounds.max.x);
+    int minZ = (int)ceil(bounds.min.z);
+    int maxZ = (int)floor(bounds.max.z);
+    int width = maxX - minX + 1;
+    int height = maxZ - minZ + 1;
+    int size = width * height;
+    float* heights = new float[size];
+    float minHeight = FLT_MAX;
+    float maxHeight = -FLT_MAX;
+
+    __totalHeightmapScanlines = height;
+
+    // Split the work into separate threads to make max use of available cpu cores and speed up computation.
+    HeightmapThreadData threadData[THREAD_COUNT];
+    THREAD_HANDLE threads[THREAD_COUNT];
+    int stepSize = height / THREAD_COUNT;
+    for (int i = 0; i < THREAD_COUNT; ++i)
+    {
+        HeightmapThreadData& data = threadData[i];
+        data.rayHeight = rayOrigin.y;
+        data.rayDirection = &rayDirection;
+        data.bounds = &bounds;
+        data.meshes = &meshes;
+        data.minX = minX;
+        data.maxX = maxX;
+        data.minZ = minZ + (stepSize * i);
+        data.maxZ = data.minZ + stepSize - 1;
+        if (i == THREAD_COUNT - 1)
+            data.maxZ = maxZ;
+        data.heights = heights;
+        data.heightIndex = width * (stepSize * i);
+
+        // Start the processing thread
+        if (!createThread(&threads[i], &generateHeightmapChunk, &data))
+        {
+            LOG(1, "ERROR: Failed to spawn worker thread for generation of heightmap: %s\n", filename);
+            return;
+        }
+    }
+
+    // Wait for all threads to terminate
+    waitForThreads(THREAD_COUNT, threads);
+
+    // Close all thread handles and free memory allocations.
+    for (int i = 0; i < THREAD_COUNT; ++i)
+        closeThread(threads[i]);
+
+    // Update min/max height from all completed threads
+    for (int i = 0; i < THREAD_COUNT; ++i)
+    {
+        if (threadData[i].minHeight < minHeight)
+            minHeight = threadData[i].minHeight;
+        if (threadData[i].maxHeight > maxHeight)
+            maxHeight = threadData[i].maxHeight;
+    }
+
+    LOG(1, "\r\tDone.\n");
+
+    if (__failedRayCasts)
+    {
+        LOG(1, "Warning: %d triangle intersections failed for heightmap: %s\n", __failedRayCasts, filename);
+
+        // Go through and clamp any height values that are set to -FLT_MAX to the min recorded height value
+        // (otherwise the range of height values will be far too large).
+        for (int i = 0; i < size; ++i)
+        {
+            if (heights[i] == -FLT_MAX)
+                heights[i] = minHeight;
+        }
+    }
+    
+    // Normalize the max height value
+    maxHeight = maxHeight - minHeight;
+
+    png_structp png_ptr = NULL;
+    png_infop info_ptr = NULL;
+    png_bytep row = NULL;
+
+    FILE* fp = fopen(filename, "wb");
+    if (fp == NULL)
+    {
+        LOG(1, "Error: Failed to open file for writing: %s\n", filename);
+        goto error;
+    }
+
+    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (png_ptr == NULL)
+    {
+        LOG(1, "Error: Write struct creation failed: %s\n", filename);
+        goto error;
+    }
+
+    info_ptr = png_create_info_struct(png_ptr);
+    if (info_ptr == NULL)
+    {
+        LOG(1, "Error: Info struct creation failed: %s\n", filename);
+        goto error;
+    }
+
+    png_init_io(png_ptr, fp);
+
+    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+    png_write_info(png_ptr, info_ptr);
+
+    // Allocate memory for a single row of image data
+    row = (png_bytep)malloc(3 * width * sizeof(png_byte));
+
+    for (int y = 0; y < height; y++)
+    {
+        for (int x = 0; x < width; x++)
+        {
+            // Write height value normalized between 0-255 (between min and max height)
+            float h = heights[y*width + x];
+            float nh = (h - minHeight) / maxHeight;
+            int pos = x*3;
+            if (highP)
+            {
+                // high precision packed 24-bit (RGB)
+                int bits = (int)(nh * 16777215.0f); // 2^24-1
+                
+                row[pos+2] = (png_byte)(bits & 0xff);
+                bits >>= 8;
+                row[pos+1] = (png_byte)(bits & 0xff);
+                bits >>= 8;
+                row[pos] = (png_byte)(bits & 0xff);
+            }
+            else
+            {
+                // standard precision 8-bit (grayscale)
+                png_byte b = (png_byte)(nh * 255.0f);
+                row[pos] = row[pos+1] = row[pos+2] = b;
+            }
+        }
+        png_write_row(png_ptr, row);
+    }
+
+    png_write_end(png_ptr, NULL);
+    LOG(1, "Saved heightmap: %s\n", filename);
+
+error:
+    if (heights)
+        delete[] heights;
+    if (fp)
+        fclose(fp);
+    if (row)
+        free(row);
+    if (info_ptr)
+        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+    if (png_ptr)
+        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+}
+
+int generateHeightmapChunk(void* threadData)
+{
+    HeightmapThreadData* data = (HeightmapThreadData*)threadData;
+
+    Vector3 rayOrigin(0, data->rayHeight, 0);
+    const Vector3& rayDirection = *data->rayDirection;
+    int minX = data->minX;
+    int maxX = data->maxX;
+    int minZ = data->minZ;
+    int maxZ = data->maxZ;
+    const std::vector<Mesh*>& meshes = *data->meshes;
+    float* heights = data->heights;
+
+    Vector3 intersectionPoint;
+    float minHeight = FLT_MAX;
+    float maxHeight = -FLT_MAX;
+    int index = data->heightIndex;
+
+    for (int z = minZ; z <= maxZ; ++z)
+    {
+        LOG(1, "\r\t%d%%", (int)(((float)__processedHeightmapScanLines / __totalHeightmapScanlines) * 100.0f));
+
+        rayOrigin.z = (float)z;
+        for (int x = minX; x <= maxX; ++x)
+        {
+            float h = -FLT_MAX;
+            rayOrigin.x = (float)x;
+
+            for (unsigned int i = 0, count = meshes.size(); i < count; ++i)
+            {
+                // Pick the highest intersecting Y value of all meshes
+                Mesh* mesh = meshes[i];
+
+                // Perform a quick ray/bounding box test to quick-out
+                if (!intersect(rayOrigin, rayDirection, mesh->bounds.min, mesh->bounds.max))
+                    continue;
+
+                // Computer intersection point of ray with mesh
+                if (intersect(rayOrigin, rayDirection, mesh->vertices, mesh->parts, &intersectionPoint))
+                {
+                    if (intersectionPoint.y > h)
+                    {
+                        h = intersectionPoint.y;
+
+                        // Update min/max height values
+                        if (h < minHeight)
+                            minHeight = h;
+                        if (h > maxHeight)
+                            maxHeight = h;
+                    }
+                }
+            }
+
+            // Update the glboal height array
+            heights[index++] = h;
+
+            if (h == -FLT_MAX)
+                ++__failedRayCasts;
+        }
+
+        ++__processedHeightmapScanLines;
+    }
+
+    // Update min/max height for this thread data
+    data->minHeight = minHeight;
+    data->maxHeight = maxHeight;
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////
+// 
+// Fast, Minimum Storage Ray-Triangle Intersection
+// 
+// Authors: Tomas Möller, Ben Trumbore
+// http://jgt.akpeters.com/papers/MollerTrumbore97
+//
+// Implementation of algorithm from Real-Time Rendering (vol 1), pg. 305.
+//
+// Adapted slightly for use here.
+// 
+#ifndef EPSILON
+#define EPSILON 0.000001
+#endif
+#define CROSS(dest,v1,v2) \
+          dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
+          dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
+          dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
+#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
+#define SUB(dest,v1,v2) \
+          dest[0]=v1[0]-v2[0]; \
+          dest[1]=v1[1]-v2[1]; \
+          dest[2]=v1[2]-v2[2]; 
+int intersect_triangle(const float orig[3], const float dir[3], const float vert0[3], const float vert1[3], const float vert2[3], float *t, float *u, float *v)
+{
+   float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
+   float det,inv_det;
+
+   /* find vectors for two edges sharing vert0 */
+   SUB(edge1, vert1, vert0);
+   SUB(edge2, vert2, vert0);
+
+   /* begin calculating determinant - also used to calculate U parameter */
+   CROSS(pvec, dir, edge2);
+
+   /* if determinant is near zero, ray lies in plane of triangle */
+   det = DOT(edge1, pvec);
+
+   if (det > -EPSILON && det < EPSILON)
+     return 0;
+   inv_det = 1.0f / det;
+
+   /* calculate distance from vert0 to ray origin */
+   SUB(tvec, orig, vert0);
+
+   /* calculate U parameter and test bounds */
+   *u = DOT(tvec, pvec) * inv_det;
+   if (*u < 0.0 || *u > 1.0)
+     return 0;
+
+   /* prepare to test V parameter */
+   CROSS(qvec, tvec, edge1);
+
+   /* calculate V parameter and test bounds */
+   *v = DOT(dir, qvec) * inv_det;
+   if (*v < 0.0 || *u + *v > 1.0)
+     return 0;
+
+   /* calculate t, ray intersects triangle */
+   *t = DOT(edge2, qvec) * inv_det;
+
+   return 1;
+}
+
+// Performs an intersection test between a ray and the given mesh part and stores the result in "point".
+bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const std::vector<Vertex>& vertices, const std::vector<MeshPart*>& parts, Vector3* point)
+{
+    const float* orig = &rayOrigin.x;
+    const float* dir = &rayDirection.x;
+
+    float minT = FLT_MAX;
+
+    for (unsigned int i = 0, partCount = parts.size(); i < partCount; ++i)
+    {
+        MeshPart* part = parts[i];
+
+        for (unsigned int j = 0, indexCount = part->getIndicesCount(); j < indexCount; j += 3)
+        {
+            const float* v0 = &vertices[part->getIndex( j )].position.x;
+            const float* v1 = &vertices[part->getIndex(j+1)].position.x;
+            const float* v2 = &vertices[part->getIndex(j+2)].position.x;
+
+            // Perform a quick check (in 2D) to determine if the point is definitely NOT in the triangle
+            float xmin, xmax, zmin, zmax;
+            xmin = v0[0] < v1[0] ? v0[0] : v1[0]; xmin = xmin < v2[0] ? xmin : v2[0];
+            xmax = v0[0] > v1[0] ? v0[0] : v1[0]; xmax = xmax > v2[0] ? xmax : v2[0];
+            zmin = v0[2] < v1[2] ? v0[2] : v1[2]; zmin = zmin < v2[2] ? zmin : v2[2];
+            zmax = v0[2] > v1[2] ? v0[2] : v1[2]; zmax = zmax > v2[2] ? zmax : v2[2];
+            if (orig[0] < xmin || orig[0] > xmax || orig[2] < zmin || orig[2] > zmax)
+                continue;
+
+            // Perform a full ray/traingle intersection test in 3D to get the intersection point
+            float t, u, v;
+            if (intersect_triangle(orig, dir, v0, v1, v2, &t, &u, &v))
+            {
+                // Found an intersection!
+                if (t < minT)
+                {
+                    minT = t;
+
+                    if (point)
+                    {
+                        Vector3 rd(rayDirection);
+                        rd.scale(t);
+                        Vector3::add(rayOrigin, rd, point);
+                    }
+                }
+                //return true;
+            }
+        }
+    }
+
+    return (minT != FLT_MAX);//false;
+}
+
+// Ray/Box intersection test.
+bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const Vector3& boxMin, const Vector3& boxMax, float* distance)
+{
+    const Vector3& origin = rayOrigin;
+    const Vector3& direction = rayDirection;
+    const Vector3& min = boxMin;
+    const Vector3& max = boxMax;
+
+    // Intermediate calculation variables.
+    float dnear = 0.0f;
+    float dfar = 0.0f;
+    float tmin = 0.0f;
+    float tmax = 0.0f;
+
+    // X direction.
+    float div = 1.0f / direction.x;
+    if (div >= 0.0f)
+    {
+        tmin = (min.x - origin.x) * div;
+        tmax = (max.x - origin.x) * div;
+    }
+    else
+    {
+        tmin = (max.x - origin.x) * div;
+        tmax = (min.x - origin.x) * div;
+    }
+    dnear = tmin;
+    dfar = tmax;
+
+    // Check if the ray misses the box.
+    if (dnear > dfar || dfar < 0.0f)
+    {
+        return false;
+    }
+
+    // Y direction.
+    div = 1.0f / direction.y;
+    if (div >= 0.0f)
+    {
+        tmin = (min.y - origin.y) * div;
+        tmax = (max.y - origin.y) * div;
+    }
+    else
+    {
+        tmin = (max.y - origin.y) * div;
+        tmax = (min.y - origin.y) * div;
+    }
+
+    // Update the near and far intersection distances.
+    if (tmin > dnear)
+    {
+        dnear = tmin;
+    }
+    if (tmax < dfar)
+    {
+        dfar = tmax;
+    }
+    // Check if the ray misses the box.
+    if (dnear > dfar || dfar < 0.0f)
+    {
+        return false;
+    }
+
+    // Z direction.
+    div = 1.0f / direction.z;
+    if (div >= 0.0f)
+    {
+        tmin = (min.z - origin.z) * div;
+        tmax = (max.z - origin.z) * div;
+    }
+    else
+    {
+        tmin = (max.z - origin.z) * div;
+        tmax = (min.z - origin.z) * div;
+    }
+
+    // Update the near and far intersection distances.
+    if (tmin > dnear)
+    {
+        dnear = tmin;
+    }
+    if (tmax < dfar)
+    {
+        dfar = tmax;
+    }
+
+    // Check if the ray misses the box.
+    if (dnear > dfar || dfar < 0.0f)
+    {
+        return false;
+    }
+
+    // The ray intersects the box
+    if (distance)
+        *distance = dnear;
+
+    return true;
+}
+
+}

+ 27 - 0
gameplay-encoder/src/Heightmap.h

@@ -0,0 +1,27 @@
+#ifndef HEIGHTMAP_H_
+#define HEIGHTMAP_H_
+
+#include "Node.h"
+
+namespace gameplay
+{
+
+class Heightmap
+{
+public:
+
+    /**
+     * Generates heightmap data and saves the result to the specified filename (PNG file).
+     *
+     * @param nodeIds List of node ids to include in the heightmap generation.
+     * @param filename Output PNG file to write the heightmap image to.
+     * @param highP Use packed 24-bit (RGB) instead of standard 8-bit grayscale.
+     */
+    static void generate(const std::vector<std::string>& nodeIds, const char* filename, bool highP = false);
+
+
+};
+
+}
+
+#endif

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

@@ -224,7 +224,7 @@ void Light::setFalloffExponent(float value)
     _falloffExponent = value;
     _falloffExponent = value;
     if ( value != 1.0)
     if ( value != 1.0)
     {
     {
-        printf("Warning: spot light falloff_exponent must be 1.0. \n");
+        LOG(1, "Warning: spot light falloff_exponent must be 1.0. \n");
     }
     }
 }
 }
 
 

+ 4 - 228
gameplay-encoder/src/Mesh.cpp

@@ -28,7 +28,7 @@ void Mesh::writeBinary(FILE* file)
     Object::writeBinary(file);
     Object::writeBinary(file);
     // vertex formats
     // vertex formats
     write(_vertexFormat.size(), file);
     write(_vertexFormat.size(), file);
-    for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
+    for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); ++i)
     {
     {
         i->writeBinary(file);
         i->writeBinary(file);
     }
     }
@@ -38,232 +38,6 @@ void Mesh::writeBinary(FILE* file)
     writeBinaryObjects(parts, file);
     writeBinaryObjects(parts, file);
 }
 }
 
 
-/////////////////////////////////////////////////////////////
-// 
-// Fast, Minimum Storage Ray-Triangle Intersection
-// 
-// Authors: Tomas Möller, Ben Trumbore
-// http://jgt.akpeters.com/papers/MollerTrumbore97
-//
-// Implementation of algorithm from Real-Time Rendering (vol 1), pg. 305.
-//
-// Adapted slightly for use here.
-// 
-#define EPSILON 0.000001
-#define CROSS(dest,v1,v2) \
-          dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
-          dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
-          dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
-#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
-#define SUB(dest,v1,v2) \
-          dest[0]=v1[0]-v2[0]; \
-          dest[1]=v1[1]-v2[1]; \
-          dest[2]=v1[2]-v2[2]; 
-
-int
-intersect_triangle(const float orig[3], const float dir[3],
-                   const float vert0[3], const float vert1[3], const float vert2[3],
-                   float *t, float *u, float *v)
-{
-   float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
-   float det,inv_det;
-
-   /* find vectors for two edges sharing vert0 */
-   SUB(edge1, vert1, vert0);
-   SUB(edge2, vert2, vert0);
-
-   /* begin calculating determinant - also used to calculate U parameter */
-   CROSS(pvec, dir, edge2);
-
-   /* if determinant is near zero, ray lies in plane of triangle */
-   det = DOT(edge1, pvec);
-
-   if (det > -EPSILON && det < EPSILON)
-     return 0;
-   inv_det = 1.0f / det;
-
-   /* calculate distance from vert0 to ray origin */
-   SUB(tvec, orig, vert0);
-
-   /* calculate U parameter and test bounds */
-   *u = DOT(tvec, pvec) * inv_det;
-   if (*u < 0.0 || *u > 1.0)
-     return 0;
-
-   /* prepare to test V parameter */
-   CROSS(qvec, tvec, edge1);
-
-   /* calculate V parameter and test bounds */
-   *v = DOT(dir, qvec) * inv_det;
-   if (*v < 0.0 || *u + *v > 1.0)
-     return 0;
-
-   /* calculate t, ray intersects triangle */
-   *t = DOT(edge2, qvec) * inv_det;
-
-   return 1;
-}
-
-// Performs an intersection test between a ray and the given mesh part
-// and stores the result in "point".
-bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const std::vector<Vertex>& vertices, const std::vector<MeshPart*>& parts, Vector3* point)
-{
-    const float* orig = &rayOrigin.x;
-    const float* dir = &rayDirection.x;
-
-    for (unsigned int i = 0, partCount = parts.size(); i < partCount; ++i)
-    {
-        MeshPart* part = parts[i];
-
-        for (unsigned int j = 0, indexCount = part->getIndicesCount(); j < indexCount; j += 3)
-        {
-            const float* v0 = &vertices[part->getIndex( j )].position.x;
-            const float* v1 = &vertices[part->getIndex(j+1)].position.x;
-            const float* v2 = &vertices[part->getIndex(j+2)].position.x;
-
-            float t, u, v;
-            if (intersect_triangle(orig, dir, v0, v1, v2, &t, &u, &v))
-            {
-                // Found an intersection!
-                if (point)
-                {
-                    Vector3 rd(rayDirection);
-                    rd.scale(t);
-                    Vector3::add(rayOrigin, rd, point);
-                }
-                return true;
-            }
-        }
-    }
-
-    return false;
-}
-
-void Mesh::generateHeightmap(const char* filename, bool highP)
-{
-    // Shoot rays down from a point just above the max Y position of the mesh.
-    // Compute ray-triangle intersection tests against the ray and this mesh to 
-    // generate heightmap data.
-    Vector3 rayOrigin(0, bounds.max.y + 10, 0);
-    Vector3 rayDirection(0, -1, 0);
-    Vector3 intersectionPoint;
-    int minX = (int)ceil(bounds.min.x);
-    int maxX = (int)floor(bounds.max.x);
-    int minZ = (int)ceil(bounds.min.z);
-    int maxZ = (int)floor(bounds.max.z);
-    int width = maxX - minX + 1;
-    int height = maxZ - minZ + 1;
-    float* heights = new float[width * height];
-    int index = 0;
-    float minHeight = FLT_MAX;
-    float maxHeight = -FLT_MAX;
-    for (int z = minZ; z <= maxZ; z++)
-    {
-        rayOrigin.z = (float)z;
-        for (int x = minX; x <= maxX; x++)
-        {
-            float h;
-            rayOrigin.x = (float)x;
-            if (intersect(rayOrigin, rayDirection, vertices, parts, &intersectionPoint))
-            {
-                h = intersectionPoint.y;
-            }
-            else
-            {
-                h = 0;
-                fprintf(stderr, "Warning: Heightmap triangle intersection failed for (%d, %d).\n", x, z);
-            }
-            if (h < minHeight)
-                minHeight = h;
-            if (h > maxHeight)
-                maxHeight = h;
-            heights[index++] = h;
-        }
-    }
-    
-    // Normalize the max height value
-    maxHeight = maxHeight - minHeight;
-
-    png_structp png_ptr = NULL;
-    png_infop info_ptr = NULL;
-    png_bytep row = NULL;
-
-    FILE* fp = fopen(filename, "wb");
-    if (fp == NULL)
-    {
-        fprintf(stderr, "Error: Failed to open file for writing: %s\n", filename);
-        goto error;
-    }
-
-    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-    if (png_ptr == NULL)
-    {
-        fprintf(stderr, "Error: Write struct creation failed: %s\n", filename);
-        goto error;
-    }
-
-    info_ptr = png_create_info_struct(png_ptr);
-    if (info_ptr == NULL)
-    {
-        fprintf(stderr, "Error: Info struct creation failed: %s\n", filename);
-        goto error;
-    }
-
-    png_init_io(png_ptr, fp);
-
-    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-    png_write_info(png_ptr, info_ptr);
-
-    // Allocate memory for a single row of image data
-    row = (png_bytep)malloc(3 * width * sizeof(png_byte));
-
-    for (int y = 0; y < height; y++)
-    {
-        for (int x = 0; x < width; x++)
-        {
-            // Write height value normalized between 0-255 (between min and max height)
-            float h = heights[y*width + x];
-            float nh = (h - minHeight) / maxHeight;
-            int pos = x*3;
-            if (highP)
-            {
-                // high precision packed 24-bit (RGB)
-                int bits = (int)(nh * 16777215.0f); // 2^24-1
-
-                row[pos+2] = (png_byte)(bits & 0xff);
-                bits >>= 8;
-                row[pos+1] = (png_byte)(bits & 0xff);
-                bits >>= 8;
-                row[pos] = (png_byte)(bits & 0xff);
-            }
-            else
-            {
-                // standard precision 8-bit (grayscale)
-                png_byte b = (png_byte)(nh * 255.0f);
-                row[pos] = row[pos+1] = row[pos+2] = b;
-            }
-        }
-        png_write_row(png_ptr, row);
-    }
-
-    png_write_end(png_ptr, NULL);
-    DEBUGPRINT_VARG("> Saved heightmap: %s\n", filename);
-
-error:
-    if (heights)
-        delete[] heights;
-    if (fp)
-        fclose(fp);
-    if (row)
-        free(row);
-    if (info_ptr)
-        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
-    if (png_ptr)
-        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
-
-}
-
 void Mesh::writeBinaryVertices(FILE* file)
 void Mesh::writeBinaryVertices(FILE* file)
 {
 {
     if (vertices.size() > 0)
     if (vertices.size() > 0)
@@ -300,7 +74,7 @@ void Mesh::writeText(FILE* file)
     // for each VertexFormat
     // for each VertexFormat
     if (vertices.size() > 0 )
     if (vertices.size() > 0 )
     {
     {
-        for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
+        for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); ++i)
         {
         {
             i->writeText(file);
             i->writeText(file);
         }
         }
@@ -403,6 +177,8 @@ void Mesh::computeBounds()
         return;
         return;
     }
     }
 
 
+    LOG(2, "Computing bounds for mesh: %s\n", getId().c_str());
+
     bounds.min.x = bounds.min.y = bounds.min.z = FLT_MAX;
     bounds.min.x = bounds.min.y = bounds.min.z = FLT_MAX;
     bounds.max.x = bounds.max.y = bounds.max.z = -FLT_MAX;
     bounds.max.x = bounds.max.y = bounds.max.z = -FLT_MAX;
     bounds.center.x = bounds.center.y = bounds.center.z = 0.0f;
     bounds.center.x = bounds.center.y = bounds.center.z = 0.0f;

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

@@ -60,13 +60,6 @@ public:
 
 
     unsigned int getVertexIndex(const Vertex& vertex);
     unsigned int getVertexIndex(const Vertex& vertex);
 
 
-    /**
-     * Generates a heightmap with the given filename for this mesh.
-     * Optional high precision uses packed 24-bit (RGB) instead of
-     * standard 8-bit grayscale.
-     */
-    void generateHeightmap(const char* filename, bool highP = false);
-
     void computeBounds();
     void computeBounds();
 
 
     Model* model;
     Model* model;

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

@@ -37,12 +37,12 @@ void MeshSkin::writeBinary(FILE* file)
     Object::writeBinary(file);
     Object::writeBinary(file);
     write(_bindShape, 16, file);
     write(_bindShape, 16, file);
     write(_joints.size(), file);
     write(_joints.size(), file);
-    for (std::vector<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); i++)
+    for (std::vector<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); ++i)
     {
     {
         (*i)->writeBinaryXref(file);
         (*i)->writeBinaryXref(file);
     }
     }
     write(_bindPoses.size() * 16, file);
     write(_bindPoses.size() * 16, file);
-    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); ++i)
     {
     {
         write(i->m, 16, file);
         write(i->m, 16, file);
     }
     }
@@ -68,13 +68,13 @@ void MeshSkin::writeText(FILE* file)
     fprintfMatrix4f(file, _bindShape);
     fprintfMatrix4f(file, _bindShape);
     fprintf(file, "</bindShape>");
     fprintf(file, "</bindShape>");
     fprintf(file, "<joints>");
     fprintf(file, "<joints>");
-    for (std::vector<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); ++i)
     {
     {
         fprintf(file, "%s ", i->c_str());
         fprintf(file, "%s ", i->c_str());
     }
     }
     fprintf(file, "</joints>\n");
     fprintf(file, "</joints>\n");
     fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size() * 16);
     fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size() * 16);
-    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); ++i)
     {
     {
         for (unsigned int j = 0; j < 16; ++j)
         for (unsigned int j = 0; j < 16; ++j)
         {
         {
@@ -129,7 +129,7 @@ void MeshSkin::setBindPoses(std::vector<Matrix>& list)
 
 
 bool MeshSkin::hasJoint(const char* id)
 bool MeshSkin::hasJoint(const char* id)
 {
 {
-    for (std::vector<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); ++i)
     {
     {
         if (equals(*i, id))
         if (equals(*i, id))
         {
         {
@@ -163,7 +163,7 @@ void MeshSkin::computeBounds()
         return;
         return;
     }
     }
 
 
-    DEBUGPRINT_VARG("\nComputing bounds for skin of mesh: %s\n", _mesh->getId().c_str());
+    LOG(2, "Computing bounds for skin of mesh: %s\n", _mesh->getId().c_str());
 
 
     Node* joint;
     Node* joint;
 
 
@@ -192,7 +192,7 @@ void MeshSkin::computeBounds()
     unsigned int jointCount = _joints.size();
     unsigned int jointCount = _joints.size();
     unsigned int vertexCount = _mesh->getVertexCount();
     unsigned int vertexCount = _mesh->getVertexCount();
 
 
-    DEBUGPRINT_VARG("> %d joints found.\n", jointCount);
+    LOG(3, "  %u joints found.\n", jointCount);
 
 
     std::vector<AnimationChannel*> channels;
     std::vector<AnimationChannel*> channels;
     std::vector<Node*> channelTargets;
     std::vector<Node*> channelTargets;
@@ -201,8 +201,8 @@ void MeshSkin::computeBounds()
     _jointBounds.resize(jointCount);
     _jointBounds.resize(jointCount);
 
 
     // Construct a list of all animation channels that target the joints affecting this mesh skin
     // Construct a list of all animation channels that target the joints affecting this mesh skin
-    DEBUGPRINT("> Collecting animations...\n");
-    DEBUGPRINT("> 0%%\r");
+    LOG(3, "  Collecting animations...\n");
+    LOG(3, "  0%%\r");
     for (unsigned int i = 0; i < jointCount; ++i)
     for (unsigned int i = 0; i < jointCount; ++i)
     {
     {
         joint = _joints[i];
         joint = _joints[i];
@@ -272,16 +272,16 @@ void MeshSkin::computeBounds()
         }
         }
         _jointBounds[i] = jointBounds;
         _jointBounds[i] = jointBounds;
 
 
-        DEBUGPRINT_VARG("> %d%%\r", (int)((float)(i+1) / (float)jointCount * 100.0f));
+        LOG(3, "  %d%%\r", (int)((float)(i+1) / (float)jointCount * 100.0f));
     }
     }
-    DEBUGPRINT("\n");
+    LOG(3, "\n");
 
 
     unsigned int channelCount = channels.size();
     unsigned int channelCount = channels.size();
 
 
     // Create a Curve for each animation channel
     // Create a Curve for each animation channel
     float maxDuration = 0.0f;
     float maxDuration = 0.0f;
-    DEBUGPRINT("> Building animation curves...\n");
-    DEBUGPRINT("> 0%%\r");
+    LOG(3, "  Building animation curves...\n");
+    LOG(3, "  0%%\r");
     for (unsigned int i = 0; i < channelCount; ++i)
     for (unsigned int i = 0; i < channelCount; ++i)
     {
     {
         AnimationChannel* channel = channels[i];
         AnimationChannel* channel = channels[i];
@@ -340,9 +340,9 @@ void MeshSkin::computeBounds()
         delete[] keyValues;
         delete[] keyValues;
         keyValues = NULL;
         keyValues = NULL;
 
 
-        DEBUGPRINT_VARG("> %d%%\r", (int)((float)(i+1) / (float)channelCount * 100.0f));
+        LOG(3, "  %d%%\r", (int)((float)(i+1) / (float)channelCount * 100.0f));
     }
     }
-    DEBUGPRINT("\n");
+    LOG(3, "\n");
 
 
     // Compute a total combined bounding volume for the MeshSkin that contains all possible
     // Compute a total combined bounding volume for the MeshSkin that contains all possible
     // vertex positions for all animations targeting the skin. This rough approximation allows
     // vertex positions for all animations targeting the skin. This rough approximation allows
@@ -366,8 +366,8 @@ void MeshSkin::computeBounds()
     _mesh->bounds.radius = 0;
     _mesh->bounds.radius = 0;
     Vector3 skinnedPos;
     Vector3 skinnedPos;
     Vector3 tempPos;
     Vector3 tempPos;
-    DEBUGPRINT("> Evaluating joints...\n");
-    DEBUGPRINT("> 0%%\r");
+    LOG(3, "  Evaluating joints...\n");
+    LOG(3, "  0%%\r");
     BoundingVolume finalBounds;
     BoundingVolume finalBounds;
     while (time <= maxDuration)
     while (time <= maxDuration)
     {
     {
@@ -416,9 +416,9 @@ void MeshSkin::computeBounds()
         else
         else
             time += 33.0f;
             time += 33.0f;
 
 
-        DEBUGPRINT_VARG("> %d%%\r", (int)(time / maxDuration * 100.0f));
+        LOG(3, "  %d%%\r", (int)(time / maxDuration * 100.0f));
     }
     }
-    DEBUGPRINT("\n");
+    LOG(3, "\n");
 
 
     // Update the bounding sphere for the mesh
     // Update the bounding sphere for the mesh
     _mesh->bounds = finalBounds;
     _mesh->bounds = finalBounds;

+ 0 - 25
gameplay-encoder/src/Node.cpp

@@ -78,8 +78,6 @@ void Node::writeBinary(FILE* file)
     {
     {
         writeZero(file);
         writeZero(file);
     }
     }
-
-    generateHeightmap();
 }
 }
 
 
 void Node::writeText(FILE* file)
 void Node::writeText(FILE* file)
@@ -117,29 +115,6 @@ void Node::writeText(FILE* file)
         _model->writeText(file);
         _model->writeText(file);
     }
     }
     fprintElementEnd(file);
     fprintElementEnd(file);
-
-    generateHeightmap();
-}
-
-void Node::generateHeightmap()
-{
-    // Is this node flagged to have a heightmap generated for it?
-    const std::vector<std::string>& heightmapNodes = EncoderArguments::getInstance()->getHeightmapNodeIds();
-    if (std::find(heightmapNodes.begin(), heightmapNodes.end(), getId()) != heightmapNodes.end())
-    {
-        Mesh* mesh = _model ? _model->getMesh() : NULL;
-        if (mesh)
-        {
-            DEBUGPRINT_VARG("> Generating heightmap for node: %s\n", getId().c_str());
-
-            std::string heightmapFilename(EncoderArguments::getInstance()->getOutputDirPath());
-            heightmapFilename += "/heightmap_";
-            heightmapFilename += getId();
-            heightmapFilename += ".png";
-
-            mesh->generateHeightmap(heightmapFilename.c_str(), EncoderArguments::getInstance()->isHeightmapHighP());
-        }
-    }
 }
 }
 
 
 void Node::addChild(Node* child)
 void Node::addChild(Node* child)

+ 0 - 6
gameplay-encoder/src/Node.h

@@ -171,12 +171,6 @@ public:
     
     
 private:
 private:
 
 
-    /**
-     * Internal method to generate heightmap for a node's mesh data
-     * if the node was flagged as a heightmap via encoder arguments.
-     */
-    void generateHeightmap();
-
     Matrix _transform;
     Matrix _transform;
     mutable Matrix _worldTransform;
     mutable Matrix _worldTransform;
 
 

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

@@ -2,6 +2,7 @@
 #define OBJ_H_
 #define OBJ_H_
 
 
 #include "FileIO.h"
 #include "FileIO.h"
+#include "Base.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {

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

@@ -52,7 +52,7 @@ bool Quaternion::isIdentity() const
 
 
 bool Quaternion::isZero() const
 bool Quaternion::isZero() const
 {
 {
-    return x == 0.0f && y == 0.0f && z == 0.0f && z == 0.0f;
+    return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
 }
 }
 
 
 void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternion* dst)
 void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternion* dst)
@@ -60,14 +60,14 @@ void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternio
     assert(dst);
     assert(dst);
 
 
     float halfAngle = angle * 0.5f;
     float halfAngle = angle * 0.5f;
-    float sinHalfAngle = sinf(halfAngle);
+    float sinHalfAngle = sin(halfAngle);
 
 
     Vector3 normal(axis);
     Vector3 normal(axis);
     normal.normalize();
     normal.normalize();
     dst->x = normal.x * sinHalfAngle;
     dst->x = normal.x * sinHalfAngle;
     dst->y = normal.y * sinHalfAngle;
     dst->y = normal.y * sinHalfAngle;
     dst->z = normal.z * sinHalfAngle;
     dst->z = normal.z * sinHalfAngle;
-    dst->w = cosf(halfAngle);
+    dst->w = cos(halfAngle);
 }
 }
 
 
 void Quaternion::conjugate()
 void Quaternion::conjugate()

+ 12 - 12
gameplay-encoder/src/TTFFontEncoder.cpp

@@ -43,7 +43,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     FT_Error error = FT_Init_FreeType(&library);
     FT_Error error = FT_Init_FreeType(&library);
     if (error)
     if (error)
     {
     {
-        fprintf(stderr, "FT_Init_FreeType error: %d \n", error);
+        LOG(1, "FT_Init_FreeType error: %d \n", error);
         return -1;
         return -1;
     }
     }
     
     
@@ -52,7 +52,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     error = FT_New_Face(library, inFilePath, 0, &face);
     error = FT_New_Face(library, inFilePath, 0, &face);
     if (error)
     if (error)
     {
     {
-        fprintf(stderr, "FT_New_Face error: %d \n", error);
+        LOG(1, "FT_New_Face error: %d \n", error);
         return -1;
         return -1;
     }
     }
     
     
@@ -66,7 +66,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     
     
     if (error)
     if (error)
     {
     {
-        fprintf(stderr, "FT_Set_Char_Size error: %d \n", error);
+        LOG(1, "FT_Set_Char_Size error: %d \n", error);
         return -1;
         return -1;
     }
     }
 
 
@@ -74,7 +74,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     error = FT_Set_Pixel_Sizes(face, FONT_SIZE, 0);
     error = FT_Set_Pixel_Sizes(face, FONT_SIZE, 0);
     if (error)
     if (error)
     {
     {
-        fprintf(stderr, "FT_Set_Pixel_Sizes error : %d \n", error);
+        LOG(1, "FT_Set_Pixel_Sizes error : %d \n", error);
         exit(1);
         exit(1);
     }
     }
     */
     */
@@ -92,7 +92,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
         error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
         if (error)
         if (error)
         {
         {
-            fprintf(stderr, "FT_Load_Char error : %d \n", error);
+            LOG(1, "FT_Load_Char error : %d \n", error);
         }
         }
         
         
         int bitmapRows = slot->bitmap.rows;
         int bitmapRows = slot->bitmap.rows;
@@ -137,7 +137,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
             error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
             error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
             if (error)
             if (error)
             {
             {
-                fprintf(stderr, "FT_Load_Char error : %d \n", error);
+                LOG(1, "FT_Load_Char error : %d \n", error);
             }
             }
 
 
             // Glyph image.
             // Glyph image.
@@ -204,7 +204,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
         error = FT_Load_Char(face, ascii, FT_LOAD_RENDER);
         if (error)
         if (error)
         {
         {
-            fprintf(stderr, "FT_Load_Char error : %d \n", error);
+            LOG(1, "FT_Load_Char error : %d \n", error);
         }
         }
 
 
         // Glyph image.
         // Glyph image.
@@ -222,10 +222,10 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
             penY = row * rowSize;
             penY = row * rowSize;
             if (penY + rowSize > (int)imageHeight)
             if (penY + rowSize > (int)imageHeight)
             {
             {
-                fprintf(stderr, "Image size exceeded!");
-               return -1;
+                free(imageBuffer);
+				LOG(1, "Image size exceeded!");
+				return -1;
             }
             }
-
         }
         }
         
         
         // penY should include the glyph offsets.
         // penY should include the glyph offsets.
@@ -298,7 +298,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     // Close file.
     // Close file.
     fclose(gpbFp);
     fclose(gpbFp);
 
 
-    printf("%s.gpb created successfully. \n", getBaseName(outFilePath).c_str());
+    LOG(1, "%s.gpb created successfully. \n", getBaseName(outFilePath).c_str());
 
 
     if (fontpreview)
     if (fontpreview)
     {
     {
@@ -306,7 +306,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         pgmFilePath.append(".pgm");
         pgmFilePath.append(".pgm");
         FILE *imageFp = fopen(pgmFilePath.c_str(), "wb");
         FILE *imageFp = fopen(pgmFilePath.c_str(), "wb");
-        fprintf(imageFp, "P5 %d %d 255\n", imageWidth, imageHeight);
+        fprintf(imageFp, "P5 %u %u 255\n", imageWidth, imageHeight);
         fwrite((const char *)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, imageFp);
         fwrite((const char *)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, imageFp);
         fclose(imageFp);
         fclose(imageFp);
     }
     }

+ 99 - 0
gameplay-encoder/src/Thread.h

@@ -0,0 +1,99 @@
+#ifndef THREAD_H_
+#define THREAD_H_
+
+namespace gameplay
+{
+
+#ifdef WIN32
+
+    #include <Windows.h>
+
+    typedef HANDLE THREAD_HANDLE;
+
+    struct WindowsThreadData
+    {
+        int(*threadFunction)(void*);
+        void* arg;
+    };
+
+    DWORD WINAPI WindowsThreadProc(LPVOID lpParam)
+    {
+        WindowsThreadData* data = (WindowsThreadData*)lpParam;
+        int(*threadFunction)(void*) = data->threadFunction;
+        void* arg = data->arg;
+        delete data;
+        data = NULL;
+        return threadFunction(arg);
+    }
+
+    static bool createThread(THREAD_HANDLE* handle, int(*threadFunction)(void*), void* arg)
+    {
+        WindowsThreadData* data = new WindowsThreadData();
+        data->threadFunction = threadFunction;
+        data->arg = arg;
+        *handle = CreateThread(NULL, 0, &WindowsThreadProc, data, 0, NULL);
+        return (*handle != NULL);
+    }
+
+    static void waitForThreads(int count, THREAD_HANDLE* threads)
+    {
+        WaitForMultipleObjects(count, threads, TRUE, INFINITE);
+    }
+
+    static void closeThread(THREAD_HANDLE thread)
+    {
+        CloseHandle(thread);
+    }
+
+#else
+
+    #include <pthread.h>
+
+    typedef pthread_t THREAD_HANDLE;
+
+    struct PThreadData
+    {
+        int(*threadFunction)(void*);
+        void* arg;
+    };
+
+    void* PThreadProc(void* threadData)
+    {
+        PThreadData* data = (PThreadData*)threadData;
+        int(*threadFunction)(void*) = data->threadFunction;
+        void* arg = data->arg;
+        delete data;
+        data = NULL;
+        int retVal = threadFunction(arg);
+        pthread_exit((void*)retVal);
+    }
+
+    static bool createThread(THREAD_HANDLE* handle, int(*threadFunction)(void*), void* arg)
+    {
+        PThreadData* data = new PThreadData();
+        data->threadFunction = threadFunction;
+        data->arg = arg;
+        return pthread_create(handle, NULL, &PThreadProc, data) == 0;
+    }
+
+    static void waitForThreads(int count, THREAD_HANDLE* threads)
+    {
+        // Call join on all threads to wait for them to terminate.
+        // This also frees any resources allocated by the threads,
+        // essentially cleaning them up.
+        for (int i = 0; i < count; ++i)
+        {
+            pthread_join(threads[i], NULL);
+        }
+    }
+
+    static void closeThread(THREAD_HANDLE thread)
+    {
+        // nothing to do... waitForThreads (which calls join) cleans up
+    }
+
+#endif
+
+}
+
+#endif

+ 11 - 32
gameplay-encoder/src/Transform.cpp

@@ -16,12 +16,6 @@ const char* Transform::getPropertyString(unsigned int prop)
             return "ANIMATE_SCALE_Y";
             return "ANIMATE_SCALE_Y";
         case ANIMATE_SCALE_Z:
         case ANIMATE_SCALE_Z:
             return "ANIMATE_SCALE_Z";
             return "ANIMATE_SCALE_Z";
-        case ANIMATE_SCALE_XY: 
-            return "ANIMATE_SCALE_XY";
-        case ANIMATE_SCALE_XZ: 
-            return "ANIMATE_SCALE_XZ";
-        case ANIMATE_SCALE_YZ:
-            return "ANIMATE_SCALE_YZ";
         case ANIMATE_ROTATE:
         case ANIMATE_ROTATE:
             return "ANIMATE_ROTATE";
             return "ANIMATE_ROTATE";
         case ANIMATE_TRANSLATE: 
         case ANIMATE_TRANSLATE: 
@@ -32,22 +26,14 @@ const char* Transform::getPropertyString(unsigned int prop)
             return "ANIMATE_TRANSLATE_Y";
             return "ANIMATE_TRANSLATE_Y";
         case ANIMATE_TRANSLATE_Z: 
         case ANIMATE_TRANSLATE_Z: 
             return "ANIMATE_TRANSLATE_Z";
             return "ANIMATE_TRANSLATE_Z";
-        case ANIMATE_TRANSLATE_XY: 
-            return "ANIMATE_TRANSLATE_XY";
-        case ANIMATE_TRANSLATE_XZ: 
-            return "ANIMATE_TRANSLATE_XZ";
-        case ANIMATE_TRANSLATE_YZ: 
-            return "ANIMATE_TRANSLATE_YZ";
         case ANIMATE_ROTATE_TRANSLATE: 
         case ANIMATE_ROTATE_TRANSLATE: 
             return "ANIMATE_ROTATE_TRANSLATE";
             return "ANIMATE_ROTATE_TRANSLATE";
         case ANIMATE_SCALE_ROTATE_TRANSLATE: 
         case ANIMATE_SCALE_ROTATE_TRANSLATE: 
             return "ANIMATE_SCALE_ROTATE_TRANSLATE";
             return "ANIMATE_SCALE_ROTATE_TRANSLATE";
-        case ANIMATE_ROTATE_X: 
-            return "ANIMATE_ROTATE_X";
-        case ANIMATE_ROTATE_Y: 
-            return "ANIMATE_ROTATE_Y";
-        case ANIMATE_ROTATE_Z: 
-            return "ANIMATE_ROTATE_Z";
+        case ANIMATE_SCALE_TRANSLATE:
+            return "ANIMATE_SCALE_TRANSLATE";
+        case ANIMATE_SCALE_ROTATE:
+            return "ANIMATE_SCALE_ROTATE";
         default:
         default:
             return "";
             return "";
     }
     }
@@ -57,31 +43,24 @@ unsigned int Transform::getPropertySize(unsigned int prop)
 {
 {
     switch (prop)
     switch (prop)
     {
     {
-        case ANIMATE_SCALE_ROTATE_TRANSLATE: 
+        case ANIMATE_SCALE_ROTATE_TRANSLATE:
             return 10;
             return 10;
-        case ANIMATE_ROTATE_TRANSLATE: 
+        case ANIMATE_ROTATE_TRANSLATE:
+        case ANIMATE_SCALE_ROTATE:
             return 7;
             return 7;
+        case ANIMATE_SCALE_TRANSLATE:
+            return 6;
         case ANIMATE_ROTATE:
         case ANIMATE_ROTATE:
             return 4;
             return 4;
         case ANIMATE_SCALE:
         case ANIMATE_SCALE:
-        case ANIMATE_TRANSLATE: 
-            return 3;   
-        case ANIMATE_SCALE_XY: 
-        case ANIMATE_SCALE_XZ: 
-        case ANIMATE_SCALE_YZ:
-        case ANIMATE_TRANSLATE_XY: 
-        case ANIMATE_TRANSLATE_XZ: 
-        case ANIMATE_TRANSLATE_YZ: 
-            return 2;
+        case ANIMATE_TRANSLATE:
+            return 3;
         case ANIMATE_SCALE_X:
         case ANIMATE_SCALE_X:
         case ANIMATE_SCALE_Y:
         case ANIMATE_SCALE_Y:
         case ANIMATE_SCALE_Z:
         case ANIMATE_SCALE_Z:
         case ANIMATE_TRANSLATE_X:
         case ANIMATE_TRANSLATE_X:
         case ANIMATE_TRANSLATE_Y:
         case ANIMATE_TRANSLATE_Y:
         case ANIMATE_TRANSLATE_Z:
         case ANIMATE_TRANSLATE_Z:
-        case ANIMATE_ROTATE_X: 
-        case ANIMATE_ROTATE_Y: 
-        case ANIMATE_ROTATE_Z: 
             return 1;
             return 1;
         default:
         default:
             return 0;
             return 0;

+ 10 - 9
gameplay-encoder/src/Transform.h

@@ -17,9 +17,6 @@ public:
         ANIMATE_SCALE_X = 2,
         ANIMATE_SCALE_X = 2,
         ANIMATE_SCALE_Y = 3,
         ANIMATE_SCALE_Y = 3,
         ANIMATE_SCALE_Z = 4,
         ANIMATE_SCALE_Z = 4,
-        ANIMATE_SCALE_XY = 5,
-        ANIMATE_SCALE_XZ = 6,
-        ANIMATE_SCALE_YZ = 7,
 
 
         /**
         /**
          * Rotation animation property. Data=qx,qy,qz,qw (as quaternion).
          * Rotation animation property. Data=qx,qy,qz,qw (as quaternion).
@@ -33,22 +30,26 @@ public:
         ANIMATE_TRANSLATE_X = 10,
         ANIMATE_TRANSLATE_X = 10,
         ANIMATE_TRANSLATE_Y = 11,
         ANIMATE_TRANSLATE_Y = 11,
         ANIMATE_TRANSLATE_Z = 12,
         ANIMATE_TRANSLATE_Z = 12,
-        ANIMATE_TRANSLATE_XY = 13,
-        ANIMATE_TRANSLATE_XZ = 14,
-        ANIMATE_TRANSLATE_YZ = 15,
 
 
         /**
         /**
          * Rotation + Translation animation property(Rigid Body). Data=qx,qy,qz,qw,tx,ty,tz
          * Rotation + Translation animation property(Rigid Body). Data=qx,qy,qz,qw,tx,ty,tz
          */
          */
         ANIMATE_ROTATE_TRANSLATE = 16,
         ANIMATE_ROTATE_TRANSLATE = 16,
+
         /**
         /**
          * Scale, Rotation + Translation animation property. Data=sx,sy,sz,qx,qy,qz,qw,tx,ty,tz
          * Scale, Rotation + Translation animation property. Data=sx,sy,sz,qx,qy,qz,qw,tx,ty,tz
          */
          */
         ANIMATE_SCALE_ROTATE_TRANSLATE = 17,
         ANIMATE_SCALE_ROTATE_TRANSLATE = 17,
 
 
-        ANIMATE_ROTATE_X = 18,
-        ANIMATE_ROTATE_Y = 19,
-        ANIMATE_ROTATE_Z = 20
+        /**
+         * Scale + Translation animation property. Data=sx,sy,sz,tx,ty,tz
+         */
+        ANIMATE_SCALE_TRANSLATE = 18,
+
+        /**
+         * Scale + Rotation animation property. Data=sx,sy,sz,qx,qy,qz,qw
+         */
+        ANIMATE_SCALE_ROTATE = 19
     };
     };
 
 
     /**
     /**

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

@@ -91,7 +91,7 @@ bool Vector4::isZero() const
 
 
 bool Vector4::isOne() const
 bool Vector4::isOne() const
 {
 {
-    return x == 1.0f && y == 1.0f && z == 1.0f && z == 1.0f;
+    return x == 1.0f && y == 1.0f && z == 1.0f && w == 1.0f;
 }
 }
 
 
 float Vector4::angle(const Vector4& v1, const Vector4& v2)
 float Vector4::angle(const Vector4& v1, const Vector4& v2)

+ 19 - 8
gameplay-encoder/src/Vertex.cpp

@@ -5,8 +5,10 @@ namespace gameplay
 {
 {
 
 
 Vertex::Vertex(void)
 Vertex::Vertex(void)
-    : hasNormal(false), hasTangent(false), hasBinormal(false), hasTexCoord(false), hasDiffuse(false), hasWeights(false)
+    : hasNormal(false), hasTangent(false), hasBinormal(false), hasDiffuse(false), hasWeights(false)
 {
 {
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+        hasTexCoord[i] = false;
 }
 }
 
 
 Vertex::~Vertex(void)
 Vertex::~Vertex(void)
@@ -22,8 +24,11 @@ unsigned int Vertex::byteSize() const
         count += TANGENT_COUNT;
         count += TANGENT_COUNT;
     if (hasBinormal)
     if (hasBinormal)
         count += BINORMAL_COUNT;
         count += BINORMAL_COUNT;
-    if (hasTexCoord)
-        count += TEXCOORD_COUNT;
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+    {
+        if (hasTexCoord[i])
+            count += TEXCOORD_COUNT;
+    }
     if (hasWeights)
     if (hasWeights)
         count += BLEND_WEIGHTS_COUNT + BLEND_INDICES_COUNT;
         count += BLEND_WEIGHTS_COUNT + BLEND_INDICES_COUNT;
     if (hasDiffuse)
     if (hasDiffuse)
@@ -46,9 +51,12 @@ void Vertex::writeBinary(FILE* file) const
     {
     {
         writeVectorBinary(binormal, file);
         writeVectorBinary(binormal, file);
     }
     }
-    if (hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
     {
-        writeVectorBinary(texCoord, file);
+        if (hasTexCoord[i])
+        {
+            writeVectorBinary(texCoord[i], file);
+        }
     }
     }
     if (hasDiffuse)
     if (hasDiffuse)
     {
     {
@@ -80,10 +88,13 @@ void Vertex::writeText(FILE* file) const
         write("// binormal\n", file);
         write("// binormal\n", file);
         writeVectorText(binormal, file);
         writeVectorText(binormal, file);
     }
     }
-    if (hasTexCoord)
+    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
     {
     {
-        write("// texCoord\n", file);
-        writeVectorText(texCoord, file);
+        if (hasTexCoord[i])
+        {
+            write("// texCoord\n", file);
+            writeVectorText(texCoord[i], file);
+        }
     }
     }
     if (hasDiffuse)
     if (hasDiffuse)
     {
     {

+ 21 - 12
gameplay-encoder/src/Vertex.h

@@ -6,6 +6,9 @@
 #include "Vector3.h"
 #include "Vector3.h"
 #include "Vector4.h"
 #include "Vector4.h"
 
 
+// Maximum number of supported UV sets
+#define MAX_UV_SETS 8
+
 namespace gameplay
 namespace gameplay
 {
 {
 
 
@@ -36,13 +39,13 @@ public:
     Vector3 normal;
     Vector3 normal;
     Vector3 tangent;
     Vector3 tangent;
     Vector3 binormal;
     Vector3 binormal;
-    Vector2 texCoord;
+    Vector2 texCoord[MAX_UV_SETS];
     Vector4 diffuse;
     Vector4 diffuse;
 
 
     Vector4 blendWeights;
     Vector4 blendWeights;
     Vector4 blendIndices;
     Vector4 blendIndices;
 
 
-    bool hasNormal, hasTangent, hasBinormal, hasTexCoord, hasDiffuse, hasWeights;
+    bool hasNormal, hasTangent, hasBinormal, hasTexCoord[MAX_UV_SETS], hasDiffuse, hasWeights;
 
 
     inline bool operator<(const Vertex& v) const
     inline bool operator<(const Vertex& v) const
     {
     {
@@ -54,23 +57,24 @@ public:
                 {
                 {
                     if (binormal == v.binormal)
                     if (binormal == v.binormal)
                     {
                     {
-                        if (texCoord == v.texCoord)
+                        if (diffuse == v.diffuse)
                         {
                         {
-                            if (diffuse == v.diffuse)
+                            if (blendWeights == v.blendWeights)
                             {
                             {
-                                if (blendWeights == v.blendWeights)
+                                if (blendIndices == v.blendIndices)
                                 {
                                 {
-                                    if (blendIndices == v.blendIndices)
+                                    for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
                                     {
                                     {
-                                        return false;
+                                        if (!(texCoord[i] == v.texCoord[i]))
+                                            return texCoord[i] < v.texCoord[i];
                                     }
                                     }
-                                    return blendIndices < v.blendIndices;
+                                    return false;
                                 }
                                 }
-                                return blendWeights < v.blendWeights;
+                                return blendIndices < v.blendIndices;
                             }
                             }
-                            return diffuse < v.diffuse;
+                            return blendWeights < v.blendWeights;
                         }
                         }
-                        return texCoord < v.texCoord;
+                        return diffuse < v.diffuse;
                     }
                     }
                     return binormal < v.binormal;
                     return binormal < v.binormal;
                 }
                 }
@@ -83,7 +87,12 @@ public:
 
 
     inline bool operator==(const Vertex& v) const
     inline bool operator==(const Vertex& v) const
     {
     {
-        return position==v.position && normal==v.normal && tangent==v.tangent && binormal==v.binormal && texCoord==v.texCoord &&
+        for (unsigned int i = 0; i < MAX_UV_SETS; ++i)
+        {
+            if (!(texCoord[i] == v.texCoord[i]))
+                return false;
+        }
+        return position==v.position && normal==v.normal && tangent==v.tangent && binormal==v.binormal &&
             diffuse==v.diffuse && blendWeights==v.blendWeights && blendIndices==v.blendIndices;
             diffuse==v.diffuse && blendWeights==v.blendWeights && blendIndices==v.blendIndices;
     }
     }
 
 

+ 4 - 4
gameplay-encoder/src/main.cpp

@@ -56,12 +56,12 @@ int main(int argc, const char** argv)
     // Check if the file exists.
     // Check if the file exists.
     if (!arguments.fileExists())
     if (!arguments.fileExists())
     {
     {
-        fprintf(stderr, "Error: File not found: %s\n", arguments.getFilePathPointer());
+        LOG(1, "Error: File not found: %s\n", arguments.getFilePathPointer());
         return -1;
         return -1;
     }
     }
 
 
     // File exists
     // File exists
-    fprintf(stderr, "Encoding file: %s\n", arguments.getFilePathPointer());
+    LOG(1, "Encoding file: %s\n", arguments.getFilePathPointer());
 
 
     switch (arguments.getFileFormat())
     switch (arguments.getFileFormat())
     {
     {
@@ -80,7 +80,7 @@ int main(int argc, const char** argv)
             fbxEncoder.write(realpath, arguments);
             fbxEncoder.write(realpath, arguments);
             break;
             break;
 #else
 #else
-            fprintf(stderr, "Error: FBX not enabled. Install the FBX SDK and use the preprocessor definition USE_FBX.\n");
+            LOG(1, "Error: FBX not enabled. Install the FBX SDK and use the preprocessor definition USE_FBX.\n");
             return -1;
             return -1;
 #endif
 #endif
         }
         }
@@ -104,7 +104,7 @@ int main(int argc, const char** argv)
         }
         }
    default:
    default:
         {
         {
-            fprintf(stderr, "Error: Unsupported file format: %s\n", arguments.getFilePathPointer());
+            LOG(1, "Error: Unsupported file format: %s\n", arguments.getFilePathPointer());
             return -1;
             return -1;
         }
         }
     }
     }

+ 23 - 15
gameplay-luagen/gameplay-luagen.doxyfile

@@ -1,4 +1,4 @@
-# Doxyfile 1.8.1
+# Doxyfile 1.8.0
 
 
 # This file describes the settings to be used by the documentation system
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
 # doxygen (www.doxygen.org) for a project
@@ -32,7 +32,7 @@ PROJECT_NAME           = gameplay
 # This could be handy for archiving the generated documentation or 
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 # if some version control system is used.
 
 
-PROJECT_NUMBER         = 1.4.0
+PROJECT_NUMBER         = 1.5.0
 
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # for a project that appears at the top of each page and should give viewer 
 # for a project that appears at the top of each page and should give viewer 
@@ -564,6 +564,12 @@ MAX_INITIALIZER_LINES  = 30
 
 
 SHOW_USED_FILES        = NO
 SHOW_USED_FILES        = NO
 
 
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
 # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
 # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
 # This will remove the Files entry from the Quick Index and from the 
 # This will remove the Files entry from the Quick Index and from the 
 # Folder Tree View (if specified). The default is YES.
 # Folder Tree View (if specified). The default is YES.
@@ -948,23 +954,20 @@ HTML_COLORSTYLE_GAMMA  = 80
 
 
 HTML_TIMESTAMP         = YES
 HTML_TIMESTAMP         = YES
 
 
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # documentation will contain sections that can be hidden and shown after the 
 # documentation will contain sections that can be hidden and shown after the 
-# page has loaded.
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
 
 
 HTML_DYNAMIC_SECTIONS  = NO
 HTML_DYNAMIC_SECTIONS  = NO
 
 
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of 
-# entries shown in the various tree structured indices initially; the user 
-# can expand and collapse entries dynamically later on. Doxygen will expand 
-# the tree to such a level that at most the specified number of entries are 
-# visible (unless a fully collapsed tree already exceeds this amount). 
-# So setting the number of entries 1 will produce a full collapsed tree by 
-# default. 0 is a special value representing an infinite number of entries 
-# and will result in a full expanded tree by default.
-
-HTML_INDEX_NUM_ENTRIES = 113
-
 # If the GENERATE_DOCSET tag is set to YES, additional index files 
 # If the GENERATE_DOCSET tag is set to YES, additional index files 
 # will be generated that can be used as input for Apple's Xcode 3 
 # will be generated that can be used as input for Apple's Xcode 3 
 # integrated development environment, introduced with OSX 10.5 (Leopard). 
 # integrated development environment, introduced with OSX 10.5 (Leopard). 
@@ -1143,6 +1146,11 @@ GENERATE_TREEVIEW      = NO
 
 
 ENUM_VALUES_PER_LINE   = 4
 ENUM_VALUES_PER_LINE   = 4
 
 
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
 # used to set the initial width (in pixels) of the frame in which the tree 
 # used to set the initial width (in pixels) of the frame in which the tree 
 # is shown.
 # is shown.
@@ -1705,7 +1713,7 @@ CALLER_GRAPH           = NO
 
 
 GRAPHICAL_HIERARCHY    = YES
 GRAPHICAL_HIERARCHY    = YES
 
 
-# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
 # then doxygen will show the dependencies a directory has on other directories 
 # then doxygen will show the dependencies a directory has on other directories 
 # in a graphical way. The dependency relations are determined by the #include 
 # in a graphical way. The dependency relations are determined by the #include 
 # relations between the files in the directories.
 # relations between the files in the directories.

+ 4 - 2
gameplay-luagen/gameplay-luagen.vcxproj

@@ -57,11 +57,13 @@
     <LinkIncremental>true</LinkIncremental>
     <LinkIncremental>true</LinkIncremental>
     <CustomBuildBeforeTargets>
     <CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
+    <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <LinkIncremental>false</LinkIncremental>
     <CustomBuildBeforeTargets>
     <CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
+    <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
     <ClCompile>
@@ -76,7 +78,7 @@
     <Link>
     <Link>
       <SubSystem>Console</SubSystem>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     </Link>
     <PreBuildEvent>
     <PreBuildEvent>
@@ -108,7 +110,7 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     </Link>
     <PreBuildEvent>
     <PreBuildEvent>

+ 70 - 70
gameplay-newproject.bat

@@ -127,7 +127,7 @@ echo.
 call:replacevar projPath "/" "\"
 call:replacevar projPath "/" "\"
 
 
 REM Does this path already exist?
 REM Does this path already exist?
-if exist %projPath% (
+if exist "%projPath%" (
     echo.
     echo.
     echo ERROR: Path '%projPath%' already exists, aborting.
     echo ERROR: Path '%projPath%' already exists, aborting.
     echo.
     echo.
@@ -151,124 +151,124 @@ REM    rmdir /S /Q %projPath%
 
 
 REM Generate relative path from project folder to GamePlay folder
 REM Generate relative path from project folder to GamePlay folder
 set gpPath=%cd%
 set gpPath=%cd%
-call:makerelative gpPath %projPath%\
+call:makerelative gpPath "%projPath%\"
 call:replacevar gpPath "\" "/"
 call:replacevar gpPath "\" "/"
 
 
-mkdir %projPath%
-mkdir %projPath%\src
-mkdir %projPath%\res
+mkdir "%projPath%"
+mkdir "%projPath%\src"
+mkdir "%projPath%\res"
 
 
 REM Copy Microsoft Visual Studio project files
 REM Copy Microsoft Visual Studio project files
-copy gameplay-template\gameplay-template.vcxproj %projPath%\%projName%.vcxproj
-call:replace %projPath%\%projName%.vcxproj TEMPLATE_PROJECT "%projName%"
-call:replace %projPath%\%projName%.vcxproj TemplateGame "%className%"
-call:replace %projPath%\%projName%.vcxproj GAMEPLAY_PATH "%gpPath%"
+copy gameplay-template\gameplay-template.vcxproj "%projPath%\%projName%.vcxproj"
+call:replace "%projPath%\%projName%.vcxproj" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\%projName%.vcxproj" TemplateGame "%className%"
+call:replace "%projPath%\%projName%.vcxproj" GAMEPLAY_PATH "%gpPath%"
 
 
-copy gameplay-template\gameplay-template.vcxproj.filters %projPath%\%projName%.vcxproj.filters
-call:replace %projPath%\%projName%.vcxproj.filters TemplateGame "%className%"
+copy gameplay-template\gameplay-template.vcxproj.filters "%projPath%\%projName%.vcxproj.filters"
+call:replace "%projPath%\%projName%.vcxproj.filters" TemplateGame "%className%"
 
 
-copy gameplay-template\gameplay-template.vcxproj.user %projPath%\%projName%.vcxproj.user
-call:replace %projPath%\%projName%.vcxproj.user GAMEPLAY_PATH "%gpPath%"
+copy gameplay-template\gameplay-template.vcxproj.user "%projPath%\%projName%.vcxproj.user"
+call:replace "%projPath%\%projName%.vcxproj.user" GAMEPLAY_PATH "%gpPath%"
 
 
 REM Copy Apple XCode project files
 REM Copy Apple XCode project files
-mkdir %projPath%\%projName%.xcodeproj
-copy gameplay-template\gameplay-template.xcodeproj\project.pbxproj %projPath%\%projName%.xcodeproj\project.pbxproj
-call:replace %projPath%\%projName%.xcodeproj\project.pbxproj GAMEPLAY_PATH "%gpPath%"
-call:replace %projPath%\%projName%.xcodeproj\project.pbxproj TemplateGame "%className%"
-call:replace %projPath%\%projName%.xcodeproj\project.pbxproj TEMPLATE_PROJECT "%projName%"
+mkdir "%projPath%\%projName%.xcodeproj"
+copy gameplay-template\gameplay-template.xcodeproj\project.pbxproj "%projPath%\%projName%.xcodeproj\project.pbxproj"
+call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" GAMEPLAY_PATH "%gpPath%"
+call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" TemplateGame "%className%"
+call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" TEMPLATE_PROJECT "%projName%"
 
 
-copy gameplay-template\TEMPLATE_PROJECT-macosx.plist %projPath%\%projName%-macosx.plist
-call:replace %projPath%\%projName%-macosx.plist TEMPLATE_UUID "%uuid%"
-call:replace %projPath%\%projName%-macosx.plist TEMPLATE_AUTHOR "%author%"
+copy gameplay-template\TEMPLATE_PROJECT-macosx.plist "%projPath%\%projName%-macosx.plist"
+call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_AUTHOR "%author%"
 
 
-copy gameplay-template\TEMPLATE_PROJECT-ios.plist %projPath%\%projName%-ios.plist
-call:replace %projPath%\%projName%-ios.plist TEMPLATE_TITLE "%title%"
-call:replace %projPath%\%projName%-ios.plist TEMPLATE_UUID "%uuid%"
-call:replace %projPath%\%projName%-ios.plist TEMPLATE_AUTHOR "%author%"
+copy gameplay-template\TEMPLATE_PROJECT-ios.plist "%projPath%\%projName%-ios.plist"
+call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_TITLE "%title%"
+call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_AUTHOR "%author%"
 
 
 REM Copy BlackBerry NDK project files
 REM Copy BlackBerry NDK project files
-copy gameplay-template\template.cproject %projPath%\.cproject
-call:replace %projPath%\.cproject TEMPLATE_PROJECT "%projName%"
-call:replace %projPath%\.cproject TEMPLATE_UUID "%uuid%"
-call:replace %projPath%\.cproject GAMEPLAY_PATH "%gpPath%"
+copy gameplay-template\template.cproject "%projPath%\.cproject"
+call:replace "%projPath%\.cproject" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\.cproject" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\.cproject" GAMEPLAY_PATH "%gpPath%"
 
 
-copy gameplay-template\template.project %projPath%\.project
-call:replace %projPath%\.project TEMPLATE_PROJECT "%projName%"
+copy gameplay-template\template.project "%projPath%\.project"
+call:replace "%projPath%\.project" TEMPLATE_PROJECT "%projName%"
 
 
-copy gameplay-template\template.bar-descriptor.xml %projPath%\bar-descriptor.xml
-call:replace %projPath%\bar-descriptor.xml TEMPLATE_PROJECT "%projName%"
-call:replace %projPath%\bar-descriptor.xml TEMPLATE_TITLE "%title%"
-call:replace %projPath%\bar-descriptor.xml TEMPLATE_UUID "%uuid%"
-call:replace %projPath%\bar-descriptor.xml TEMPLATE_AUTHOR "%author%"
-call:replace %projPath%\bar-descriptor.xml TEMPLATE_DESCRIPTION "%desc%"
+copy gameplay-template\template.bar-descriptor.xml "%projPath%\bar-descriptor.xml"
+call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_TITLE "%title%"
+call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_AUTHOR "%author%"
+call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_DESCRIPTION "%desc%"
 
 
 REM Copy Android NDK project files
 REM Copy Android NDK project files
-mkdir %projPath%\android
+mkdir "%projPath%\android"
 
 
-copy gameplay-template\android\template.AndroidManifest.xml %projPath%\android\AndroidManifest.xml
-call:replace %projPath%\android\AndroidManifest.xml TEMPLATE_PROJECT "%projName%"
-call:replace %projPath%\android\AndroidManifest.xml TEMPLATE_UUID "%uuid%"
+copy gameplay-template\android\template.AndroidManifest.xml "%projPath%\android\AndroidManifest.xml"
+call:replace "%projPath%\android\AndroidManifest.xml" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\android\AndroidManifest.xml" TEMPLATE_UUID "%uuid%"
 
 
-copy gameplay-template\android\template.build.xml %projPath%\android\build.xml
-call:replace %projPath%\android\build.xml TEMPLATE_PROJECT "%projName%"
+copy gameplay-template\android\template.build.xml "%projPath%\android\build.xml"
+call:replace "%projPath%\android\build.xml" TEMPLATE_PROJECT "%projName%"
 
 
-mkdir %projPath%\android\jni
+mkdir "%projPath%\android\jni"
 
 
-copy gameplay-template\android\jni\Application.mk %projPath%\android\jni\Application.mk
+copy gameplay-template\android\jni\Application.mk "%projPath%\android\jni\Application.mk"
 
 
-copy gameplay-template\android\jni\template.Android.mk %projPath%\android\jni\Android.mk
-call:replace %projPath%\android\jni\Android.mk TemplateGame "%className%"
-call:replace %projPath%\android\jni\Android.mk TEMPLATE_PROJECT "%projName%"
-call:replace %projPath%\android\jni\Android.mk GAMEPLAY_PATH "%gpPath%"
+copy gameplay-template\android\jni\template.Android.mk "%projPath%\android\jni\Android.mk"
+call:replace "%projPath%\android\jni\Android.mk" TemplateGame "%className%"
+call:replace "%projPath%\android\jni\Android.mk" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\android\jni\Android.mk" GAMEPLAY_PATH "%gpPath%"
 
 
-mkdir %projPath%\android\res\drawable
+mkdir "%projPath%\android\res\drawable"
 
 
-copy gameplay-template\icon.png %projPath%\android\res\drawable\icon.png
+copy gameplay-template\icon.png "%projPath%\android\res\drawable\icon.png"
 
 
-mkdir %projPath%\android\res\values
+mkdir "%projPath%\android\res\values"
 
 
-copy gameplay-template\android\res\values\template.strings.xml %projPath%\android\res\values\strings.xml
-call:replace %projPath%\android\res\values\strings.xml TEMPLATE_TITLE "%title%"
+copy gameplay-template\android\res\values\template.strings.xml "%projPath%\android\res\values\strings.xml"
+call:replace "%projPath%\android\res\values\strings.xml" TEMPLATE_TITLE "%title%"
 
 
 
 
 REM Copy source files
 REM Copy source files
-copy gameplay-template\src\TemplateGame.h %projPath%\src\%className%.h
-copy gameplay-template\src\TemplateGame.cpp %projPath%\src\%className%.cpp
-call:replace %projPath%\src\%className%.h TemplateGame "%className%"
-call:replace %projPath%\src\%className%.cpp TemplateGame "%className%"
+copy gameplay-template\src\TemplateGame.h "%projPath%\src\%className%.h"
+copy gameplay-template\src\TemplateGame.cpp "%projPath%\src\%className%.cpp"
+call:replace "%projPath%\src\%className%.h" TemplateGame "%className%"
+call:replace "%projPath%\src\%className%.cpp" TemplateGame "%className%"
 
 
 REM Copy resource files
 REM Copy resource files
-copy gameplay-template\res\* %projPath%\res\
+copy gameplay-template\res\* "%projPath%\res\"
 
 
 REM Copy icon
 REM Copy icon
-copy gameplay-template\icon.png %projPath%\icon.png
+copy gameplay-template\icon.png "%projPath%\icon.png"
 
 
 REM Copy config
 REM Copy config
-copy gameplay-template\game.config %projPath%\game.config
-call:replace %projPath%\game.config TEMPLATE_TITLE "%title%"
+copy gameplay-template\game.config "%projPath%\game.config"
+call:replace "%projPath%\game.config" TEMPLATE_TITLE "%title%"
 
 
 REM Open new project folder
 REM Open new project folder
-start %projPath%
+start "" "%projPath%"
 
 
 goto done
 goto done
 
 
 :replace
 :replace
-set rtemp=%1.rtemp
-if exist %rtemp% del /Q %rtemp%
-for /f "tokens=1* eol=€ delims=€]" %%j in ('type "%1" ^| find /V /N ""') do (
+set rtemp=%~1.rtemp
+if exist "%rtemp%" del /Q "%rtemp%"
+for /f "tokens=1* eol=€ delims=€]" %%j in ('type "%~1" ^| find /V /N ""') do (
     set line=%%k
     set line=%%k
     setlocal EnableDelayedExpansion
     setlocal EnableDelayedExpansion
     if "!line!" == "" (
     if "!line!" == "" (
-        echo.>>%rtemp%
+        echo.>>"%rtemp%"
     ) else (
     ) else (
         set linput=!line!
         set linput=!line!
         set loutput=!linput:%~2=%~3!
         set loutput=!linput:%~2=%~3!
-        echo.!loutput!>>%rtemp%
+        echo.!loutput!>>"%rtemp%"
     )
     )
     endlocal
     endlocal
 )
 )
-copy /Y %rtemp% %1
-del /Q %rtemp%
+copy /Y "%rtemp%" "%~1"
+del /Q "%rtemp%"
 exit /b
 exit /b
 goto done
 goto done
 
 

+ 54 - 36
gameplay-newproject.sh

@@ -1,4 +1,4 @@
-#/bin/bash
+#!/bin/bash
 # ********************************************************************
 # ********************************************************************
 #
 #
 # generate-project.sh
 # generate-project.sh
@@ -13,6 +13,21 @@
 #
 #
 # ********************************************************************
 # ********************************************************************
 
 
+#Find out which OS we're on. 
+unamestr=$(uname)
+
+#Switch-on alias expansion within the script (see http://chiefsandendians.blogspot.co.uk/2010/07/linux-scripts-and-alias.html)
+shopt -s expand_aliases
+
+#alias the sed in-place command for OSX and Linux - incompatibilities between BSD and Linux sed args
+if [[ "$unamestr" == "Darwin" ]]; then
+	alias aliassedinplace='sed -i ""'
+else
+	#For Linux, notice no space after the '-i' 
+	alias aliassedinplace='sed -i""'
+fi
+
+
 echo
 echo
 echo "1. Enter a name for the new project."
 echo "1. Enter a name for the new project."
 echo
 echo
@@ -161,15 +176,15 @@ fi
 # Copy Microsoft Visual Studio project files
 # Copy Microsoft Visual Studio project files
 #############################################
 #############################################
 cp "gameplay-template/gameplay-template.vcxproj" "$projPath/$projName.vcxproj"
 cp "gameplay-template/gameplay-template.vcxproj" "$projPath/$projName.vcxproj"
-sed -i "" "s*TEMPLATE_PROJECT*$projectName*g" "$projPath/$projName.vcxproj"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj"
-sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj"
+aliassedinplace "s*TEMPLATE_PROJECT*$projectName*g" "$projPath/$projName.vcxproj"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj"
 
 
 cp "gameplay-template/gameplay-template.vcxproj.filters" "$projPath/$projName.vcxproj.filters"
 cp "gameplay-template/gameplay-template.vcxproj.filters" "$projPath/$projName.vcxproj.filters"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj.filters"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj.filters"
 
 
 cp "gameplay-template/gameplay-template.vcxproj.user" "$projPath/$projName.vcxproj.user"
 cp "gameplay-template/gameplay-template.vcxproj.user" "$projPath/$projName.vcxproj.user"
-sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj.user"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj.user"
 
 
 
 
 #############################################
 #############################################
@@ -177,36 +192,36 @@ sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj.user"
 #############################################
 #############################################
 mkdir -p "$projPath/$projName.xcodeproj"
 mkdir -p "$projPath/$projName.xcodeproj"
 cp "gameplay-template/gameplay-template.xcodeproj/project.pbxproj" "$projPath/$projName.xcodeproj/project.pbxproj"
 cp "gameplay-template/gameplay-template.xcodeproj/project.pbxproj" "$projPath/$projName.xcodeproj/project.pbxproj"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/$projName.xcodeproj/project.pbxproj"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/$projName.xcodeproj/project.pbxproj"
-sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.xcodeproj/project.pbxproj"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/$projName.xcodeproj/project.pbxproj"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.xcodeproj/project.pbxproj"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.xcodeproj/project.pbxproj"
 
 
 cp "gameplay-template/TEMPLATE_PROJECT-macosx.plist" "$projPath/$projName-macosx.plist"
 cp "gameplay-template/TEMPLATE_PROJECT-macosx.plist" "$projPath/$projName-macosx.plist"
-sed -i "" "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-macosx.plist"
-sed -i "" "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-macosx.plist"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-macosx.plist"
+aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-macosx.plist"
 
 
 cp "gameplay-template/TEMPLATE_PROJECT-ios.plist" "$projPath/$projName-ios.plist"
 cp "gameplay-template/TEMPLATE_PROJECT-ios.plist" "$projPath/$projName-ios.plist"
-sed -i "" "s*TEMPLATE_TITLE*$title*g" "$projPath/$projName-ios.plist"
-sed -i "" "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-ios.plist"
-sed -i "" "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-ios.plist"
+aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/$projName-ios.plist"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-ios.plist"
+aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-ios.plist"
 
 
 #############################################
 #############################################
 # Copy BlackBerry NDK project files
 # Copy BlackBerry NDK project files
 #############################################
 #############################################
 cp "gameplay-template/template.cproject" "$projPath/.cproject"
 cp "gameplay-template/template.cproject" "$projPath/.cproject"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.cproject"
-sed -i "" "s*TEMPLATE_UUID*$uuid*g" "$projPath/.cproject"
-sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/.cproject"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.cproject"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/.cproject"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/.cproject"
 
 
 cp "gameplay-template/template.project" "$projPath/.project"
 cp "gameplay-template/template.project" "$projPath/.project"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.project"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.project"
 
 
 cp "gameplay-template/template.bar-descriptor.xml" "$projPath/bar-descriptor.xml"
 cp "gameplay-template/template.bar-descriptor.xml" "$projPath/bar-descriptor.xml"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/bar-descriptor.xml"
-sed -i "" "s*TEMPLATE_TITLE*$title*g" "$projPath/bar-descriptor.xml"
-sed -i "" "s*TEMPLATE_UUID*$uuid*g" "$projPath/bar-descriptor.xml"
-sed -i "" "s*TEMPLATE_AUTHOR*$author*g" "$projPath/bar-descriptor.xml"
-sed -i "" "s*TEMPLATE_DESCRIPTION*$desc*g" "$projPath/bar-descriptor.xml"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/bar-descriptor.xml"
+aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/bar-descriptor.xml"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/bar-descriptor.xml"
+aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/bar-descriptor.xml"
+aliassedinplace "s*TEMPLATE_DESCRIPTION*$desc*g" "$projPath/bar-descriptor.xml"
 
 
 #############################################
 #############################################
 # Copy Android NDK project files
 # Copy Android NDK project files
@@ -217,23 +232,23 @@ mkdir -p "$projPath/android/res/values"
 mkdir -p "$projPath/android/res/drawable"
 mkdir -p "$projPath/android/res/drawable"
 
 
 cp "gameplay-template/android/template.AndroidManifest.xml" "$projPath/android/AndroidManifest.xml"
 cp "gameplay-template/android/template.AndroidManifest.xml" "$projPath/android/AndroidManifest.xml"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/AndroidManifest.xml"
-sed -i "" "s*TEMPLATE_UUID*$uuid*g" "$projPath/android/AndroidManifest.xml"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/AndroidManifest.xml"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/android/AndroidManifest.xml"
 
 
 cp "gameplay-template/android/template.build.xml" "$projPath/android/build.xml"
 cp "gameplay-template/android/template.build.xml" "$projPath/android/build.xml"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/build.xml"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/build.xml"
 
 
 cp "gameplay-template/android/jni/Application.mk" "$projPath/android/jni/Application.mk"
 cp "gameplay-template/android/jni/Application.mk" "$projPath/android/jni/Application.mk"
 
 
 cp "gameplay-template/android/jni/template.Android.mk" "$projPath/android/jni/Android.mk"
 cp "gameplay-template/android/jni/template.Android.mk" "$projPath/android/jni/Android.mk"
-sed -i "" "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/jni/Android.mk"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/android/jni/Android.mk"
-sed -i "" "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/jni/Android.mk"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/jni/Android.mk"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/android/jni/Android.mk"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/jni/Android.mk"
 
 
 
 
 cp "gameplay-template/icon.png" "$projPath/android/res/drawable/icon.png"
 cp "gameplay-template/icon.png" "$projPath/android/res/drawable/icon.png"
 cp "gameplay-template/android/res/values/template.strings.xml" "$projPath/android/res/values/strings.xml"
 cp "gameplay-template/android/res/values/template.strings.xml" "$projPath/android/res/values/strings.xml"
-sed -i "" "s*TEMPLATE_TITLE*$title*g" "$projPath/android/res/values/strings.xml"
+aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/android/res/values/strings.xml"
 
 
 
 
 #############################################
 #############################################
@@ -241,8 +256,8 @@ sed -i "" "s*TEMPLATE_TITLE*$title*g" "$projPath/android/res/values/strings.xml"
 #############################################
 #############################################
 cp "gameplay-template/src/TemplateGame.h" "$projPath/src/$className.h"
 cp "gameplay-template/src/TemplateGame.h" "$projPath/src/$className.h"
 cp "gameplay-template/src/TemplateGame.cpp" "$projPath/src/$className.cpp"
 cp "gameplay-template/src/TemplateGame.cpp" "$projPath/src/$className.cpp"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/src/$className.h"
-sed -i "" "s*TemplateGame*$className*g" "$projPath/src/$className.cpp"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/src/$className.h"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/src/$className.cpp"
 
 
 # Copy resource files
 # Copy resource files
 cp "gameplay-template/res/"* "$projPath/res/"
 cp "gameplay-template/res/"* "$projPath/res/"
@@ -252,10 +267,13 @@ cp "gameplay-template/icon.png" "$projPath/icon.png"
 
 
 # Copy config
 # Copy config
 cp "gameplay-template/game.config" "$projPath/game.config"
 cp "gameplay-template/game.config" "$projPath/game.config"
-sed -i "" "s*TEMPLATE_TITLE*$title*g" "$projPath/game.config"
-
+aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/game.config"
 
 
-# Open the new project folder
-open $projPath
+# Open the new project folder, use xdg-open on Linux
+if [[ "$unamestr" == "Linux" ]]; then
+	xdg-open $projPath
+else
+	open $projPath
+fi
 
 
 exit 0
 exit 0

+ 3 - 3
gameplay-template/gameplay-template.vcxproj

@@ -82,7 +82,7 @@
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/win32;GAMEPLAY_PATH/external-deps/bullet/lib/win32;GAMEPLAY_PATH/external-deps/openal/lib/win32;GAMEPLAY_PATH/external-deps/oggvorbis/lib/win32;GAMEPLAY_PATH/external-deps/glew/lib/win32;GAMEPLAY_PATH/external-deps/libpng/lib/win32;GAMEPLAY_PATH/external-deps/zlib/lib/win32;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     </Link>
     <PostBuildEvent>
     <PostBuildEvent>
       <Command>
       <Command>
@@ -114,7 +114,7 @@
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/win32;GAMEPLAY_PATH/external-deps/bullet/lib/win32;GAMEPLAY_PATH/external-deps/openal/lib/win32;GAMEPLAY_PATH/external-deps/oggvorbis/lib/win32;GAMEPLAY_PATH/external-deps/glew/lib/win32;GAMEPLAY_PATH/external-deps/libpng/lib/win32;GAMEPLAY_PATH/external-deps/zlib/lib/win32;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     </Link>
     <PostBuildEvent>
     <PostBuildEvent>
       <Command>
       <Command>
@@ -146,7 +146,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/win32;GAMEPLAY_PATH/external-deps/bullet/lib/win32;GAMEPLAY_PATH/external-deps/openal/lib/win32;GAMEPLAY_PATH/external-deps/oggvorbis/lib/win32;GAMEPLAY_PATH/external-deps/glew/lib/win32;GAMEPLAY_PATH/external-deps/libpng/lib/win32;GAMEPLAY_PATH/external-deps/zlib/lib/win32;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     </Link>
     <PostBuildEvent>
     <PostBuildEvent>
       <Command>
       <Command>

+ 3 - 3
gameplay-template/gameplay-template.vcxproj.user

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

+ 6 - 32
gameplay-template/gameplay-template.xcodeproj/project.pbxproj

@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
 		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
 		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
 		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
 		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
+		424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424CC03B161FCBDD00577827 /* IOKit.framework */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
 		42C932EE1491A4CB0098216A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		42C932EE1491A4CB0098216A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		42C932F11491A5160098216A /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
 		42C932F11491A5160098216A /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
@@ -45,6 +46,7 @@
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
 		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		42438B521491AD2000D218B8 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
 		42438B521491AD2000D218B8 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
+		424CC03B161FCBDD00577827 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		42C932C01491A0DB0098216A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		42C932C01491A0DB0098216A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		42C932ED1491A4CB0098216A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
 		42C932ED1491A4CB0098216A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
@@ -87,6 +89,7 @@
 				42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */,
 				42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */,
 				42C9332C1491A7680098216A /* libpng.a in Frameworks */,
 				42C9332C1491A7680098216A /* libpng.a in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
+				424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
 				42C9331D1491A6750098216A /* QuartzCore.framework in Frameworks */,
 				42C9331D1491A6750098216A /* QuartzCore.framework in Frameworks */,
 				42C933171491A5EB0098216A /* OpenGL.framework in Frameworks */,
 				42C933171491A5EB0098216A /* OpenGL.framework in Frameworks */,
@@ -192,6 +195,7 @@
 		5B61613A14CCC3590073B857 /* MacOSX */ = {
 		5B61613A14CCC3590073B857 /* MacOSX */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				424CC03B161FCBDD00577827 /* IOKit.framework */,
 				42C932C01491A0DB0098216A /* Cocoa.framework */,
 				42C932C01491A0DB0098216A /* Cocoa.framework */,
 				42C9331C1491A6750098216A /* QuartzCore.framework */,
 				42C9331C1491A6750098216A /* QuartzCore.framework */,
 				42C933161491A5EB0098216A /* OpenGL.framework */,
 				42C933161491A5EB0098216A /* OpenGL.framework */,
@@ -220,7 +224,6 @@
 				42C932B91491A0DB0098216A /* Frameworks */,
 				42C932B91491A0DB0098216A /* Frameworks */,
 				42C933301491A7B50098216A /* ShellScript */,
 				42C933301491A7B50098216A /* ShellScript */,
 				42C932BA1491A0DB0098216A /* Resources */,
 				42C932BA1491A0DB0098216A /* Resources */,
-				5BAF20D7152F30C3003E2AC3 /* Copy Gameplay Resources - Run Script */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -239,7 +242,6 @@
 				5B61611714CCC24C0073B857 /* Frameworks */,
 				5B61611714CCC24C0073B857 /* Frameworks */,
 				5B61612414CCC24C0073B857 /* ShellScript */,
 				5B61612414CCC24C0073B857 /* ShellScript */,
 				5B61612514CCC24C0073B857 /* Resources */,
 				5B61612514CCC24C0073B857 /* Resources */,
-				5BAF20A3152F2FCE003E2AC3 /* Copy Gameplay Resources Run Script */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -310,7 +312,7 @@
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellPath = /bin/sh;
-			shellScript = "touch -cm ${SRCROOT}/res";
+			shellScript = "cp -rf GAMEPLAY_PATH/gameplay/res/shaders ${SRCROOT}/res\ncp -rf GAMEPLAY_PATH/gameplay/res/logo_powered_white.png ${SRCROOT}/res\ntouch -cm ${SRCROOT}/res";
 		};
 		};
 		5B61612414CCC24C0073B857 /* ShellScript */ = {
 		5B61612414CCC24C0073B857 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
 			isa = PBXShellScriptBuildPhase;
@@ -323,35 +325,7 @@
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellPath = /bin/sh;
-			shellScript = "touch -cm ${SRCROOT}/res";
-		};
-		5BAF20A3152F2FCE003E2AC3 /* Copy Gameplay Resources Run Script */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Copy Gameplay Reousrces Run Script";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "cp -rn GAMEPLAY_PATH/gameplay/res/shaders ${SRCROOT}/res\ncp -rf GAMEPLAY_PATH/gameplay/res/logo_powered_white.png ${SRCROOT}/res\ntouch -cm ${SRCROOT}/res";
-		};
-		5BAF20D7152F30C3003E2AC3 /* Copy Gameplay Resources - Run Script */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Copy Gameplay Resources - Run Script";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "cp -rn GAMEPLAY_PATH/gameplay/res/shaders ${SRCROOT}/res\ncp -rn GAMEPLAY_PATH/gameplay/res/logo_powered_white.png ${SRCROOT}/res\ntouch -cm ${SRCROOT}/res";
+			shellScript = "cp -rf GAMEPLAY_PATH/gameplay/res/shaders ${SRCROOT}/res\ncp -rf GAMEPLAY_PATH/gameplay/res/logo_powered_white.png ${SRCROOT}/res\ntouch -cm ${SRCROOT}/res";
 		};
 		};
 /* End PBXShellScriptBuildPhase section */
 /* End PBXShellScriptBuildPhase section */
 
 

二進制
gameplay-template/icon.png


+ 0 - 2
gameplay-template/template.bar-descriptor.xml

@@ -39,8 +39,6 @@
 
 
     <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
     <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
     <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
     <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
-    
-    <platformVersion>2.0.0.7971</platformVersion>
 
 
     <initialWindow>
     <initialWindow>
         <aspectRatio>landscape</aspectRatio>
         <aspectRatio>landscape</aspectRatio>

+ 28 - 21
gameplay-template/template.cproject

@@ -55,9 +55,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/arm&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.1174766388" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.1174766388" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -67,6 +67,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -139,9 +140,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/arm&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.380839761" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.380839761" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -151,6 +152,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -226,9 +228,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/arm&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.248496823" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.248496823" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -238,6 +240,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -314,9 +317,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/armle-v7/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/arm&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/arm&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/arm&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/arm&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.955918617" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.955918617" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -326,6 +329,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -399,9 +403,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/x86&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/x86&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.298922406" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.298922406" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -411,6 +415,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -486,9 +491,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/x86&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/x86&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.1203875316" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.1203875316" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -498,6 +503,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
@@ -573,9 +579,9 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/x86/usr/lib"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/gameplay/${ConfigName}&quot;"/>
-                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/qnx/x86&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/qnx/x86&quot;"/>
+                                    <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/lua/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/bullet/lib/blackberry/x86&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/GAMEPLAY_PATH/external-deps/oggvorbis/lib/blackberry/x86&quot;"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.linker.libraries.2055007034" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 								<option id="com.qnx.qcc.option.linker.libraries.2055007034" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs">
 									<listOptionValue builtIn="false" value="GLESv2"/>
 									<listOptionValue builtIn="false" value="GLESv2"/>
@@ -585,6 +591,7 @@
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="png14"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="pps"/>
 									<listOptionValue builtIn="false" value="bps"/>
 									<listOptionValue builtIn="false" value="bps"/>
+									<listOptionValue builtIn="false" value="gestures"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="OpenAL"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="asound"/>
 									<listOptionValue builtIn="false" value="gameplay"/>
 									<listOptionValue builtIn="false" value="gameplay"/>

+ 23 - 15
gameplay.doxyfile

@@ -1,4 +1,4 @@
-# Doxyfile 1.8.1
+# Doxyfile 1.8.0
 
 
 # This file describes the settings to be used by the documentation system
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
 # doxygen (www.doxygen.org) for a project
@@ -32,7 +32,7 @@ PROJECT_NAME           = gameplay
 # This could be handy for archiving the generated documentation or 
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 # if some version control system is used.
 
 
-PROJECT_NUMBER         = 1.4.0
+PROJECT_NUMBER         = 1.5.0
 
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # for a project that appears at the top of each page and should give viewer 
 # for a project that appears at the top of each page and should give viewer 
@@ -564,6 +564,12 @@ MAX_INITIALIZER_LINES  = 30
 
 
 SHOW_USED_FILES        = NO
 SHOW_USED_FILES        = NO
 
 
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
 # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
 # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
 # This will remove the Files entry from the Quick Index and from the 
 # This will remove the Files entry from the Quick Index and from the 
 # Folder Tree View (if specified). The default is YES.
 # Folder Tree View (if specified). The default is YES.
@@ -948,23 +954,20 @@ HTML_COLORSTYLE_GAMMA  = 80
 
 
 HTML_TIMESTAMP         = YES
 HTML_TIMESTAMP         = YES
 
 
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
 # documentation will contain sections that can be hidden and shown after the 
 # documentation will contain sections that can be hidden and shown after the 
-# page has loaded.
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
 
 
 HTML_DYNAMIC_SECTIONS  = NO
 HTML_DYNAMIC_SECTIONS  = NO
 
 
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of 
-# entries shown in the various tree structured indices initially; the user 
-# can expand and collapse entries dynamically later on. Doxygen will expand 
-# the tree to such a level that at most the specified number of entries are 
-# visible (unless a fully collapsed tree already exceeds this amount). 
-# So setting the number of entries 1 will produce a full collapsed tree by 
-# default. 0 is a special value representing an infinite number of entries 
-# and will result in a full expanded tree by default.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
 # If the GENERATE_DOCSET tag is set to YES, additional index files 
 # If the GENERATE_DOCSET tag is set to YES, additional index files 
 # will be generated that can be used as input for Apple's Xcode 3 
 # will be generated that can be used as input for Apple's Xcode 3 
 # integrated development environment, introduced with OSX 10.5 (Leopard). 
 # integrated development environment, introduced with OSX 10.5 (Leopard). 
@@ -1143,6 +1146,11 @@ GENERATE_TREEVIEW      = NO
 
 
 ENUM_VALUES_PER_LINE   = 4
 ENUM_VALUES_PER_LINE   = 4
 
 
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
 # used to set the initial width (in pixels) of the frame in which the tree 
 # used to set the initial width (in pixels) of the frame in which the tree 
 # is shown.
 # is shown.
@@ -1705,7 +1713,7 @@ CALLER_GRAPH           = NO
 
 
 GRAPHICAL_HIERARCHY    = YES
 GRAPHICAL_HIERARCHY    = YES
 
 
-# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
 # then doxygen will show the dependencies a directory has on other directories 
 # then doxygen will show the dependencies a directory has on other directories 
 # in a graphical way. The dependency relations are determined by the #include 
 # in a graphical way. The dependency relations are determined by the #include 
 # relations between the files in the directories.
 # relations between the files in the directories.

+ 198 - 8
gameplay.sln

@@ -3,6 +3,16 @@ Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
 # Visual Studio 2010
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay", "gameplay\gameplay.vcxproj", "{1032BA4B-57EB-4348-9E03-29DD63E80E4A}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay", "gameplay\gameplay.vcxproj", "{1032BA4B-57EB-4348-9E03-29DD63E80E4A}"
 EndProject
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-tests", "gameplay-tests\gameplay-tests.vcxproj", "{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample00-mesh", "gameplay-samples\sample00-mesh\sample00-mesh.vcxproj", "{D672DC66-3CE0-4878-B0D2-813CA731012F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample01-longboard", "gameplay-samples\sample01-longboard\sample01-longboard.vcxproj", "{9A515C8B-3320-4C5C-9754-211E91206C9D}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample01-longboard", "gameplay-samples\sample01-longboard\sample01-longboard.vcxproj", "{9A515C8B-3320-4C5C-9754-211E91206C9D}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
@@ -23,65 +33,245 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample04-particles", "gamep
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample00-mesh", "gameplay-samples\sample00-mesh\sample00-mesh.vcxproj", "{D672DC66-3CE0-4878-B0D2-813CA731012F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{C6121A62-AA46-BA6D-A1CE-8000544456AA}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{C6121A62-AA46-BA6D-A1CE-8000544456AA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample06-racer", "gameplay-samples\sample06-racer\sample06-racer.vcxproj", "{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|BlackBerry = Debug|BlackBerry
+		Debug|BlackBerrySimulator = Debug|BlackBerrySimulator
 		Debug|Win32 = Debug|Win32
 		Debug|Win32 = Debug|Win32
+		DebugMem|BlackBerry = DebugMem|BlackBerry
+		DebugMem|BlackBerrySimulator = DebugMem|BlackBerrySimulator
 		DebugMem|Win32 = DebugMem|Win32
 		DebugMem|Win32 = DebugMem|Win32
+		Release|BlackBerry = Release|BlackBerry
+		Release|BlackBerrySimulator = Release|BlackBerrySimulator
 		Release|Win32 = Release|Win32
 		Release|Win32 = Release|Win32
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{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}.Debug|Win32.Build.0 = Debug|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.ActiveCfg = DebugMem|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}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.ActiveCfg = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.ActiveCfg = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.Build.0 = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.Build.0 = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.Build.0 = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.ActiveCfg = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.Build.0 = Release|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{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|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{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|BlackBerry.ActiveCfg = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{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|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.ActiveCfg = Debug|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}.Debug|Win32.Build.0 = Debug|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.ActiveCfg = DebugMem|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}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|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}.Debug|Win32.Build.0 = Debug|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.ActiveCfg = DebugMem|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}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.ActiveCfg = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.ActiveCfg = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.Build.0 = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.Build.0 = Release|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.ActiveCfg = Debug|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}.Debug|Win32.Build.0 = Debug|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.ActiveCfg = DebugMem|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}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.ActiveCfg = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.ActiveCfg = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.Build.0 = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.Build.0 = Release|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.Build.0 = Debug|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.Build.0 = Debug|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.ActiveCfg = Release|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.ActiveCfg = Release|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.Build.0 = Release|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.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
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.Build.0 = Debug|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.Build.0 = Debug|Win32
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.Build.0 = Debug|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.ActiveCfg = Release|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 30 - 0
gameplay.workspace

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_workspace_file>
+	<Workspace title="GamePlay">
+		<Project filename="gameplay/gameplay.cbp" />
+		<Project filename="gameplay-tests/gameplay-tests.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample00-mesh/sample00-mesh.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample01-longboard/sample01-longboard.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample02-spaceship/sample02-spaceship.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample03-character/sample03-character.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample04-particles/sample04-particles.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample05-lua/sample05-lua.cbp">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+		<Project filename="gameplay-samples/sample06-racer/sample06-racer.cbp" active="1">
+			<Depends filename="gameplay/gameplay.cbp" />
+		</Project>
+	</Workspace>
+</CodeBlocks_workspace_file>

+ 6 - 0
gameplay.xcworkspace/contents.xcworkspacedata

@@ -4,6 +4,9 @@
    <FileRef
    <FileRef
       location = "group:gameplay/gameplay.xcodeproj">
       location = "group:gameplay/gameplay.xcodeproj">
    </FileRef>
    </FileRef>
+   <FileRef
+      location = "group:gameplay-tests/gameplay-tests.xcodeproj">
+   </FileRef>
    <FileRef
    <FileRef
       location = "group:gameplay-samples/sample00-mesh/sample00-mesh.xcodeproj">
       location = "group:gameplay-samples/sample00-mesh/sample00-mesh.xcodeproj">
    </FileRef>
    </FileRef>
@@ -22,4 +25,7 @@
    <FileRef
    <FileRef
       location = "group:gameplay-samples/sample05-lua/sample05-lua.xcodeproj">
       location = "group:gameplay-samples/sample05-lua/sample05-lua.xcodeproj">
    </FileRef>
    </FileRef>
+   <FileRef
+      location = "group:gameplay-samples/sample06-racer/sample06-racer.xcodeproj">
+   </FileRef>
 </Workspace>
 </Workspace>

+ 614 - 0
gameplay/CMakeLists.txt

@@ -0,0 +1,614 @@
+set(GAMEPLAY_SRC
+    src/AbsoluteLayout.cpp
+    src/AbsoluteLayout.h
+    src/AIAgent.cpp
+    src/AIAgent.h
+    src/AIController.cpp
+    src/AIController.h
+    src/AIMessage.cpp
+    src/AIMessage.h
+    src/AIState.cpp
+    src/AIState.h
+    src/AIStateMachine.cpp
+    src/AIStateMachine.h
+    src/Animation.cpp
+    src/Animation.h
+    src/AnimationClip.cpp
+    src/AnimationClip.h
+    src/AnimationController.cpp
+    src/AnimationController.h
+    src/AnimationTarget.cpp
+    src/AnimationTarget.h
+    src/AnimationValue.cpp
+    src/AnimationValue.h
+    src/AudioBuffer.cpp
+    src/AudioBuffer.h
+    src/AudioController.cpp
+    src/AudioController.h
+    src/AudioListener.cpp
+    src/AudioListener.h
+    src/AudioSource.cpp
+    src/AudioSource.h
+    src/Base.h
+    src/BoundingBox.cpp
+    src/BoundingBox.h
+    src/BoundingBox.inl
+    src/BoundingSphere.cpp
+    src/BoundingSphere.h
+    src/BoundingSphere.inl
+    src/Bundle.cpp
+    src/Bundle.h
+    src/Button.cpp
+    src/Button.h
+    src/Camera.cpp
+    src/Camera.h
+    src/CheckBox.cpp
+    src/CheckBox.h
+    src/Container.cpp
+    src/Container.h
+    src/Control.cpp
+    src/Control.h
+    src/Curve.cpp
+    src/Curve.h
+    src/DebugNew.cpp
+    src/DebugNew.h
+    src/DepthStencilTarget.cpp
+    src/DepthStencilTarget.h
+    src/Effect.cpp
+    src/Effect.h
+    src/FileSystem.cpp
+    src/FileSystem.h
+    src/FlowLayout.cpp
+    src/FlowLayout.h
+    src/Font.cpp
+    src/Font.h
+    src/Form.cpp
+    src/Form.h
+    src/FrameBuffer.cpp
+    src/FrameBuffer.h
+    src/Frustum.cpp
+    src/Frustum.h
+    src/Game.cpp
+    src/Game.h
+    src/Game.inl
+    src/Gamepad.cpp
+    src/Gamepad.h
+    src/gameplay-main-android.cpp
+    src/gameplay-main-blackberry.cpp
+    src/gameplay-main-linux.cpp
+    src/gameplay-main-windows.cpp
+	src/Gesture.h
+    src/Image.cpp
+    src/Image.h
+    src/Image.inl
+    src/Joint.cpp
+    src/Joint.h
+    src/Joystick.cpp
+    src/Joystick.h
+    src/Joystick.inl
+    src/Label.cpp
+    src/Label.h
+    src/Layout.cpp
+    src/Layout.h
+    src/Light.cpp
+    src/Light.h
+    src/Logger.cpp
+    src/Logger.h
+    src/Material.cpp
+    src/Material.h
+    src/MaterialParameter.cpp
+    src/MaterialParameter.h
+    src/MathUtil.cpp
+    src/MathUtil.h
+    src/MathUtil.inl
+    src/MathUtilNeon.inl
+    src/Matrix.cpp
+    src/Matrix.h
+    src/Matrix.inl
+    src/Mesh.cpp
+    src/Mesh.h
+    src/MeshBatch.cpp
+    src/MeshBatch.h
+    src/MeshBatch.inl
+    src/MeshPart.cpp
+    src/MeshPart.h
+    src/MeshSkin.cpp
+    src/MeshSkin.h
+    src/Model.cpp
+    src/Model.h
+    src/Node.cpp
+    src/Node.h
+    src/ParticleEmitter.cpp
+    src/ParticleEmitter.h
+    src/Pass.cpp
+    src/Pass.h
+    src/PhysicsCharacter.cpp
+    src/PhysicsCharacter.h
+    src/PhysicsCollisionObject.cpp
+    src/PhysicsCollisionObject.h
+    src/PhysicsCollisionShape.cpp
+    src/PhysicsCollisionShape.h
+    src/PhysicsConstraint.cpp
+    src/PhysicsConstraint.h
+    src/PhysicsController.cpp
+    src/PhysicsController.h
+    src/PhysicsFixedConstraint.cpp
+    src/PhysicsFixedConstraint.h
+    src/PhysicsGenericConstraint.cpp
+    src/PhysicsGenericConstraint.h
+    src/PhysicsGhostObject.cpp
+    src/PhysicsGhostObject.h
+    src/PhysicsHingeConstraint.cpp
+    src/PhysicsHingeConstraint.h
+    src/PhysicsRigidBody.cpp
+    src/PhysicsRigidBody.h
+    src/PhysicsSocketConstraint.cpp
+    src/PhysicsSocketConstraint.h
+    src/PhysicsSpringConstraint.cpp
+    src/PhysicsSpringConstraint.h
+	src/PhysicsVehicle.cpp
+	src/PhysicsVehicle.h
+	src/PhysicsVehicleWheel.cpp
+	src/PhysicsVehicle.h
+    src/Plane.cpp
+    src/Plane.h
+    src/Plane.inl
+    src/Platform.h
+    src/PlatformAndroid.cpp
+    src/PlatformBlackBerry.cpp
+    src/PlatformLinux.cpp
+    src/PlatformWindows.cpp
+    src/Properties.cpp
+    src/Properties.h
+    src/Quaternion.cpp
+    src/Quaternion.h
+    src/Quaternion.inl
+    src/RadioButton.cpp
+    src/RadioButton.h
+    src/Ray.cpp
+    src/Ray.h
+    src/Ray.inl
+    src/Rectangle.cpp
+    src/Rectangle.h
+    src/Ref.cpp
+    src/Ref.h
+    src/RenderState.cpp
+    src/RenderState.h
+    src/RenderTarget.cpp
+    src/RenderTarget.h
+    src/Scene.cpp
+    src/Scene.h
+    src/SceneLoader.cpp
+    src/SceneLoader.h
+    src/ScreenDisplayer.cpp
+    src/ScreenDisplayer.h
+    src/ScriptController.cpp
+    src/ScriptController.h
+    src/ScriptController.inl
+    src/ScriptTarget.cpp
+    src/ScriptTarget.h
+    src/Slider.cpp
+    src/Slider.h
+    src/SpriteBatch.cpp
+    src/SpriteBatch.h
+    src/Technique.cpp
+    src/Technique.h
+    src/TextBox.cpp
+    src/TextBox.h
+    src/Texture.cpp
+    src/Texture.h
+    src/Theme.cpp
+    src/Theme.h
+    src/ThemeStyle.cpp
+    src/ThemeStyle.h
+    src/Transform.cpp
+    src/Transform.h
+    src/Vector2.cpp
+    src/Vector2.h
+    src/Vector2.inl
+    src/Vector3.cpp
+    src/Vector3.h
+    src/Vector3.inl
+    src/Vector4.cpp
+    src/Vector4.h
+    src/Vector4.inl
+    src/VertexAttributeBinding.cpp
+    src/VertexAttributeBinding.h
+    src/VertexFormat.cpp
+    src/VertexFormat.h
+    src/VerticalLayout.cpp
+    src/VerticalLayout.h
+)
+
+set(GAMEPLAY_LUA
+    src/lua/lua_all_bindings.cpp
+    src/lua/lua_all_bindings.h
+    src/lua/lua_AbsoluteLayout.cpp
+    src/lua/lua_AbsoluteLayout.h
+    src/lua/lua_AIAgent.cpp
+    src/lua/lua_AIAgent.h
+    src/lua/lua_AIAgentListener.cpp
+    src/lua/lua_AIAgentListener.h
+    src/lua/lua_AIController.cpp
+    src/lua/lua_AIController.h
+    src/lua/lua_AIMessage.cpp
+    src/lua/lua_AIMessage.h
+    src/lua/lua_AIMessageParameterType.cpp
+    src/lua/lua_AIMessageParameterType.h
+    src/lua/lua_AIState.cpp
+    src/lua/lua_AIState.h
+    src/lua/lua_AIStateListener.cpp
+    src/lua/lua_AIStateListener.h
+    src/lua/lua_AIStateMachine.cpp
+    src/lua/lua_AIStateMachine.h
+    src/lua/lua_Animation.cpp
+    src/lua/lua_Animation.h
+    src/lua/lua_AnimationClip.cpp
+    src/lua/lua_AnimationClip.h
+    src/lua/lua_AnimationClipListener.cpp
+    src/lua/lua_AnimationClipListener.h
+    src/lua/lua_AnimationClipListenerEventType.cpp
+    src/lua/lua_AnimationClipListenerEventType.h
+    src/lua/lua_AnimationController.cpp
+    src/lua/lua_AnimationController.h
+    src/lua/lua_AnimationTarget.cpp
+    src/lua/lua_AnimationTarget.h
+    src/lua/lua_AnimationValue.cpp
+    src/lua/lua_AnimationValue.h
+    src/lua/lua_AudioBuffer.cpp
+    src/lua/lua_AudioBuffer.h
+    src/lua/lua_AudioController.cpp
+    src/lua/lua_AudioController.h
+    src/lua/lua_AudioListener.cpp
+    src/lua/lua_AudioListener.h
+    src/lua/lua_AudioSource.cpp
+    src/lua/lua_AudioSource.h
+    src/lua/lua_AudioSourceState.cpp
+    src/lua/lua_AudioSourceState.h
+    src/lua/lua_BoundingBox.cpp
+    src/lua/lua_BoundingBox.h
+    src/lua/lua_BoundingSphere.cpp
+    src/lua/lua_BoundingSphere.h
+    src/lua/lua_Bundle.cpp
+    src/lua/lua_Bundle.h
+    src/lua/lua_Button.cpp
+    src/lua/lua_Button.h
+    src/lua/lua_Camera.cpp
+    src/lua/lua_Camera.h
+    src/lua/lua_CameraType.cpp
+    src/lua/lua_CameraType.h
+    src/lua/lua_CheckBox.cpp
+    src/lua/lua_CheckBox.h
+    src/lua/lua_Container.cpp
+    src/lua/lua_Container.h
+    src/lua/lua_ContainerScroll.cpp
+    src/lua/lua_ContainerScroll.h
+    src/lua/lua_Control.cpp
+    src/lua/lua_Control.h
+    src/lua/lua_ControlAlignment.cpp
+    src/lua/lua_ControlAlignment.h
+    src/lua/lua_ControlListener.cpp
+    src/lua/lua_ControlListener.h
+    src/lua/lua_ControlListenerEventType.cpp
+    src/lua/lua_ControlListenerEventType.h
+    src/lua/lua_ControlState.cpp
+    src/lua/lua_ControlState.h
+    src/lua/lua_Curve.cpp
+    src/lua/lua_Curve.h
+    src/lua/lua_CurveInterpolationType.cpp
+    src/lua/lua_CurveInterpolationType.h
+    src/lua/lua_DepthStencilTarget.cpp
+    src/lua/lua_DepthStencilTarget.h
+    src/lua/lua_DepthStencilTargetFormat.cpp
+    src/lua/lua_DepthStencilTargetFormat.h
+    src/lua/lua_Effect.cpp
+    src/lua/lua_Effect.h
+    src/lua/lua_FileSystem.cpp
+    src/lua/lua_FileSystem.h
+    src/lua/lua_FlowLayout.cpp
+    src/lua/lua_FlowLayout.h
+    src/lua/lua_Font.cpp
+    src/lua/lua_Font.h
+    src/lua/lua_FontJustify.cpp
+    src/lua/lua_FontJustify.h
+    src/lua/lua_FontStyle.cpp
+    src/lua/lua_FontStyle.h
+    src/lua/lua_FontText.cpp
+    src/lua/lua_FontText.h
+    src/lua/lua_Form.cpp
+    src/lua/lua_Form.h
+    src/lua/lua_FrameBuffer.cpp
+    src/lua/lua_FrameBuffer.h
+    src/lua/lua_Frustum.cpp
+    src/lua/lua_Frustum.h
+    src/lua/lua_Game.cpp
+    src/lua/lua_Game.h
+    src/lua/lua_GameClearFlags.cpp
+    src/lua/lua_GameClearFlags.h
+    src/lua/lua_Gamepad.cpp
+    src/lua/lua_Gamepad.h
+    src/lua/lua_GamepadButtonState.cpp
+    src/lua/lua_GamepadButtonState.h
+    src/lua/lua_GamepadGamepadEvent.cpp
+    src/lua/lua_GamepadGamepadEvent.h
+    src/lua/lua_GameState.cpp
+    src/lua/lua_GameState.h
+	src/lua/lua_Gesture.cpp
+	src/lua/lua_Gesture.h
+	src/lua/lua_GestureGestureEvent.cpp
+	src/lua/lua_GestureGestureEvent.h
+    src/lua/lua_Global.cpp
+    src/lua/lua_Global.h
+    src/lua/lua_Image.cpp
+    src/lua/lua_Image.h
+    src/lua/lua_ImageFormat.cpp
+    src/lua/lua_ImageFormat.h
+    src/lua/lua_Joint.cpp
+    src/lua/lua_Joint.h
+    src/lua/lua_Joystick.cpp
+    src/lua/lua_Joystick.h
+    src/lua/lua_Keyboard.cpp
+    src/lua/lua_Keyboard.h
+    src/lua/lua_KeyboardKey.cpp
+    src/lua/lua_KeyboardKey.h
+    src/lua/lua_KeyboardKeyEvent.cpp
+    src/lua/lua_KeyboardKeyEvent.h
+    src/lua/lua_Label.cpp
+    src/lua/lua_Label.h
+    src/lua/lua_Layout.cpp
+    src/lua/lua_Layout.h
+    src/lua/lua_LayoutType.cpp
+    src/lua/lua_LayoutType.h
+    src/lua/lua_Light.cpp
+    src/lua/lua_Light.h
+    src/lua/lua_LightType.cpp
+    src/lua/lua_LightType.h
+    src/lua/lua_Logger.cpp
+    src/lua/lua_Logger.h
+    src/lua/lua_LoggerLevel.cpp
+    src/lua/lua_LoggerLevel.h
+    src/lua/lua_Material.cpp
+    src/lua/lua_Material.h
+    src/lua/lua_MaterialParameter.cpp
+    src/lua/lua_MaterialParameter.h
+    src/lua/lua_MathUtil.cpp
+    src/lua/lua_MathUtil.h
+    src/lua/lua_Matrix.cpp
+    src/lua/lua_Matrix.h
+    src/lua/lua_Mesh.cpp
+    src/lua/lua_Mesh.h
+    src/lua/lua_MeshBatch.cpp
+    src/lua/lua_MeshBatch.h
+    src/lua/lua_MeshIndexFormat.cpp
+    src/lua/lua_MeshIndexFormat.h
+    src/lua/lua_MeshPart.cpp
+    src/lua/lua_MeshPart.h
+    src/lua/lua_MeshPrimitiveType.cpp
+    src/lua/lua_MeshPrimitiveType.h
+    src/lua/lua_MeshSkin.cpp
+    src/lua/lua_MeshSkin.h
+    src/lua/lua_Model.cpp
+    src/lua/lua_Model.h
+    src/lua/lua_Mouse.cpp
+    src/lua/lua_Mouse.h
+    src/lua/lua_MouseMouseEvent.cpp
+    src/lua/lua_MouseMouseEvent.h
+    src/lua/lua_Node.cpp
+    src/lua/lua_Node.h
+    src/lua/lua_NodeCloneContext.cpp
+    src/lua/lua_NodeCloneContext.h
+    src/lua/lua_NodeType.cpp
+    src/lua/lua_NodeType.h
+    src/lua/lua_ParticleEmitter.cpp
+    src/lua/lua_ParticleEmitter.h
+    src/lua/lua_ParticleEmitterTextureBlending.cpp
+    src/lua/lua_ParticleEmitterTextureBlending.h
+    src/lua/lua_Pass.cpp
+    src/lua/lua_Pass.h
+    src/lua/lua_PhysicsCharacter.cpp
+    src/lua/lua_PhysicsCharacter.h
+    src/lua/lua_PhysicsCollisionObject.cpp
+    src/lua/lua_PhysicsCollisionObject.h
+    src/lua/lua_PhysicsCollisionObjectCollisionListener.cpp
+    src/lua/lua_PhysicsCollisionObjectCollisionListener.h
+    src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.cpp
+    src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.h
+    src/lua/lua_PhysicsCollisionObjectCollisionPair.cpp
+    src/lua/lua_PhysicsCollisionObjectCollisionPair.h
+    src/lua/lua_PhysicsCollisionObjectType.cpp
+    src/lua/lua_PhysicsCollisionObjectType.h
+    src/lua/lua_PhysicsCollisionShape.cpp
+    src/lua/lua_PhysicsCollisionShape.h
+    src/lua/lua_PhysicsCollisionShapeDefinition.cpp
+    src/lua/lua_PhysicsCollisionShapeDefinition.h
+    src/lua/lua_PhysicsCollisionShapeType.cpp
+    src/lua/lua_PhysicsCollisionShapeType.h
+    src/lua/lua_PhysicsConstraint.cpp
+    src/lua/lua_PhysicsConstraint.h
+    src/lua/lua_PhysicsController.cpp
+    src/lua/lua_PhysicsController.h
+    src/lua/lua_PhysicsControllerHitFilter.cpp
+    src/lua/lua_PhysicsControllerHitFilter.h
+    src/lua/lua_PhysicsControllerHitResult.cpp
+    src/lua/lua_PhysicsControllerHitResult.h
+    src/lua/lua_PhysicsControllerListener.cpp
+    src/lua/lua_PhysicsControllerListener.h
+    src/lua/lua_PhysicsControllerListenerEventType.cpp
+    src/lua/lua_PhysicsControllerListenerEventType.h
+    src/lua/lua_PhysicsFixedConstraint.cpp
+    src/lua/lua_PhysicsFixedConstraint.h
+    src/lua/lua_PhysicsGenericConstraint.cpp
+    src/lua/lua_PhysicsGenericConstraint.h
+    src/lua/lua_PhysicsGhostObject.cpp
+    src/lua/lua_PhysicsGhostObject.h
+    src/lua/lua_PhysicsHingeConstraint.cpp
+    src/lua/lua_PhysicsHingeConstraint.h
+    src/lua/lua_PhysicsRigidBody.cpp
+    src/lua/lua_PhysicsRigidBody.h
+    src/lua/lua_PhysicsRigidBodyParameters.cpp
+    src/lua/lua_PhysicsRigidBodyParameters.h
+    src/lua/lua_PhysicsSocketConstraint.cpp
+    src/lua/lua_PhysicsSocketConstraint.h
+    src/lua/lua_PhysicsSpringConstraint.cpp
+    src/lua/lua_PhysicsSpringConstraint.h
+	src/lua/lua_PhysicsVehicle.cpp
+	src/lua/lua_PhysicsVehicle.h
+	src/lua/lua_PhysicsVehicleWheel.cpp
+	src/lua/lua_PhysicsVehicleWheel.h
+    src/lua/lua_Plane.cpp
+    src/lua/lua_Plane.h
+    src/lua/lua_Platform.cpp
+    src/lua/lua_Platform.h
+    src/lua/lua_Properties.cpp
+    src/lua/lua_Properties.h
+    src/lua/lua_PropertiesType.cpp
+    src/lua/lua_PropertiesType.h
+    src/lua/lua_Quaternion.cpp
+    src/lua/lua_Quaternion.h
+    src/lua/lua_RadioButton.cpp
+    src/lua/lua_RadioButton.h
+    src/lua/lua_Ray.cpp
+    src/lua/lua_Ray.h
+    src/lua/lua_Rectangle.cpp
+    src/lua/lua_Rectangle.h
+    src/lua/lua_Ref.cpp
+    src/lua/lua_Ref.h
+    src/lua/lua_RenderState.cpp
+    src/lua/lua_RenderState.h
+    src/lua/lua_RenderStateAutoBinding.cpp
+    src/lua/lua_RenderStateAutoBinding.h
+    src/lua/lua_RenderStateBlend.cpp
+    src/lua/lua_RenderStateBlend.h
+    src/lua/lua_RenderStateStateBlock.cpp
+    src/lua/lua_RenderStateStateBlock.h
+    src/lua/lua_RenderTarget.cpp
+    src/lua/lua_RenderTarget.h
+    src/lua/lua_Scene.cpp
+    src/lua/lua_Scene.h
+    src/lua/lua_SceneDebugFlags.cpp
+    src/lua/lua_SceneDebugFlags.h
+    src/lua/lua_ScreenDisplayer.cpp
+    src/lua/lua_ScreenDisplayer.h
+    src/lua/lua_ScriptController.cpp
+    src/lua/lua_ScriptController.h
+    src/lua/lua_ScriptTarget.cpp
+    src/lua/lua_ScriptTarget.h
+    src/lua/lua_Slider.cpp
+    src/lua/lua_Slider.h
+    src/lua/lua_SpriteBatch.cpp
+    src/lua/lua_SpriteBatch.h
+    src/lua/lua_Technique.cpp
+    src/lua/lua_Technique.h
+    src/lua/lua_TextBox.cpp
+    src/lua/lua_TextBox.h
+    src/lua/lua_Texture.cpp
+    src/lua/lua_Texture.h
+    src/lua/lua_TextureFilter.cpp
+    src/lua/lua_TextureFilter.h
+    src/lua/lua_TextureFormat.cpp
+    src/lua/lua_TextureFormat.h
+    src/lua/lua_TextureSampler.cpp
+    src/lua/lua_TextureSampler.h
+    src/lua/lua_TextureWrap.cpp
+    src/lua/lua_TextureWrap.h
+    src/lua/lua_Theme.cpp
+    src/lua/lua_Theme.h
+    src/lua/lua_ThemeSideRegions.cpp
+    src/lua/lua_ThemeSideRegions.h
+    src/lua/lua_ThemeStyle.cpp
+    src/lua/lua_ThemeStyle.h
+    src/lua/lua_ThemeThemeImage.cpp
+    src/lua/lua_ThemeThemeImage.h
+    src/lua/lua_ThemeUVs.cpp
+    src/lua/lua_ThemeUVs.h
+    src/lua/lua_Touch.cpp
+    src/lua/lua_Touch.h
+    src/lua/lua_TouchTouchEvent.cpp
+    src/lua/lua_TouchTouchEvent.h
+    src/lua/lua_Transform.cpp
+    src/lua/lua_Transform.h
+    src/lua/lua_TransformListener.cpp
+    src/lua/lua_TransformListener.h
+    src/lua/lua_Uniform.cpp
+    src/lua/lua_Uniform.h
+    src/lua/lua_Vector2.cpp
+    src/lua/lua_Vector2.h
+    src/lua/lua_Vector3.cpp
+    src/lua/lua_Vector3.h
+    src/lua/lua_Vector4.cpp
+    src/lua/lua_Vector4.h
+    src/lua/lua_VertexAttributeBinding.cpp
+    src/lua/lua_VertexAttributeBinding.h
+    src/lua/lua_VertexFormat.cpp
+    src/lua/lua_VertexFormat.h
+    src/lua/lua_VertexFormatElement.cpp
+    src/lua/lua_VertexFormatElement.h
+    src/lua/lua_VertexFormatUsage.cpp
+    src/lua/lua_VertexFormatUsage.h
+    src/lua/lua_VerticalLayout.cpp
+    src/lua/lua_VerticalLayout.h
+)
+
+set(GAMEPLAY_RES
+    res/logo_black.png
+    res/logo_powered_black.png
+    res/logo_powered_white.png
+    res/logo_white.png
+)
+
+set(GAMEPLAY_RES_SHADERS
+    res/shaders/colored-unlit.frag
+    res/shaders/colored-unlit.vert
+    res/shaders/colored.frag
+    res/shaders/colored.vert
+    res/shaders/textured-bumped.frag
+    res/shaders/textured-bumped.vert
+    res/shaders/textured-unlit.frag
+    res/shaders/textured-unlit.vert
+    res/shaders/textured.frag
+    res/shaders/textured.vert
+)
+
+set(GAMEPLAY_RES_SHADERS_LIB
+    res/shaders/lib/attributes-skinning.vert
+    res/shaders/lib/attributes.vert
+    res/shaders/lib/lighting-directional.frag
+    res/shaders/lib/lighting-directional.vert
+    res/shaders/lib/lighting-point.frag
+    res/shaders/lib/lighting-point.vert
+    res/shaders/lib/lighting-spot.frag
+    res/shaders/lib/lighting-spot.vert
+    res/shaders/lib/lighting.frag
+)
+
+include_directories( 
+    src
+    ../external-deps/lua/include
+    ../external-deps/bullet/include
+    ../external-deps/libpng/include
+    ../external-deps/zlib/include
+    ../external-deps/oggvorbis/include
+    ../external-deps/openal/include
+    ../external-deps/glew/include
+)
+
+add_definitions(-D__linux__)
+add_definitions(-lstdc++)
+
+add_library(gameplay STATIC
+    ${GAMEPLAY_SRC}
+    ${GAMEPLAY_LUA}
+)
+
+set_target_properties(gameplay PROPERTIES
+    OUTPUT_NAME "gameplay"
+    CLEAN_DIRECT_OUTPUT 1
+    VERSION ${GAMEPLAY_VERSION}
+)
+
+source_group(lua FILES ${GAMEPLAY_LUA})
+source_group(res FILES ${GAMEPLAY_RES} ${GAMEPLAY_RES} ${GAMEPLAY_RES_SHADERS} ${GAMEPLAY_RES_SHADERS_LIB})
+source_group(src FILES ${GAMEPLAY_SRC})
+
+
+

+ 11 - 2
gameplay/android/jni/Android.mk

@@ -52,15 +52,16 @@ LOCAL_SRC_FILES := \
     Frustum.cpp \
     Frustum.cpp \
     Game.cpp \
     Game.cpp \
     Gamepad.cpp \
     Gamepad.cpp \
-    gameplay-main-android.cpp \
     Image.cpp \
     Image.cpp \
     Joint.cpp \
     Joint.cpp \
     Joystick.cpp \
     Joystick.cpp \
     Label.cpp \
     Label.cpp \
     Layout.cpp \
     Layout.cpp \
     Light.cpp \
     Light.cpp \
+    Logger.cpp \
     Material.cpp \
     Material.cpp \
     MaterialParameter.cpp \
     MaterialParameter.cpp \
+    MathUtil.cpp \
     Matrix.cpp \
     Matrix.cpp \
     Mesh.cpp \
     Mesh.cpp \
     MeshBatch.cpp \
     MeshBatch.cpp \
@@ -82,6 +83,8 @@ LOCAL_SRC_FILES := \
     PhysicsRigidBody.cpp \
     PhysicsRigidBody.cpp \
     PhysicsSocketConstraint.cpp \
     PhysicsSocketConstraint.cpp \
     PhysicsSpringConstraint.cpp \
     PhysicsSpringConstraint.cpp \
+    PhysicsVehicle.cpp \
+    PhysicsVehicleWheel.cpp \
     Plane.cpp \
     Plane.cpp \
     PlatformAndroid.cpp \
     PlatformAndroid.cpp \
     Properties.cpp \
     Properties.cpp \
@@ -167,6 +170,8 @@ LOCAL_SRC_FILES := \
     lua/lua_GamepadButtonState.cpp \
     lua/lua_GamepadButtonState.cpp \
     lua/lua_GamepadGamepadEvent.cpp \
     lua/lua_GamepadGamepadEvent.cpp \
     lua/lua_GameState.cpp \
     lua/lua_GameState.cpp \
+    lua/lua_Gesture.cpp \
+    lua/lua_GestureGestureEvent.cpp \
     lua/lua_Global.cpp \
     lua/lua_Global.cpp \
     lua/lua_Image.cpp \
     lua/lua_Image.cpp \
     lua/lua_ImageFormat.cpp \
     lua/lua_ImageFormat.cpp \
@@ -180,6 +185,8 @@ LOCAL_SRC_FILES := \
     lua/lua_LayoutType.cpp \
     lua/lua_LayoutType.cpp \
     lua/lua_Light.cpp \
     lua/lua_Light.cpp \
     lua/lua_LightType.cpp \
     lua/lua_LightType.cpp \
+    lua/lua_Logger.cpp \
+    lua/lua_LoggerLevel.cpp \
     lua/lua_Material.cpp \
     lua/lua_Material.cpp \
     lua/lua_MaterialParameter.cpp \
     lua/lua_MaterialParameter.cpp \
     lua/lua_MathUtil.cpp \
     lua/lua_MathUtil.cpp \
@@ -222,6 +229,8 @@ LOCAL_SRC_FILES := \
     lua/lua_PhysicsRigidBodyParameters.cpp \
     lua/lua_PhysicsRigidBodyParameters.cpp \
     lua/lua_PhysicsSocketConstraint.cpp \
     lua/lua_PhysicsSocketConstraint.cpp \
     lua/lua_PhysicsSpringConstraint.cpp \
     lua/lua_PhysicsSpringConstraint.cpp \
+    lua/lua_PhysicsVehicle.cpp \
+    lua/lua_PhysicsVehicleWheel.cpp \
     lua/lua_Plane.cpp \
     lua/lua_Plane.cpp \
     lua/lua_Platform.cpp \
     lua/lua_Platform.cpp \
     lua/lua_Properties.cpp \
     lua/lua_Properties.cpp \
@@ -275,4 +284,4 @@ LOCAL_STATIC_LIBRARIES := android_native_app_glue
 
 
 include $(BUILD_STATIC_LIBRARY)
 include $(BUILD_STATIC_LIBRARY)
 
 
-$(call import-module,android/native_app_glue)
+$(call import-module,android/native_app_glue)

+ 591 - 0
gameplay/gameplay.cbp

@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="gameplay" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="Debug">
+				<Option output="Debug/libgameplay" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="" />
+				<Option object_output="Debug/" />
+				<Option type="2" />
+				<Option compiler="gcc" />
+				<Option createDefFile="1" />
+				<Compiler>
+					<Add option="-g" />
+				</Compiler>
+			</Target>
+			<Target title="Release">
+				<Option output="Release/libgameplay" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="" />
+				<Option object_output="Release/" />
+				<Option type="2" />
+				<Option compiler="gcc" />
+				<Option createDefFile="1" />
+				<Compiler>
+					<Add option="-O2" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-pedantic" />
+			<Add option="-Wswitch" />
+			<Add option="-Wunused-variable" />
+			<Add directory="../external-deps/zlib/include" />
+			<Add directory="../external-deps/lua/include" />
+			<Add directory="../external-deps/libpng/include" />
+			<Add directory="../external-deps/bullet/include" />
+			<Add directory="../external-deps/oggvorbis/include" />
+			<Add directory="../gameplay/src" />
+		</Compiler>
+		<Linker>
+			<Add directory="../external-deps/lua/lib/linux" />
+			<Add directory="../external-deps/libpng/lib/linux" />
+			<Add directory="../external-deps/bullet/lib/linux" />
+			<Add directory="../external-deps/oggvorbis/lib/linux" />
+		</Linker>
+		<Unit filename="src/AIAgent.cpp" />
+		<Unit filename="src/AIAgent.h" />
+		<Unit filename="src/AIController.cpp" />
+		<Unit filename="src/AIController.h" />
+		<Unit filename="src/AIMessage.cpp" />
+		<Unit filename="src/AIMessage.h" />
+		<Unit filename="src/AIState.cpp" />
+		<Unit filename="src/AIState.h" />
+		<Unit filename="src/AIStateMachine.cpp" />
+		<Unit filename="src/AIStateMachine.h" />
+		<Unit filename="src/AbsoluteLayout.cpp" />
+		<Unit filename="src/AbsoluteLayout.h" />
+		<Unit filename="src/Animation.cpp" />
+		<Unit filename="src/Animation.h" />
+		<Unit filename="src/AnimationClip.cpp" />
+		<Unit filename="src/AnimationClip.h" />
+		<Unit filename="src/AnimationController.cpp" />
+		<Unit filename="src/AnimationController.h" />
+		<Unit filename="src/AnimationTarget.cpp" />
+		<Unit filename="src/AnimationTarget.h" />
+		<Unit filename="src/AnimationValue.cpp" />
+		<Unit filename="src/AnimationValue.h" />
+		<Unit filename="src/AudioBuffer.cpp" />
+		<Unit filename="src/AudioBuffer.h" />
+		<Unit filename="src/AudioController.cpp" />
+		<Unit filename="src/AudioController.h" />
+		<Unit filename="src/AudioListener.cpp" />
+		<Unit filename="src/AudioListener.h" />
+		<Unit filename="src/AudioSource.cpp" />
+		<Unit filename="src/AudioSource.h" />
+		<Unit filename="src/Base.h" />
+		<Unit filename="src/BoundingBox.cpp" />
+		<Unit filename="src/BoundingBox.h" />
+		<Unit filename="src/BoundingSphere.cpp" />
+		<Unit filename="src/BoundingSphere.h" />
+		<Unit filename="src/Bundle.cpp" />
+		<Unit filename="src/Bundle.h" />
+		<Unit filename="src/Button.cpp" />
+		<Unit filename="src/Button.h" />
+		<Unit filename="src/Camera.cpp" />
+		<Unit filename="src/Camera.h" />
+		<Unit filename="src/CheckBox.cpp" />
+		<Unit filename="src/CheckBox.h" />
+		<Unit filename="src/Container.cpp" />
+		<Unit filename="src/Container.h" />
+		<Unit filename="src/Control.cpp" />
+		<Unit filename="src/Control.h" />
+		<Unit filename="src/Curve.cpp" />
+		<Unit filename="src/Curve.h" />
+		<Unit filename="src/DebugNew.cpp" />
+		<Unit filename="src/DebugNew.h" />
+		<Unit filename="src/DepthStencilTarget.cpp" />
+		<Unit filename="src/DepthStencilTarget.h" />
+		<Unit filename="src/Effect.cpp" />
+		<Unit filename="src/Effect.h" />
+		<Unit filename="src/FileSystem.cpp" />
+		<Unit filename="src/FileSystem.h" />
+		<Unit filename="src/FlowLayout.cpp" />
+		<Unit filename="src/FlowLayout.h" />
+		<Unit filename="src/Font.cpp" />
+		<Unit filename="src/Font.h" />
+		<Unit filename="src/Form.cpp" />
+		<Unit filename="src/Form.h" />
+		<Unit filename="src/FrameBuffer.cpp" />
+		<Unit filename="src/FrameBuffer.h" />
+		<Unit filename="src/Frustum.cpp" />
+		<Unit filename="src/Frustum.h" />
+		<Unit filename="src/Game.cpp" />
+		<Unit filename="src/Game.h" />
+		<Unit filename="src/Gamepad.cpp" />
+		<Unit filename="src/Gamepad.h" />
+		<Unit filename="src/gameplay.h" />
+        <Unit filename="src/gameplay-main-android.cpp" />
+		<Unit filename="src/gameplay-main-blackberry.cpp" />
+		<Unit filename="src/gameplay-main-linux.cpp" />
+		<Unit filename="src/gameplay-main-windows.cpp" />
+		<Unit filename="src/Gesture.h" />
+		<Unit filename="src/Image.cpp" />
+		<Unit filename="src/Image.h" />
+		<Unit filename="src/Joint.cpp" />
+		<Unit filename="src/Joint.h" />
+		<Unit filename="src/Joystick.cpp" />
+		<Unit filename="src/Joystick.h" />
+		<Unit filename="src/Keyboard.h" />
+		<Unit filename="src/Label.cpp" />
+		<Unit filename="src/Label.h" />
+		<Unit filename="src/Layout.cpp" />
+		<Unit filename="src/Layout.h" />
+		<Unit filename="src/Light.cpp" />
+		<Unit filename="src/Light.h" />
+		<Unit filename="src/Logger.cpp" />
+		<Unit filename="src/Logger.h" />
+		<Unit filename="src/Material.cpp" />
+		<Unit filename="src/Material.h" />
+		<Unit filename="src/MaterialParameter.cpp" />
+		<Unit filename="src/MaterialParameter.h" />
+		<Unit filename="src/MathUtil.cpp" />
+		<Unit filename="src/MathUtil.h" />
+		<Unit filename="src/Matrix.cpp" />
+		<Unit filename="src/Matrix.h" />
+		<Unit filename="src/Mesh.cpp" />
+		<Unit filename="src/Mesh.h" />
+		<Unit filename="src/MeshBatch.cpp" />
+		<Unit filename="src/MeshBatch.h" />
+		<Unit filename="src/MeshPart.cpp" />
+		<Unit filename="src/MeshPart.h" />
+		<Unit filename="src/MeshSkin.cpp" />
+		<Unit filename="src/MeshSkin.h" />
+		<Unit filename="src/Model.cpp" />
+		<Unit filename="src/Model.h" />
+		<Unit filename="src/Mouse.h" />
+		<Unit filename="src/Node.cpp" />
+		<Unit filename="src/Node.h" />
+		<Unit filename="src/ParticleEmitter.cpp" />
+		<Unit filename="src/ParticleEmitter.h" />
+		<Unit filename="src/Pass.cpp" />
+		<Unit filename="src/Pass.h" />
+		<Unit filename="src/PhysicsCharacter.cpp" />
+		<Unit filename="src/PhysicsCharacter.h" />
+		<Unit filename="src/PhysicsCollisionObject.cpp" />
+		<Unit filename="src/PhysicsCollisionObject.h" />
+		<Unit filename="src/PhysicsCollisionShape.cpp" />
+		<Unit filename="src/PhysicsCollisionShape.h" />
+		<Unit filename="src/PhysicsConstraint.cpp" />
+		<Unit filename="src/PhysicsConstraint.h" />
+		<Unit filename="src/PhysicsController.cpp" />
+		<Unit filename="src/PhysicsController.h" />
+		<Unit filename="src/PhysicsFixedConstraint.cpp" />
+		<Unit filename="src/PhysicsFixedConstraint.h" />
+		<Unit filename="src/PhysicsGenericConstraint.cpp" />
+		<Unit filename="src/PhysicsGenericConstraint.h" />
+		<Unit filename="src/PhysicsGhostObject.cpp" />
+		<Unit filename="src/PhysicsGhostObject.h" />
+		<Unit filename="src/PhysicsHingeConstraint.cpp" />
+		<Unit filename="src/PhysicsHingeConstraint.h" />
+		<Unit filename="src/PhysicsRigidBody.cpp" />
+		<Unit filename="src/PhysicsRigidBody.h" />
+		<Unit filename="src/PhysicsSocketConstraint.cpp" />
+		<Unit filename="src/PhysicsSocketConstraint.h" />
+		<Unit filename="src/PhysicsSpringConstraint.cpp" />
+		<Unit filename="src/PhysicsSpringConstraint.h" />
+		<Unit filename="src/PhysicsVehicle.cpp" />
+		<Unit filename="src/PhysicsVehicle.h" />
+		<Unit filename="src/PhysicsVehicleWheel.cpp" />
+		<Unit filename="src/PhysicsVehicleWheel.h" />
+		<Unit filename="src/Plane.cpp" />
+		<Unit filename="src/Plane.h" />
+		<Unit filename="src/Platform.h" />
+		<Unit filename="src/PlatformAndroid.cpp" />
+		<Unit filename="src/PlatformBlackBerry.cpp" />
+		<Unit filename="src/PlatformLinux.cpp" />
+		<Unit filename="src/PlatformWindows.cpp" />
+		<Unit filename="src/Properties.cpp" />
+		<Unit filename="src/Properties.h" />
+		<Unit filename="src/Quaternion.cpp" />
+		<Unit filename="src/Quaternion.h" />
+		<Unit filename="src/RadioButton.cpp" />
+		<Unit filename="src/RadioButton.h" />
+		<Unit filename="src/Ray.cpp" />
+		<Unit filename="src/Ray.h" />
+		<Unit filename="src/Rectangle.cpp" />
+		<Unit filename="src/Rectangle.h" />
+		<Unit filename="src/Ref.cpp" />
+		<Unit filename="src/Ref.h" />
+		<Unit filename="src/RenderState.cpp" />
+		<Unit filename="src/RenderState.h" />
+		<Unit filename="src/RenderTarget.cpp" />
+		<Unit filename="src/RenderTarget.h" />
+		<Unit filename="src/Scene.cpp" />
+		<Unit filename="src/Scene.h" />
+		<Unit filename="src/SceneLoader.cpp" />
+		<Unit filename="src/SceneLoader.h" />
+		<Unit filename="src/ScreenDisplayer.cpp" />
+		<Unit filename="src/ScreenDisplayer.h" />
+		<Unit filename="src/ScriptController.cpp" />
+		<Unit filename="src/ScriptController.h" />
+		<Unit filename="src/ScriptTarget.cpp" />
+		<Unit filename="src/ScriptTarget.h" />
+		<Unit filename="src/Slider.cpp" />
+		<Unit filename="src/Slider.h" />
+		<Unit filename="src/SpriteBatch.cpp" />
+		<Unit filename="src/SpriteBatch.h" />
+		<Unit filename="src/Technique.cpp" />
+		<Unit filename="src/Technique.h" />
+		<Unit filename="src/TextBox.cpp" />
+		<Unit filename="src/TextBox.h" />
+		<Unit filename="src/Texture.cpp" />
+		<Unit filename="src/Texture.h" />
+		<Unit filename="src/Theme.cpp" />
+		<Unit filename="src/Theme.h" />
+		<Unit filename="src/ThemeStyle.cpp" />
+		<Unit filename="src/ThemeStyle.h" />
+		<Unit filename="src/TimeListener.h" />
+		<Unit filename="src/Touch.h" />
+		<Unit filename="src/Transform.cpp" />
+		<Unit filename="src/Transform.h" />
+		<Unit filename="src/Vector2.cpp" />
+		<Unit filename="src/Vector2.h" />
+		<Unit filename="src/Vector3.cpp" />
+		<Unit filename="src/Vector3.h" />
+		<Unit filename="src/Vector4.cpp" />
+		<Unit filename="src/Vector4.h" />
+		<Unit filename="src/VertexAttributeBinding.cpp" />
+		<Unit filename="src/VertexAttributeBinding.h" />
+		<Unit filename="src/VertexFormat.cpp" />
+		<Unit filename="src/VertexFormat.h" />
+		<Unit filename="src/VerticalLayout.cpp" />
+		<Unit filename="src/VerticalLayout.h" />
+		<Unit filename="src/lua/lua_AIAgent.cpp" />
+		<Unit filename="src/lua/lua_AIAgent.h" />
+		<Unit filename="src/lua/lua_AIAgentListener.cpp" />
+		<Unit filename="src/lua/lua_AIAgentListener.h" />
+		<Unit filename="src/lua/lua_AIController.cpp" />
+		<Unit filename="src/lua/lua_AIController.h" />
+		<Unit filename="src/lua/lua_AIMessage.cpp" />
+		<Unit filename="src/lua/lua_AIMessage.h" />
+		<Unit filename="src/lua/lua_AIMessageParameterType.cpp" />
+		<Unit filename="src/lua/lua_AIMessageParameterType.h" />
+		<Unit filename="src/lua/lua_AIState.cpp" />
+		<Unit filename="src/lua/lua_AIState.h" />
+		<Unit filename="src/lua/lua_AIStateListener.cpp" />
+		<Unit filename="src/lua/lua_AIStateListener.h" />
+		<Unit filename="src/lua/lua_AIStateMachine.cpp" />
+		<Unit filename="src/lua/lua_AIStateMachine.h" />
+		<Unit filename="src/lua/lua_AbsoluteLayout.cpp" />
+		<Unit filename="src/lua/lua_AbsoluteLayout.h" />
+		<Unit filename="src/lua/lua_Animation.cpp" />
+		<Unit filename="src/lua/lua_Animation.h" />
+		<Unit filename="src/lua/lua_AnimationClip.cpp" />
+		<Unit filename="src/lua/lua_AnimationClip.h" />
+		<Unit filename="src/lua/lua_AnimationClipListener.cpp" />
+		<Unit filename="src/lua/lua_AnimationClipListener.h" />
+		<Unit filename="src/lua/lua_AnimationClipListenerEventType.cpp" />
+		<Unit filename="src/lua/lua_AnimationClipListenerEventType.h" />
+		<Unit filename="src/lua/lua_AnimationController.cpp" />
+		<Unit filename="src/lua/lua_AnimationController.h" />
+		<Unit filename="src/lua/lua_AnimationTarget.cpp" />
+		<Unit filename="src/lua/lua_AnimationTarget.h" />
+		<Unit filename="src/lua/lua_AnimationValue.cpp" />
+		<Unit filename="src/lua/lua_AnimationValue.h" />
+		<Unit filename="src/lua/lua_AudioBuffer.cpp" />
+		<Unit filename="src/lua/lua_AudioBuffer.h" />
+		<Unit filename="src/lua/lua_AudioController.cpp" />
+		<Unit filename="src/lua/lua_AudioController.h" />
+		<Unit filename="src/lua/lua_AudioListener.cpp" />
+		<Unit filename="src/lua/lua_AudioListener.h" />
+		<Unit filename="src/lua/lua_AudioSource.cpp" />
+		<Unit filename="src/lua/lua_AudioSource.h" />
+		<Unit filename="src/lua/lua_AudioSourceState.cpp" />
+		<Unit filename="src/lua/lua_AudioSourceState.h" />
+		<Unit filename="src/lua/lua_BoundingBox.cpp" />
+		<Unit filename="src/lua/lua_BoundingBox.h" />
+		<Unit filename="src/lua/lua_BoundingSphere.cpp" />
+		<Unit filename="src/lua/lua_BoundingSphere.h" />
+		<Unit filename="src/lua/lua_Bundle.cpp" />
+		<Unit filename="src/lua/lua_Bundle.h" />
+		<Unit filename="src/lua/lua_Button.cpp" />
+		<Unit filename="src/lua/lua_Button.h" />
+		<Unit filename="src/lua/lua_Camera.cpp" />
+		<Unit filename="src/lua/lua_Camera.h" />
+		<Unit filename="src/lua/lua_CameraType.cpp" />
+		<Unit filename="src/lua/lua_CameraType.h" />
+		<Unit filename="src/lua/lua_CheckBox.cpp" />
+		<Unit filename="src/lua/lua_CheckBox.h" />
+		<Unit filename="src/lua/lua_Container.cpp" />
+		<Unit filename="src/lua/lua_Container.h" />
+		<Unit filename="src/lua/lua_ContainerScroll.cpp" />
+		<Unit filename="src/lua/lua_ContainerScroll.h" />
+		<Unit filename="src/lua/lua_Control.cpp" />
+		<Unit filename="src/lua/lua_Control.h" />
+		<Unit filename="src/lua/lua_ControlAlignment.cpp" />
+		<Unit filename="src/lua/lua_ControlAlignment.h" />
+		<Unit filename="src/lua/lua_ControlListener.cpp" />
+		<Unit filename="src/lua/lua_ControlListener.h" />
+		<Unit filename="src/lua/lua_ControlListenerEventType.cpp" />
+		<Unit filename="src/lua/lua_ControlListenerEventType.h" />
+		<Unit filename="src/lua/lua_ControlState.cpp" />
+		<Unit filename="src/lua/lua_ControlState.h" />
+		<Unit filename="src/lua/lua_Curve.cpp" />
+		<Unit filename="src/lua/lua_Curve.h" />
+		<Unit filename="src/lua/lua_CurveInterpolationType.cpp" />
+		<Unit filename="src/lua/lua_CurveInterpolationType.h" />
+		<Unit filename="src/lua/lua_DepthStencilTarget.cpp" />
+		<Unit filename="src/lua/lua_DepthStencilTarget.h" />
+		<Unit filename="src/lua/lua_DepthStencilTargetFormat.cpp" />
+		<Unit filename="src/lua/lua_DepthStencilTargetFormat.h" />
+		<Unit filename="src/lua/lua_Effect.cpp" />
+		<Unit filename="src/lua/lua_Effect.h" />
+		<Unit filename="src/lua/lua_FileSystem.cpp" />
+		<Unit filename="src/lua/lua_FileSystem.h" />
+		<Unit filename="src/lua/lua_FlowLayout.cpp" />
+		<Unit filename="src/lua/lua_FlowLayout.h" />
+		<Unit filename="src/lua/lua_Font.cpp" />
+		<Unit filename="src/lua/lua_Font.h" />
+		<Unit filename="src/lua/lua_FontJustify.cpp" />
+		<Unit filename="src/lua/lua_FontJustify.h" />
+		<Unit filename="src/lua/lua_FontStyle.cpp" />
+		<Unit filename="src/lua/lua_FontStyle.h" />
+		<Unit filename="src/lua/lua_FontText.cpp" />
+		<Unit filename="src/lua/lua_FontText.h" />
+		<Unit filename="src/lua/lua_Form.cpp" />
+		<Unit filename="src/lua/lua_Form.h" />
+		<Unit filename="src/lua/lua_FrameBuffer.cpp" />
+		<Unit filename="src/lua/lua_FrameBuffer.h" />
+		<Unit filename="src/lua/lua_Frustum.cpp" />
+		<Unit filename="src/lua/lua_Frustum.h" />
+		<Unit filename="src/lua/lua_Game.cpp" />
+		<Unit filename="src/lua/lua_Game.h" />
+		<Unit filename="src/lua/lua_GameClearFlags.cpp" />
+		<Unit filename="src/lua/lua_GameClearFlags.h" />
+		<Unit filename="src/lua/lua_GameState.cpp" />
+		<Unit filename="src/lua/lua_GameState.h" />
+		<Unit filename="src/lua/lua_Gamepad.cpp" />
+		<Unit filename="src/lua/lua_Gamepad.h" />
+		<Unit filename="src/lua/lua_GamepadButtonState.cpp" />
+		<Unit filename="src/lua/lua_GamepadButtonState.h" />
+		<Unit filename="src/lua/lua_GamepadGamepadEvent.cpp" />
+		<Unit filename="src/lua/lua_GamepadGamepadEvent.h" />
+		<Unit filename="src/lua/lua_Gesture.cpp" />
+		<Unit filename="src/lua/lua_Gesture.h" />
+		<Unit filename="src/lua/lua_GestureGestureEvent.cpp" />
+		<Unit filename="src/lua/lua_GestureGestureEvent.h" />
+		<Unit filename="src/lua/lua_Global.cpp" />
+		<Unit filename="src/lua/lua_Global.h" />
+		<Unit filename="src/lua/lua_Image.cpp" />
+		<Unit filename="src/lua/lua_Image.h" />
+		<Unit filename="src/lua/lua_ImageFormat.cpp" />
+		<Unit filename="src/lua/lua_ImageFormat.h" />
+		<Unit filename="src/lua/lua_Joint.cpp" />
+		<Unit filename="src/lua/lua_Joint.h" />
+		<Unit filename="src/lua/lua_Joystick.cpp" />
+		<Unit filename="src/lua/lua_Joystick.h" />
+		<Unit filename="src/lua/lua_Keyboard.cpp" />
+		<Unit filename="src/lua/lua_Keyboard.h" />
+		<Unit filename="src/lua/lua_KeyboardKey.cpp" />
+		<Unit filename="src/lua/lua_KeyboardKey.h" />
+		<Unit filename="src/lua/lua_KeyboardKeyEvent.cpp" />
+		<Unit filename="src/lua/lua_KeyboardKeyEvent.h" />
+		<Unit filename="src/lua/lua_Label.cpp" />
+		<Unit filename="src/lua/lua_Label.h" />
+		<Unit filename="src/lua/lua_Layout.cpp" />
+		<Unit filename="src/lua/lua_Layout.h" />
+		<Unit filename="src/lua/lua_LayoutType.cpp" />
+		<Unit filename="src/lua/lua_LayoutType.h" />
+		<Unit filename="src/lua/lua_Light.cpp" />
+		<Unit filename="src/lua/lua_Light.h" />
+		<Unit filename="src/lua/lua_LightType.cpp" />
+		<Unit filename="src/lua/lua_LightType.h" />
+		<Unit filename="src/lua/lua_Logger.cpp" />
+		<Unit filename="src/lua/lua_Logger.h" />
+		<Unit filename="src/lua/lua_LoggerLevel.cpp" />
+		<Unit filename="src/lua/lua_LoggerLevel.h" />
+		<Unit filename="src/lua/lua_Material.cpp" />
+		<Unit filename="src/lua/lua_Material.h" />
+		<Unit filename="src/lua/lua_MaterialParameter.cpp" />
+		<Unit filename="src/lua/lua_MaterialParameter.h" />
+		<Unit filename="src/lua/lua_MathUtil.cpp" />
+		<Unit filename="src/lua/lua_MathUtil.h" />
+		<Unit filename="src/lua/lua_Matrix.cpp" />
+		<Unit filename="src/lua/lua_Matrix.h" />
+		<Unit filename="src/lua/lua_Mesh.cpp" />
+		<Unit filename="src/lua/lua_Mesh.h" />
+		<Unit filename="src/lua/lua_MeshBatch.cpp" />
+		<Unit filename="src/lua/lua_MeshBatch.h" />
+		<Unit filename="src/lua/lua_MeshIndexFormat.cpp" />
+		<Unit filename="src/lua/lua_MeshIndexFormat.h" />
+		<Unit filename="src/lua/lua_MeshPart.cpp" />
+		<Unit filename="src/lua/lua_MeshPart.h" />
+		<Unit filename="src/lua/lua_MeshPrimitiveType.cpp" />
+		<Unit filename="src/lua/lua_MeshPrimitiveType.h" />
+		<Unit filename="src/lua/lua_MeshSkin.cpp" />
+		<Unit filename="src/lua/lua_MeshSkin.h" />
+		<Unit filename="src/lua/lua_Model.cpp" />
+		<Unit filename="src/lua/lua_Model.h" />
+		<Unit filename="src/lua/lua_Mouse.cpp" />
+		<Unit filename="src/lua/lua_Mouse.h" />
+		<Unit filename="src/lua/lua_MouseMouseEvent.cpp" />
+		<Unit filename="src/lua/lua_MouseMouseEvent.h" />
+		<Unit filename="src/lua/lua_Node.cpp" />
+		<Unit filename="src/lua/lua_Node.h" />
+		<Unit filename="src/lua/lua_NodeCloneContext.cpp" />
+		<Unit filename="src/lua/lua_NodeCloneContext.h" />
+		<Unit filename="src/lua/lua_NodeType.cpp" />
+		<Unit filename="src/lua/lua_NodeType.h" />
+		<Unit filename="src/lua/lua_ParticleEmitter.cpp" />
+		<Unit filename="src/lua/lua_ParticleEmitter.h" />
+		<Unit filename="src/lua/lua_ParticleEmitterTextureBlending.cpp" />
+		<Unit filename="src/lua/lua_ParticleEmitterTextureBlending.h" />
+		<Unit filename="src/lua/lua_Pass.cpp" />
+		<Unit filename="src/lua/lua_Pass.h" />
+		<Unit filename="src/lua/lua_PhysicsCharacter.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCharacter.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObject.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObject.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListener.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListener.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionPair.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionPair.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectType.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionObjectType.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShape.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShape.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShapeDefinition.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShapeDefinition.h" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShapeType.cpp" />
+		<Unit filename="src/lua/lua_PhysicsCollisionShapeType.h" />
+		<Unit filename="src/lua/lua_PhysicsConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsController.cpp" />
+		<Unit filename="src/lua/lua_PhysicsController.h" />
+		<Unit filename="src/lua/lua_PhysicsControllerHitFilter.cpp" />
+		<Unit filename="src/lua/lua_PhysicsControllerHitFilter.h" />
+		<Unit filename="src/lua/lua_PhysicsControllerHitResult.cpp" />
+		<Unit filename="src/lua/lua_PhysicsControllerHitResult.h" />
+		<Unit filename="src/lua/lua_PhysicsControllerListener.cpp" />
+		<Unit filename="src/lua/lua_PhysicsControllerListener.h" />
+		<Unit filename="src/lua/lua_PhysicsControllerListenerEventType.cpp" />
+		<Unit filename="src/lua/lua_PhysicsControllerListenerEventType.h" />
+		<Unit filename="src/lua/lua_PhysicsFixedConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsFixedConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsGenericConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsGenericConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsGhostObject.cpp" />
+		<Unit filename="src/lua/lua_PhysicsGhostObject.h" />
+		<Unit filename="src/lua/lua_PhysicsHingeConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsHingeConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsRigidBody.cpp" />
+		<Unit filename="src/lua/lua_PhysicsRigidBody.h" />
+		<Unit filename="src/lua/lua_PhysicsRigidBodyParameters.cpp" />
+		<Unit filename="src/lua/lua_PhysicsRigidBodyParameters.h" />
+		<Unit filename="src/lua/lua_PhysicsSocketConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsSocketConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsSpringConstraint.cpp" />
+		<Unit filename="src/lua/lua_PhysicsSpringConstraint.h" />
+		<Unit filename="src/lua/lua_PhysicsVehicle.cpp" />
+		<Unit filename="src/lua/lua_PhysicsVehicle.h" />
+		<Unit filename="src/lua/lua_PhysicsVehicleWheel.cpp" />
+		<Unit filename="src/lua/lua_PhysicsVehicleWheel.h" />
+		<Unit filename="src/lua/lua_Plane.cpp" />
+		<Unit filename="src/lua/lua_Plane.h" />
+		<Unit filename="src/lua/lua_Platform.cpp" />
+		<Unit filename="src/lua/lua_Platform.h" />
+		<Unit filename="src/lua/lua_Properties.cpp" />
+		<Unit filename="src/lua/lua_Properties.h" />
+		<Unit filename="src/lua/lua_PropertiesType.cpp" />
+		<Unit filename="src/lua/lua_PropertiesType.h" />
+		<Unit filename="src/lua/lua_Quaternion.cpp" />
+		<Unit filename="src/lua/lua_Quaternion.h" />
+		<Unit filename="src/lua/lua_RadioButton.cpp" />
+		<Unit filename="src/lua/lua_RadioButton.h" />
+		<Unit filename="src/lua/lua_Ray.cpp" />
+		<Unit filename="src/lua/lua_Ray.h" />
+		<Unit filename="src/lua/lua_Rectangle.cpp" />
+		<Unit filename="src/lua/lua_Rectangle.h" />
+		<Unit filename="src/lua/lua_Ref.cpp" />
+		<Unit filename="src/lua/lua_Ref.h" />
+		<Unit filename="src/lua/lua_RenderState.cpp" />
+		<Unit filename="src/lua/lua_RenderState.h" />
+		<Unit filename="src/lua/lua_RenderStateAutoBinding.cpp" />
+		<Unit filename="src/lua/lua_RenderStateAutoBinding.h" />
+		<Unit filename="src/lua/lua_RenderStateBlend.cpp" />
+		<Unit filename="src/lua/lua_RenderStateBlend.h" />
+		<Unit filename="src/lua/lua_RenderStateStateBlock.cpp" />
+		<Unit filename="src/lua/lua_RenderStateStateBlock.h" />
+		<Unit filename="src/lua/lua_RenderTarget.cpp" />
+		<Unit filename="src/lua/lua_RenderTarget.h" />
+		<Unit filename="src/lua/lua_Scene.cpp" />
+		<Unit filename="src/lua/lua_Scene.h" />
+		<Unit filename="src/lua/lua_SceneDebugFlags.cpp" />
+		<Unit filename="src/lua/lua_SceneDebugFlags.h" />
+		<Unit filename="src/lua/lua_ScreenDisplayer.cpp" />
+		<Unit filename="src/lua/lua_ScreenDisplayer.h" />
+		<Unit filename="src/lua/lua_ScriptController.cpp" />
+		<Unit filename="src/lua/lua_ScriptController.h" />
+		<Unit filename="src/lua/lua_ScriptTarget.cpp" />
+		<Unit filename="src/lua/lua_ScriptTarget.h" />
+		<Unit filename="src/lua/lua_Slider.cpp" />
+		<Unit filename="src/lua/lua_Slider.h" />
+		<Unit filename="src/lua/lua_SpriteBatch.cpp" />
+		<Unit filename="src/lua/lua_SpriteBatch.h" />
+		<Unit filename="src/lua/lua_Technique.cpp" />
+		<Unit filename="src/lua/lua_Technique.h" />
+		<Unit filename="src/lua/lua_TextBox.cpp" />
+		<Unit filename="src/lua/lua_TextBox.h" />
+		<Unit filename="src/lua/lua_Texture.cpp" />
+		<Unit filename="src/lua/lua_Texture.h" />
+		<Unit filename="src/lua/lua_TextureFilter.cpp" />
+		<Unit filename="src/lua/lua_TextureFilter.h" />
+		<Unit filename="src/lua/lua_TextureFormat.cpp" />
+		<Unit filename="src/lua/lua_TextureFormat.h" />
+		<Unit filename="src/lua/lua_TextureSampler.cpp" />
+		<Unit filename="src/lua/lua_TextureSampler.h" />
+		<Unit filename="src/lua/lua_TextureWrap.cpp" />
+		<Unit filename="src/lua/lua_TextureWrap.h" />
+		<Unit filename="src/lua/lua_Theme.cpp" />
+		<Unit filename="src/lua/lua_Theme.h" />
+		<Unit filename="src/lua/lua_ThemeSideRegions.cpp" />
+		<Unit filename="src/lua/lua_ThemeSideRegions.h" />
+		<Unit filename="src/lua/lua_ThemeStyle.cpp" />
+		<Unit filename="src/lua/lua_ThemeStyle.h" />
+		<Unit filename="src/lua/lua_ThemeThemeImage.cpp" />
+		<Unit filename="src/lua/lua_ThemeThemeImage.h" />
+		<Unit filename="src/lua/lua_ThemeUVs.cpp" />
+		<Unit filename="src/lua/lua_ThemeUVs.h" />
+		<Unit filename="src/lua/lua_Touch.cpp" />
+		<Unit filename="src/lua/lua_Touch.h" />
+		<Unit filename="src/lua/lua_TouchTouchEvent.cpp" />
+		<Unit filename="src/lua/lua_TouchTouchEvent.h" />
+		<Unit filename="src/lua/lua_Transform.cpp" />
+		<Unit filename="src/lua/lua_Transform.h" />
+		<Unit filename="src/lua/lua_TransformListener.cpp" />
+		<Unit filename="src/lua/lua_TransformListener.h" />
+		<Unit filename="src/lua/lua_Uniform.cpp" />
+		<Unit filename="src/lua/lua_Uniform.h" />
+		<Unit filename="src/lua/lua_Vector2.cpp" />
+		<Unit filename="src/lua/lua_Vector2.h" />
+		<Unit filename="src/lua/lua_Vector3.cpp" />
+		<Unit filename="src/lua/lua_Vector3.h" />
+		<Unit filename="src/lua/lua_Vector4.cpp" />
+		<Unit filename="src/lua/lua_Vector4.h" />
+		<Unit filename="src/lua/lua_VertexAttributeBinding.cpp" />
+		<Unit filename="src/lua/lua_VertexAttributeBinding.h" />
+		<Unit filename="src/lua/lua_VertexFormat.cpp" />
+		<Unit filename="src/lua/lua_VertexFormat.h" />
+		<Unit filename="src/lua/lua_VertexFormatElement.cpp" />
+		<Unit filename="src/lua/lua_VertexFormatElement.h" />
+		<Unit filename="src/lua/lua_VertexFormatUsage.cpp" />
+		<Unit filename="src/lua/lua_VertexFormatUsage.h" />
+		<Unit filename="src/lua/lua_VerticalLayout.cpp" />
+		<Unit filename="src/lua/lua_VerticalLayout.h" />
+		<Unit filename="src/lua/lua_all_bindings.cpp" />
+		<Unit filename="src/lua/lua_all_bindings.h" />
+		<Extensions>
+			<code_completion />
+			<debugger />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>

+ 255 - 8
gameplay/gameplay.vcxproj

@@ -1,14 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugMem|BlackBerry">
+      <Configuration>DebugMem</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|BlackBerrySimulator">
+      <Configuration>DebugMem</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugMem|Win32">
     <ProjectConfiguration Include="DebugMem|Win32">
       <Configuration>DebugMem</Configuration>
       <Configuration>DebugMem</Configuration>
       <Platform>Win32</Platform>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|BlackBerry">
+      <Configuration>Debug</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|BlackBerrySimulator">
+      <Configuration>Debug</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|BlackBerry">
+      <Configuration>Release</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|BlackBerrySimulator">
+      <Configuration>Release</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
       <Platform>Win32</Platform>
@@ -50,14 +74,16 @@
     <ClCompile Include="src\Game.cpp" />
     <ClCompile Include="src\Game.cpp" />
     <ClCompile Include="src\Gamepad.cpp" />
     <ClCompile Include="src\Gamepad.cpp" />
     <ClCompile Include="src\gameplay-main-android.cpp" />
     <ClCompile Include="src\gameplay-main-android.cpp" />
-    <ClCompile Include="src\gameplay-main-qnx.cpp" />
-    <ClCompile Include="src\gameplay-main-win32.cpp" />
+    <ClCompile Include="src\gameplay-main-blackberry.cpp" />
+    <ClCompile Include="src\gameplay-main-linux.cpp" />
+    <ClCompile Include="src\gameplay-main-windows.cpp" />
     <ClCompile Include="src\Image.cpp" />
     <ClCompile Include="src\Image.cpp" />
     <ClCompile Include="src\Joint.cpp" />
     <ClCompile Include="src\Joint.cpp" />
     <ClCompile Include="src\Joystick.cpp" />
     <ClCompile Include="src\Joystick.cpp" />
     <ClCompile Include="src\Label.cpp" />
     <ClCompile Include="src\Label.cpp" />
     <ClCompile Include="src\Layout.cpp" />
     <ClCompile Include="src\Layout.cpp" />
     <ClCompile Include="src\Light.cpp" />
     <ClCompile Include="src\Light.cpp" />
+    <ClCompile Include="src\Logger.cpp" />
     <ClCompile Include="src\lua\lua_AbsoluteLayout.cpp" />
     <ClCompile Include="src\lua\lua_AbsoluteLayout.cpp" />
     <ClCompile Include="src\lua\lua_AIAgent.cpp" />
     <ClCompile Include="src\lua\lua_AIAgent.cpp" />
     <ClCompile Include="src\lua\lua_AIAgentListener.cpp" />
     <ClCompile Include="src\lua\lua_AIAgentListener.cpp" />
@@ -114,6 +140,8 @@
     <ClCompile Include="src\lua\lua_GamepadButtonState.cpp" />
     <ClCompile Include="src\lua\lua_GamepadButtonState.cpp" />
     <ClCompile Include="src\lua\lua_GamepadGamepadEvent.cpp" />
     <ClCompile Include="src\lua\lua_GamepadGamepadEvent.cpp" />
     <ClCompile Include="src\lua\lua_GameState.cpp" />
     <ClCompile Include="src\lua\lua_GameState.cpp" />
+    <ClCompile Include="src\lua\lua_Gesture.cpp" />
+    <ClCompile Include="src\lua\lua_GestureGestureEvent.cpp" />
     <ClCompile Include="src\lua\lua_Global.cpp" />
     <ClCompile Include="src\lua\lua_Global.cpp" />
     <ClCompile Include="src\lua\lua_Image.cpp" />
     <ClCompile Include="src\lua\lua_Image.cpp" />
     <ClCompile Include="src\lua\lua_ImageFormat.cpp" />
     <ClCompile Include="src\lua\lua_ImageFormat.cpp" />
@@ -127,6 +155,8 @@
     <ClCompile Include="src\lua\lua_LayoutType.cpp" />
     <ClCompile Include="src\lua\lua_LayoutType.cpp" />
     <ClCompile Include="src\lua\lua_Light.cpp" />
     <ClCompile Include="src\lua\lua_Light.cpp" />
     <ClCompile Include="src\lua\lua_LightType.cpp" />
     <ClCompile Include="src\lua\lua_LightType.cpp" />
+    <ClCompile Include="src\lua\lua_Logger.cpp" />
+    <ClCompile Include="src\lua\lua_LoggerLevel.cpp" />
     <ClCompile Include="src\lua\lua_Material.cpp" />
     <ClCompile Include="src\lua\lua_Material.cpp" />
     <ClCompile Include="src\lua\lua_MaterialParameter.cpp" />
     <ClCompile Include="src\lua\lua_MaterialParameter.cpp" />
     <ClCompile Include="src\lua\lua_MathUtil.cpp" />
     <ClCompile Include="src\lua\lua_MathUtil.cpp" />
@@ -169,6 +199,8 @@
     <ClCompile Include="src\lua\lua_PhysicsRigidBodyParameters.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsRigidBodyParameters.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSpringConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSpringConstraint.cpp" />
+    <ClCompile Include="src\lua\lua_PhysicsVehicle.cpp" />
+    <ClCompile Include="src\lua\lua_PhysicsVehicleWheel.cpp" />
     <ClCompile Include="src\lua\lua_Plane.cpp" />
     <ClCompile Include="src\lua\lua_Plane.cpp" />
     <ClCompile Include="src\lua\lua_Platform.cpp" />
     <ClCompile Include="src\lua\lua_Platform.cpp" />
     <ClCompile Include="src\lua\lua_Properties.cpp" />
     <ClCompile Include="src\lua\lua_Properties.cpp" />
@@ -216,6 +248,7 @@
     <ClCompile Include="src\lua\lua_VertexFormatUsage.cpp" />
     <ClCompile Include="src\lua\lua_VertexFormatUsage.cpp" />
     <ClCompile Include="src\lua\lua_VerticalLayout.cpp" />
     <ClCompile Include="src\lua\lua_VerticalLayout.cpp" />
     <ClCompile Include="src\Material.cpp" />
     <ClCompile Include="src\Material.cpp" />
+    <ClCompile Include="src\MathUtil.cpp" />
     <ClCompile Include="src\MeshBatch.cpp" />
     <ClCompile Include="src\MeshBatch.cpp" />
     <ClCompile Include="src\Pass.cpp" />
     <ClCompile Include="src\Pass.cpp" />
     <ClCompile Include="src\MaterialParameter.cpp" />
     <ClCompile Include="src\MaterialParameter.cpp" />
@@ -239,10 +272,13 @@
     <ClCompile Include="src\PhysicsRigidBody.cpp" />
     <ClCompile Include="src\PhysicsRigidBody.cpp" />
     <ClCompile Include="src\PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\PhysicsSpringConstraint.cpp" />
     <ClCompile Include="src\PhysicsSpringConstraint.cpp" />
+    <ClCompile Include="src\PhysicsVehicle.cpp" />
+    <ClCompile Include="src\PhysicsVehicleWheel.cpp" />
     <ClCompile Include="src\Plane.cpp" />
     <ClCompile Include="src\Plane.cpp" />
     <ClCompile Include="src\PlatformAndroid.cpp" />
     <ClCompile Include="src\PlatformAndroid.cpp" />
-    <ClCompile Include="src\PlatformQNX.cpp" />
-    <ClCompile Include="src\PlatformWin32.cpp" />
+    <ClCompile Include="src\PlatformBlackBerry.cpp" />
+    <ClCompile Include="src\PlatformLinux.cpp" />
+    <ClCompile Include="src\PlatformWindows.cpp" />
     <ClCompile Include="src\Properties.cpp" />
     <ClCompile Include="src\Properties.cpp" />
     <ClCompile Include="src\Quaternion.cpp" />
     <ClCompile Include="src\Quaternion.cpp" />
     <ClCompile Include="src\RadioButton.cpp" />
     <ClCompile Include="src\RadioButton.cpp" />
@@ -308,6 +344,7 @@
     <ClInclude Include="src\Game.h" />
     <ClInclude Include="src\Game.h" />
     <ClInclude Include="src\Gamepad.h" />
     <ClInclude Include="src\Gamepad.h" />
     <ClInclude Include="src\gameplay.h" />
     <ClInclude Include="src\gameplay.h" />
+    <ClInclude Include="src\Gesture.h" />
     <ClInclude Include="src\Image.h" />
     <ClInclude Include="src\Image.h" />
     <ClInclude Include="src\Joint.h" />
     <ClInclude Include="src\Joint.h" />
     <ClInclude Include="src\Joystick.h" />
     <ClInclude Include="src\Joystick.h" />
@@ -315,6 +352,7 @@
     <ClInclude Include="src\Label.h" />
     <ClInclude Include="src\Label.h" />
     <ClInclude Include="src\Layout.h" />
     <ClInclude Include="src\Layout.h" />
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\Light.h" />
+    <ClInclude Include="src\Logger.h" />
     <ClInclude Include="src\lua\lua_AbsoluteLayout.h" />
     <ClInclude Include="src\lua\lua_AbsoluteLayout.h" />
     <ClInclude Include="src\lua\lua_AIAgent.h" />
     <ClInclude Include="src\lua\lua_AIAgent.h" />
     <ClInclude Include="src\lua\lua_AIAgentListener.h" />
     <ClInclude Include="src\lua\lua_AIAgentListener.h" />
@@ -371,6 +409,8 @@
     <ClInclude Include="src\lua\lua_GamepadButtonState.h" />
     <ClInclude Include="src\lua\lua_GamepadButtonState.h" />
     <ClInclude Include="src\lua\lua_GamepadGamepadEvent.h" />
     <ClInclude Include="src\lua\lua_GamepadGamepadEvent.h" />
     <ClInclude Include="src\lua\lua_GameState.h" />
     <ClInclude Include="src\lua\lua_GameState.h" />
+    <ClInclude Include="src\lua\lua_Gesture.h" />
+    <ClInclude Include="src\lua\lua_GestureGestureEvent.h" />
     <ClInclude Include="src\lua\lua_Global.h" />
     <ClInclude Include="src\lua\lua_Global.h" />
     <ClInclude Include="src\lua\lua_Image.h" />
     <ClInclude Include="src\lua\lua_Image.h" />
     <ClInclude Include="src\lua\lua_ImageFormat.h" />
     <ClInclude Include="src\lua\lua_ImageFormat.h" />
@@ -384,6 +424,8 @@
     <ClInclude Include="src\lua\lua_LayoutType.h" />
     <ClInclude Include="src\lua\lua_LayoutType.h" />
     <ClInclude Include="src\lua\lua_Light.h" />
     <ClInclude Include="src\lua\lua_Light.h" />
     <ClInclude Include="src\lua\lua_LightType.h" />
     <ClInclude Include="src\lua\lua_LightType.h" />
+    <ClInclude Include="src\lua\lua_Logger.h" />
+    <ClInclude Include="src\lua\lua_LoggerLevel.h" />
     <ClInclude Include="src\lua\lua_Material.h" />
     <ClInclude Include="src\lua\lua_Material.h" />
     <ClInclude Include="src\lua\lua_MaterialParameter.h" />
     <ClInclude Include="src\lua\lua_MaterialParameter.h" />
     <ClInclude Include="src\lua\lua_MathUtil.h" />
     <ClInclude Include="src\lua\lua_MathUtil.h" />
@@ -426,6 +468,8 @@
     <ClInclude Include="src\lua\lua_PhysicsRigidBodyParameters.h" />
     <ClInclude Include="src\lua\lua_PhysicsRigidBodyParameters.h" />
     <ClInclude Include="src\lua\lua_PhysicsSocketConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSocketConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSpringConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSpringConstraint.h" />
+    <ClInclude Include="src\lua\lua_PhysicsVehicle.h" />
+    <ClInclude Include="src\lua\lua_PhysicsVehicleWheel.h" />
     <ClInclude Include="src\lua\lua_Plane.h" />
     <ClInclude Include="src\lua\lua_Plane.h" />
     <ClInclude Include="src\lua\lua_Platform.h" />
     <ClInclude Include="src\lua\lua_Platform.h" />
     <ClInclude Include="src\lua\lua_Properties.h" />
     <ClInclude Include="src\lua\lua_Properties.h" />
@@ -498,6 +542,8 @@
     <ClInclude Include="src\PhysicsRigidBody.h" />
     <ClInclude Include="src\PhysicsRigidBody.h" />
     <ClInclude Include="src\PhysicsSocketConstraint.h" />
     <ClInclude Include="src\PhysicsSocketConstraint.h" />
     <ClInclude Include="src\PhysicsSpringConstraint.h" />
     <ClInclude Include="src\PhysicsSpringConstraint.h" />
+    <ClInclude Include="src\PhysicsVehicle.h" />
+    <ClInclude Include="src\PhysicsVehicleWheel.h" />
     <ClInclude Include="src\Plane.h" />
     <ClInclude Include="src\Plane.h" />
     <ClInclude Include="src\Platform.h" />
     <ClInclude Include="src\Platform.h" />
     <ClInclude Include="src\Properties.h" />
     <ClInclude Include="src\Properties.h" />
@@ -557,8 +603,6 @@
     <None Include="src\BoundingBox.inl" />
     <None Include="src\BoundingBox.inl" />
     <None Include="src\BoundingSphere.inl" />
     <None Include="src\BoundingSphere.inl" />
     <None Include="src\Game.inl" />
     <None Include="src\Game.inl" />
-    <None Include="src\gameplay-main-ios.mm" />
-    <None Include="src\gameplay-main-macosx.mm" />
     <None Include="src\Image.inl" />
     <None Include="src\Image.inl" />
     <None Include="src\MathUtil.inl" />
     <None Include="src\MathUtil.inl" />
     <None Include="src\MathUtilNeon.inl" />
     <None Include="src\MathUtilNeon.inl" />
@@ -566,8 +610,6 @@
     <None Include="src\Matrix.inl" />
     <None Include="src\Matrix.inl" />
     <None Include="src\MeshBatch.inl" />
     <None Include="src\MeshBatch.inl" />
     <None Include="src\Plane.inl" />
     <None Include="src\Plane.inl" />
-    <None Include="src\PlatformiOS.mm" />
-    <None Include="src\PlatformMacOSX.mm" />
     <None Include="src\Quaternion.inl" />
     <None Include="src\Quaternion.inl" />
     <None Include="src\Ray.inl" />
     <None Include="src\Ray.inl" />
     <None Include="src\ScriptController.inl" />
     <None Include="src\ScriptController.inl" />
@@ -593,48 +635,140 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
   <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" />
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'" 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'">
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <OutDir>$(Configuration)\</OutDir>
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <OutDir>$(Configuration)\</OutDir>
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <IntDir>$(Configuration)\</IntDir>
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <IntDir>$(Configuration)\</IntDir>
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <OutDir>$(Configuration)\</OutDir>
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <IntDir>$(Configuration)\</IntDir>
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
     <ClCompile>
       <PrecompiledHeader>
       <PrecompiledHeader>
@@ -652,6 +786,41 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <GenerateDebugInformation>true</GenerateDebugInformation>
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <ClCompile>
     <ClCompile>
       <PrecompiledHeader>
       <PrecompiledHeader>
@@ -672,6 +841,47 @@
       </Verbose>
       </Verbose>
     </Lib>
     </Lib>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
@@ -690,6 +900,43 @@
       <OptimizeReferences>true</OptimizeReferences>
       <OptimizeReferences>true</OptimizeReferences>
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
   </ImportGroup>

+ 74 - 20
gameplay/gameplay.vcxproj.filters

@@ -81,10 +81,16 @@
     <ClCompile Include="src\Plane.cpp">
     <ClCompile Include="src\Plane.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="src\PlatformQNX.cpp">
+    <ClCompile Include="src\gameplay-main-blackberry.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="src\PlatformWin32.cpp">
+    <ClCompile Include="src\PlatformBlackBerry.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\gameplay-main-windows.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\PlatformWindows.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
     <ClCompile Include="src\Quaternion.cpp">
     <ClCompile Include="src\Quaternion.cpp">
@@ -165,12 +171,6 @@
     <ClCompile Include="src\RenderState.cpp">
     <ClCompile Include="src\RenderState.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </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">
     <ClCompile Include="src\DebugNew.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
@@ -783,6 +783,42 @@
     <ClCompile Include="src\lua\lua_ScriptTarget.cpp">
     <ClCompile Include="src\lua\lua_ScriptTarget.cpp">
       <Filter>lua</Filter>
       <Filter>lua</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\gameplay-main-linux.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\PlatformLinux.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_Gesture.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_GestureGestureEvent.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\PhysicsVehicle.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\PhysicsVehicleWheel.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_PhysicsVehicle.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_PhysicsVehicleWheel.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\MathUtil.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Logger.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_LoggerLevel.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_Logger.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
     <ClInclude Include="src\Animation.h">
@@ -1556,14 +1592,38 @@
     <ClInclude Include="src\lua\lua_ScriptTarget.h">
     <ClInclude Include="src\lua\lua_ScriptTarget.h">
       <Filter>lua</Filter>
       <Filter>lua</Filter>
     </ClInclude>
     </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="src\gameplay-main-macosx.mm">
+    <ClInclude Include="src\Gesture.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
-    </None>
-    <None Include="src\PlatformMacOSX.mm">
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_Gesture.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_GestureGestureEvent.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\PhysicsVehicleWheel.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
-    </None>
+    </ClInclude>
+    <ClInclude Include="src\PhysicsVehicle.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_PhysicsVehicle.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_PhysicsVehicleWheel.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Logger.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_Logger.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_LoggerLevel.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
     <None Include="src\Game.inl">
     <None Include="src\Game.inl">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </None>
     </None>
@@ -1573,12 +1633,6 @@
     <None Include="src\MeshBatch.inl">
     <None Include="src\MeshBatch.inl">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </None>
     </None>
-    <None Include="src\gameplay-main-ios.mm">
-      <Filter>src</Filter>
-    </None>
-    <None Include="src\PlatformiOS.mm">
-      <Filter>src</Filter>
-    </None>
     <None Include="res\logo_black.png">
     <None Include="res\logo_black.png">
       <Filter>res</Filter>
       <Filter>res</Filter>
     </None>
     </None>

文件差異過大導致無法顯示
+ 996 - 3
gameplay/gameplay.xcodeproj/project.pbxproj


+ 58 - 0
gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "5B04C52B14BFCFE100EB0071"
+               BuildableName = "libgameplay.a"
+               BlueprintName = "gameplay-ios"
+               ReferencedContainer = "container:gameplay.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 58 - 0
gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "4234D99914686C52003031B3"
+               BuildableName = "libgameplay.a"
+               BlueprintName = "gameplay-macosx"
+               ReferencedContainer = "container:gameplay.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 4 - 1
gameplay/res/shaders/colored-unlit.frag

@@ -6,6 +6,9 @@ precision highp float;
 #if defined(VERTEX_COLOR)
 #if defined(VERTEX_COLOR)
 varying vec3 v_color;						// Input Vertex color ( r g b )
 varying vec3 v_color;						// Input Vertex color ( r g b )
 #endif
 #endif
+#if defined(TEXTURE_LIGHTMAP)
+varying vec2 v_texCoord;
+#endif
 
 
 // Uniforms
 // Uniforms
 uniform vec4 u_diffuseColor;               	// Diffuse color
 uniform vec4 u_diffuseColor;               	// Diffuse color
@@ -30,7 +33,7 @@ void main()
     #endif
     #endif
 	#if defined(TEXTURE_LIGHTMAP)
 	#if defined(TEXTURE_LIGHTMAP)
 	vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord);
 	vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord);
-	gl_FragColor.a *= lightColor.a;
+	gl_FragColor.rgb *= lightColor.rgb;
 	#endif
 	#endif
 	// Global color modulation
 	// Global color modulation
 	#if defined(MODULATE_COLOR)
 	#if defined(MODULATE_COLOR)

+ 16 - 2
gameplay/res/shaders/colored-unlit.vert

@@ -1,14 +1,23 @@
 // Inputs
 // Inputs
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
+#if defined(TEXTURE_LIGHTMAP)
+attribute vec2 a_texCoord;                                  // Texture Coordinate (for lightmapping)
+#endif
 #if defined(SKINNING)
 #if defined(SKINNING)
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
 #endif
 #endif
 #if defined(VERTEX_COLOR)
 #if defined(VERTEX_COLOR)
 attribute vec3 a_color;										// Vertex Color								(r, g, b)
 attribute vec3 a_color;										// Vertex Color								(r, g, b)
-varying vec3 v_color;										// Output Vertex color						(r, g, b)
 #endif
 #endif
 
 
+// Outputs
+#if defined(TEXTURE_LIGHTMAP)
+varying vec2 v_texCoord;                                    // Output Texture Coordinate
+#endif
+#if defined(VERTEX_COLOR)
+varying vec3 v_color;										// Output Vertex color						(r, g, b)
+#endif
 
 
 // Uniforms
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
@@ -32,8 +41,13 @@ void main()
     // Transform position to clip space.a
     // Transform position to clip space.a
     gl_Position = u_worldViewProjectionMatrix *  position;
     gl_Position = u_worldViewProjectionMatrix *  position;
     
     
+    // Pass lightmap tex coord to fragment shader
+    #if defined(TEXTURE_LIGHTMAP)
+    v_texCoord0 = a_texCoord0;
+    #endif
+
      // Pass on vertex color to fragment shader
      // Pass on vertex color to fragment shader
     #if defined(VERTEX_COLOR)
     #if defined(VERTEX_COLOR)
 	v_color = a_color;
 	v_color = a_color;
     #endif
     #endif
-}
+}

+ 11 - 4
gameplay/res/shaders/textured-unlit.frag

@@ -15,16 +15,23 @@ uniform float u_modulateAlpha;              // Modulation alpha
 #endif
 #endif
 
 
 // Inputs
 // Inputs
-varying vec2 v_texCoord;                	// Texture coordinate(u, v)
+varying vec2 v_texCoord0;                	// Texture coordinate(u, v)
+#if defined(TEXCOORD1)
+varying vec2 v_texCoord1;                   // Second tex coord for multi-texturing
+#endif
 
 
 // Fragment Program
 // Fragment Program
 void main()
 void main()
 {
 {
     // Sample the texture for the color
     // Sample the texture for the color
-    gl_FragColor = texture2D(u_diffuseTexture, v_texCoord);
+    gl_FragColor = texture2D(u_diffuseTexture, v_texCoord0);
 	#if defined(TEXTURE_LIGHTMAP)
 	#if defined(TEXTURE_LIGHTMAP)
-	vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord);
-	gl_FragColor.a *= lightColor.a;
+    #if defined(TEXCOORD1)
+    vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord1);
+    #else
+    vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord0);
+    #endif
+    gl_FragColor.rgb *= lightColor.rgb;
 	#endif
 	#endif
 	// Global color modulation
 	// Global color modulation
 	#if defined(MODULATE_COLOR)
 	#if defined(MODULATE_COLOR)

+ 14 - 5
gameplay/res/shaders/textured-unlit.vert

@@ -1,6 +1,9 @@
 // Inputs
 // Inputs
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
-attribute vec2 a_texCoord;									// Vertex Texture Coordinate				(u, v)
+attribute vec2 a_texCoord0;									// Vertex Texture Coordinate				(u, v)
+#if defined(TEXCOORD1)
+attribute vec2 a_texCoord1;                                 // Second tex coord for multi-texturing
+#endif
 #if defined(SKINNING)
 #if defined(SKINNING)
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendWeights;								// Vertex blend weight, up to 4				(0, 1, 2, 3) 
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
 attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette	(0, 1, 2, 3)
@@ -19,7 +22,10 @@ uniform vec2 u_textureOffset;								// Texture offset
 #endif
 #endif
 
 
 // Outputs
 // Outputs
-varying vec2 v_texCoord;									// Texture Coordinate
+varying vec2 v_texCoord0;									// Texture Coordinate
+#if defined(TEXCOORD1)
+varying vec2 v_texCoord1;                                   // Second tex coord for multi-texturing
+#endif
 
 
 // Vertex attribute accessors
 // Vertex attribute accessors
 #if defined(SKINNING)
 #if defined(SKINNING)
@@ -38,11 +44,14 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
     gl_Position = u_worldViewProjectionMatrix * position;
 
 
     // Texture transformation.
     // Texture transformation.
-    v_texCoord = a_texCoord;
+    v_texCoord0 = a_texCoord0;
+    #if defined(TEXCOORD1)
+    v_texCoord1 = a_texCoord1;
+    #endif
     #if defined(TEXTURE_REPEAT)
     #if defined(TEXTURE_REPEAT)
-    v_texCoord *= u_textureRepeat;
+    v_texCoord0 *= u_textureRepeat;
     #endif
     #endif
     #if defined(TEXTURE_OFFSET)
     #if defined(TEXTURE_OFFSET)
-    v_texCoord += u_textureOffset;
+    v_texCoord0 += u_textureOffset;
     #endif
     #endif
 }
 }

+ 24 - 23
gameplay/src/Animation.cpp

@@ -15,17 +15,18 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
-    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
+Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
+    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
 {
 {
-    createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
+    createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
+
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     release();
     release();
     GP_ASSERT(getRefCount() == 1);
     GP_ASSERT(getRefCount() == 1);
 }
 }
 
 
-Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
-    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
+Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
+    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
 {
 {
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
@@ -34,7 +35,7 @@ Animation::Animation(const char* id, AnimationTarget* target, int propertyId, un
 }
 }
 
 
 Animation::Animation(const char* id)
 Animation::Animation(const char* id)
-    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
+    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
 {
 {
 }
 }
 
 
@@ -55,9 +56,9 @@ Animation::~Animation()
     if (_clips)
     if (_clips)
     {
     {
         std::vector<AnimationClip*>::iterator clipIter = _clips->begin();
         std::vector<AnimationClip*>::iterator clipIter = _clips->begin();
-    
+
         while (clipIter != _clips->end())
         while (clipIter != _clips->end())
-        {   
+        {
             AnimationClip* clip = *clipIter;
             AnimationClip* clip = *clipIter;
             GP_ASSERT(clip);
             GP_ASSERT(clip);
             if (clip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
             if (clip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
@@ -127,7 +128,7 @@ void Animation::createClips(const char* url)
 
 
     Properties* pAnimation = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
     Properties* pAnimation = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
     GP_ASSERT(pAnimation);
     GP_ASSERT(pAnimation);
-    
+
     int frameCount = pAnimation->getInt("frameCount");
     int frameCount = pAnimation->getInt("frameCount");
     if (frameCount <= 0)
     if (frameCount <= 0)
         GP_ERROR("The animation's frame count must be greater than 0.");
         GP_ERROR("The animation's frame count must be greater than 0.");
@@ -180,7 +181,7 @@ void Animation::play(const char* clipId)
     {
     {
         if (_defaultClip == NULL)
         if (_defaultClip == NULL)
             createDefaultClip();
             createDefaultClip();
-        
+
         _defaultClip->play();
         _defaultClip->play();
     }
     }
     else
     else
@@ -245,9 +246,9 @@ void Animation::createDefaultClip()
 void Animation::createClips(Properties* animationProperties, unsigned int frameCount)
 void Animation::createClips(Properties* animationProperties, unsigned int frameCount)
 {
 {
     GP_ASSERT(animationProperties);
     GP_ASSERT(animationProperties);
-    
+
     Properties* pClip = animationProperties->getNextNamespace();
     Properties* pClip = animationProperties->getNextNamespace();
-    
+
     while (pClip != NULL && std::strcmp(pClip->getNamespace(), "clip") == 0)
     while (pClip != NULL && std::strcmp(pClip->getNamespace(), "clip") == 0)
     {
     {
         int begin = pClip->getInt("begin");
         int begin = pClip->getInt("begin");
@@ -296,8 +297,8 @@ AnimationClip* Animation::findClip(const char* id) const
     if (_clips)
     if (_clips)
     {
     {
         AnimationClip* clip = NULL;
         AnimationClip* clip = NULL;
-        unsigned int clipCount = _clips->size();
-        for (unsigned int i = 0; i < clipCount; i++)
+        size_t clipCount = _clips->size();
+        for (size_t i = 0; i < clipCount; i++)
         {
         {
             clip = _clips->at(i);
             clip = _clips->at(i);
             GP_ASSERT(clip);
             GP_ASSERT(clip);
@@ -310,7 +311,7 @@ AnimationClip* Animation::findClip(const char* id) const
     return NULL;
     return NULL;
 }
 }
 
 
-Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
+Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
 {
 {
     GP_ASSERT(target);
     GP_ASSERT(target);
     GP_ASSERT(keyTimes);
     GP_ASSERT(keyTimes);
@@ -324,7 +325,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     if (target->_targetType == AnimationTarget::TRANSFORM)
     if (target->_targetType == AnimationTarget::TRANSFORM)
         setTransformRotationOffset(curve, propertyId);
         setTransformRotationOffset(curve, propertyId);
 
 
-    unsigned long lowest = keyTimes[0];
+    unsigned int lowest = keyTimes[0];
     unsigned long duration = keyTimes[keyCount-1] - lowest;
     unsigned long duration = keyTimes[keyCount-1] - lowest;
 
 
     float* normalizedKeyTimes = new float[keyCount];
     float* normalizedKeyTimes = new float[keyCount];
@@ -344,7 +345,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     normalizedKeyTimes[i] = 1.0f;
     normalizedKeyTimes[i] = 1.0f;
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);
 
 
-    SAFE_DELETE(normalizedKeyTimes);
+    SAFE_DELETE_ARRAY(normalizedKeyTimes);
 
 
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     curve->release();
     curve->release();
@@ -352,7 +353,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     return channel;
     return channel;
 }
 }
 
 
-Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
+Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
 {
 {
     GP_ASSERT(target);
     GP_ASSERT(target);
     GP_ASSERT(keyTimes);
     GP_ASSERT(keyTimes);
@@ -365,12 +366,12 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     GP_ASSERT(curve);
     GP_ASSERT(curve);
     if (target->_targetType == AnimationTarget::TRANSFORM)
     if (target->_targetType == AnimationTarget::TRANSFORM)
         setTransformRotationOffset(curve, propertyId);
         setTransformRotationOffset(curve, propertyId);
-    
+
     unsigned long lowest = keyTimes[0];
     unsigned long lowest = keyTimes[0];
     unsigned long duration = keyTimes[keyCount-1] - lowest;
     unsigned long duration = keyTimes[keyCount-1] - lowest;
 
 
     float* normalizedKeyTimes = new float[keyCount];
     float* normalizedKeyTimes = new float[keyCount];
-    
+
     normalizedKeyTimes[0] = 0.0f;
     normalizedKeyTimes[0] = 0.0f;
     curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type, keyInValue, keyOutValue);
     curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type, keyInValue, keyOutValue);
 
 
@@ -386,7 +387,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     normalizedKeyTimes[i] = 1.0f;
     normalizedKeyTimes[i] = 1.0f;
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);
 
 
-    SAFE_DELETE(normalizedKeyTimes);
+    SAFE_DELETE_ARRAY(normalizedKeyTimes);
 
 
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     curve->release();
     curve->release();
@@ -398,7 +399,7 @@ void Animation::addChannel(Channel* channel)
 {
 {
     GP_ASSERT(channel);
     GP_ASSERT(channel);
     _channels.push_back(channel);
     _channels.push_back(channel);
-    
+
     if (channel->_duration > _duration)
     if (channel->_duration > _duration)
         _duration = channel->_duration;
         _duration = channel->_duration;
 }
 }
@@ -409,7 +410,7 @@ void Animation::removeChannel(Channel* channel)
     while (itr != _channels.end())
     while (itr != _channels.end())
     {
     {
         Animation::Channel* chan = *itr;
         Animation::Channel* chan = *itr;
-        if (channel == chan) 
+        if (channel == chan)
         {
         {
             _channels.erase(itr);
             _channels.erase(itr);
             return;
             return;

+ 30 - 29
gameplay/src/Animation.h

@@ -27,14 +27,14 @@ class Animation : public Ref
     friend class Bundle;
     friend class Bundle;
 
 
 public:
 public:
-    
+
     /**
     /**
      * Gets the Animation's ID.
      * Gets the Animation's ID.
-     * 
+     *
      * @return The Animation's ID.
      * @return The Animation's ID.
      */
      */
     const char* getId() const;
     const char* getId() const;
-    
+
     /**
     /**
      * Gets the Animation's duration.
      * Gets the Animation's duration.
      *
      *
@@ -43,28 +43,29 @@ public:
     unsigned long getDuration() const;
     unsigned long getDuration() const;
 
 
     /**
     /**
-     * Creates an AnimationClip from the Properties object defined at the specified URL, 
+     * Creates an AnimationClip from the Properties object defined at the specified URL,
      * where the URL is of the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
      * where the URL is of the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
      * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
      * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
-     * 
+     *
      * @param url The URL pointing to the Properties object containing the clip definitions.
      * @param url The URL pointing to the Properties object containing the clip definitions.
      */
      */
     void createClips(const char* url);
     void createClips(const char* url);
-    
+
     /**
     /**
      * Creates an AnimationClip from the Animation.
      * Creates an AnimationClip from the Animation.
-     * 
+     *
      * @param id The ID to the give the AnimationClip.
      * @param id The ID to the give the AnimationClip.
      * @param start The time (in milliseconds) that the AnimationClip will begin from.
      * @param start The time (in milliseconds) that the AnimationClip will begin from.
      * @param end The time (in milliseconds) that the AnimationClip will end.
      * @param end The time (in milliseconds) that the AnimationClip will end.
-     * 
+     *
      * @return The newly created AnimationClip; NULL if an AnimationClip already exists with the same ID.
      * @return The newly created AnimationClip; NULL if an AnimationClip already exists with the same ID.
+     * @script{create}
      */
      */
     AnimationClip* createClip(const char* id, unsigned long start, unsigned long end);
     AnimationClip* createClip(const char* id, unsigned long start, unsigned long end);
-    
+
     /**
     /**
      * Finds the AnimationClip with the specified name. If NULL, gets the default clip.
      * Finds the AnimationClip with the specified name. If NULL, gets the default clip.
-     * 
+     *
      * @param clipId The ID of the AnimationClip to get.
      * @param clipId The ID of the AnimationClip to get.
      *
      *
      * @return The AnimationClip with the specified ID; NULL if an AnimationClip with the given ID is not found.
      * @return The AnimationClip with the specified ID; NULL if an AnimationClip with the given ID is not found.
@@ -82,22 +83,22 @@ public:
      * Returns the number of animation clips in this animation.
      * Returns the number of animation clips in this animation.
      */
      */
     unsigned int getClipCount() const;
     unsigned int getClipCount() const;
-    
+
     /**
     /**
-     * Plays the AnimationClip with the specified name. 
+     * Plays the AnimationClip with the specified name.
      *
      *
      * @param clipId The ID of the AnimationClip to play. If NULL, plays the default clip.
      * @param clipId The ID of the AnimationClip to play. If NULL, plays the default clip.
-     */ 
+     */
     void play(const char* clipId = NULL);
     void play(const char* clipId = NULL);
 
 
     /**
     /**
-     * Stops the AnimationClip with the specified name. 
-     * 
+     * Stops the AnimationClip with the specified name.
+     *
      * @param clipId The ID of the AnimationClip to stop. If NULL, stops the default clip.
      * @param clipId The ID of the AnimationClip to stop. If NULL, stops the default clip.
      */
      */
     void stop(const char* clipId = NULL);
     void stop(const char* clipId = NULL);
 
 
-    /** 
+    /**
      * Pauses the AnimationClip with the specified name.
      * Pauses the AnimationClip with the specified name.
      *
      *
      * @param clipId The ID of the AnimationClip to pause. If NULL, pauses the default clip.
      * @param clipId The ID of the AnimationClip to pause. If NULL, pauses the default clip.
@@ -108,7 +109,7 @@ public:
      * Returns true if this animation targets the given AnimationTarget.
      * Returns true if this animation targets the given AnimationTarget.
      */
      */
     bool targets(AnimationTarget* target) const;
     bool targets(AnimationTarget* target) const;
-    
+
 private:
 private:
 
 
     /**
     /**
@@ -147,12 +148,12 @@ private:
     /**
     /**
      * Constructor.
      * Constructor.
      */
      */
-    Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type);
-    
+    Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type);
+
     /**
     /**
      * Constructor.
      * Constructor.
      */
      */
-    Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type);
+    Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type);
 
 
     /**
     /**
      * Constructor.
      * Constructor.
@@ -163,12 +164,12 @@ private:
      * Destructor.
      * Destructor.
      */
      */
     ~Animation();
     ~Animation();
-    
+
     /**
     /**
      * Hidden copy assignment operator.
      * Hidden copy assignment operator.
      */
      */
     Animation& operator=(const Animation&);
     Animation& operator=(const Animation&);
-    
+
     /**
     /**
      * Creates the default clip.
      * Creates the default clip.
      */
      */
@@ -191,13 +192,13 @@ private:
 
 
     /**
     /**
      * Creates a channel within this animation.
      * Creates a channel within this animation.
-     */ 
-    Channel* createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type);
+     */
+    Channel* createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type);
 
 
     /**
     /**
      * Creates a channel within this animation.
      * Creates a channel within this animation.
      */
      */
-    Channel* createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type);
+    Channel* createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type);
 
 
     /**
     /**
      * Adds a channel to the animation.
      * Adds a channel to the animation.
@@ -216,17 +217,17 @@ private:
 
 
     /**
     /**
      * Clones this animation.
      * Clones this animation.
-     * 
+     *
      * @param channel The channel to clone and add to the animation.
      * @param channel The channel to clone and add to the animation.
      * @param target The target of the animation.
      * @param target The target of the animation.
-     * 
+     *
      * @return The newly created animation.
      * @return The newly created animation.
      */
      */
     Animation* clone(Channel* channel, AnimationTarget* target);
     Animation* clone(Channel* channel, AnimationTarget* target);
-    
+
     AnimationController* _controller;       // The AnimationController that this Animation will run on.
     AnimationController* _controller;       // The AnimationController that this Animation will run on.
     std::string _id;                        // The Animation's ID.
     std::string _id;                        // The Animation's ID.
-    unsigned long _duration;                // the length of the animation (in milliseconds).
+    unsigned long _duration;              // the length of the animation (in milliseconds).
     std::vector<Channel*> _channels;        // The channels within this Animation.
     std::vector<Channel*> _channels;        // The channels within this Animation.
     AnimationClip* _defaultClip;            // The Animation's default clip.
     AnimationClip* _defaultClip;            // The Animation's default clip.
     std::vector<AnimationClip*>* _clips;    // All the clips created from this Animation.
     std::vector<AnimationClip*>* _clips;    // All the clips created from this Animation.

+ 5 - 5
gameplay/src/AnimationClip.cpp

@@ -43,7 +43,7 @@ AnimationClip::~AnimationClip()
 
 
     if (_scriptListeners)
     if (_scriptListeners)
     {
     {
-        for (unsigned int i = 0; i < _scriptListeners->size(); i++)
+        for (size_t i = 0; i < _scriptListeners->size(); i++)
         {
         {
             SAFE_DELETE((*_scriptListeners)[i]);
             SAFE_DELETE((*_scriptListeners)[i]);
         }
         }
@@ -169,7 +169,7 @@ float AnimationClip::getBlendWeight() const
 
 
 bool AnimationClip::isPlaying() const
 bool AnimationClip::isPlaying() const
 {
 {
-    return isClipStateBitSet(CLIP_IS_PLAYING_BIT);
+    return (isClipStateBitSet(CLIP_IS_PLAYING_BIT) && !isClipStateBitSet(CLIP_IS_PAUSED_BIT));
 }
 }
 
 
 void AnimationClip::play()
 void AnimationClip::play()
@@ -498,8 +498,8 @@ bool AnimationClip::update(float elapsedTime)
     Animation::Channel* channel = NULL;
     Animation::Channel* channel = NULL;
     AnimationValue* value = NULL;
     AnimationValue* value = NULL;
     AnimationTarget* target = NULL;
     AnimationTarget* target = NULL;
-    unsigned int channelCount = _animation->_channels.size();
-    for (unsigned int i = 0; i < channelCount; i++)
+    size_t channelCount = _animation->_channels.size();
+    for (size_t i = 0; i < channelCount; i++)
     {
     {
         channel = _animation->_channels[i];
         channel = _animation->_channels[i];
         GP_ASSERT(channel);
         GP_ASSERT(channel);
@@ -627,4 +627,4 @@ void AnimationClip::ScriptListener::animationEvent(AnimationClip* clip, EventTyp
 }
 }
 
 
 
 
-}
+}

+ 1 - 1
gameplay/src/AnimationController.cpp

@@ -97,7 +97,7 @@ void AnimationController::update(float elapsedTime)
 {
 {
     if (_state != RUNNING)
     if (_state != RUNNING)
         return;
         return;
-
+    
     Transform::suspendTransformChanged();
     Transform::suspendTransformChanged();
 
 
     // Loop through running clips and call update() on them.
     // Loop through running clips and call update() on them.

+ 35 - 35
gameplay/src/AnimationTarget.cpp

@@ -31,7 +31,7 @@ AnimationTarget::~AnimationTarget()
     }
     }
 }
 }
 
 
-Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
+Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, Curve::InterpolationType type)
 {
 {
     GP_ASSERT(type != Curve::BEZIER && type != Curve::HERMITE);
     GP_ASSERT(type != Curve::BEZIER && type != Curve::HERMITE);
     GP_ASSERT(keyCount >= 1 && keyTimes && keyValues);
     GP_ASSERT(keyCount >= 1 && keyTimes && keyValues);
@@ -41,7 +41,7 @@ Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsi
     return animation;
     return animation;
 }
 }
 
 
-Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
+Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
 {
 {
     GP_ASSERT(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
     GP_ASSERT(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
     Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
     Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
@@ -73,9 +73,9 @@ Animation* AnimationTarget::createAnimationFromTo(const char* id, int propertyId
     memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
     memcpy(keyValues, from, sizeof(float) * propertyComponentCount);
     memcpy(keyValues + propertyComponentCount, to, sizeof(float) * propertyComponentCount);
     memcpy(keyValues + propertyComponentCount, to, sizeof(float) * propertyComponentCount);
 
 
-    unsigned long* keyTimes = new unsigned long[2];
+    unsigned int* keyTimes = new unsigned int[2];
     keyTimes[0] = 0;
     keyTimes[0] = 0;
-    keyTimes[1] = duration;
+    keyTimes[1] = (unsigned int)duration;
 
 
     Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
     Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
 
 
@@ -99,9 +99,9 @@ Animation* AnimationTarget::createAnimationFromBy(const char* id, int propertyId
     convertByValues(propertyId, propertyComponentCount, from, by);
     convertByValues(propertyId, propertyComponentCount, from, by);
     memcpy(keyValues + propertyComponentCount, by, sizeof(float) * propertyComponentCount);
     memcpy(keyValues + propertyComponentCount, by, sizeof(float) * propertyComponentCount);
 
 
-    unsigned long* keyTimes = new unsigned long[2];
+    unsigned int* keyTimes = new unsigned int[2];
     keyTimes[0] = 0;
     keyTimes[0] = 0;
-    keyTimes[1] = duration;
+    keyTimes[1] = (unsigned int)duration;
 
 
     Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
     Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type);
 
 
@@ -119,14 +119,14 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         GP_ERROR("Invalid animation namespace '%s'.", animationProperties->getNamespace());
         GP_ERROR("Invalid animation namespace '%s'.", animationProperties->getNamespace());
         return NULL;
         return NULL;
     }
     }
-    
+
     const char* propertyIdStr = animationProperties->getString("property");
     const char* propertyIdStr = animationProperties->getString("property");
     if (propertyIdStr == NULL)
     if (propertyIdStr == NULL)
     {
     {
         GP_ERROR("Attribute 'property' must be specified for an animation.");
         GP_ERROR("Attribute 'property' must be specified for an animation.");
         return NULL;
         return NULL;
     }
     }
-    
+
     // Get animation target property id
     // Get animation target property id
     int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr);
     int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr);
     if (propertyId == -1)
     if (propertyId == -1)
@@ -134,7 +134,7 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         GP_ERROR("Property ID is invalid.");
         GP_ERROR("Property ID is invalid.");
         return NULL;
         return NULL;
     }
     }
-    
+
     unsigned int keyCount = animationProperties->getInt("keyCount");
     unsigned int keyCount = animationProperties->getInt("keyCount");
     if (keyCount == 0)
     if (keyCount == 0)
     {
     {
@@ -148,27 +148,27 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         GP_ERROR("Attribute 'keyTimes' must be specified for an animation.");
         GP_ERROR("Attribute 'keyTimes' must be specified for an animation.");
         return NULL;
         return NULL;
     }
     }
-    
+
     const char* keyValuesStr = animationProperties->getString("keyValues");
     const char* keyValuesStr = animationProperties->getString("keyValues");
     if (keyValuesStr == NULL)
     if (keyValuesStr == NULL)
     {
     {
         GP_ERROR("Attribute 'keyValues' must be specified for an animation.");
         GP_ERROR("Attribute 'keyValues' must be specified for an animation.");
         return NULL;
         return NULL;
     }
     }
-    
+
     const char* curveStr = animationProperties->getString("curve");
     const char* curveStr = animationProperties->getString("curve");
     if (curveStr == NULL)
     if (curveStr == NULL)
     {
     {
         GP_ERROR("Attribute 'curve' must be specified for an animation.");
         GP_ERROR("Attribute 'curve' must be specified for an animation.");
         return NULL;
         return NULL;
     }
     }
-    
+
     char delimeter = ' ';
     char delimeter = ' ';
-    unsigned int startOffset = 0;
-    unsigned int endOffset = (unsigned int)std::string::npos;
-    
-    unsigned long* keyTimes = new unsigned long[keyCount];
-    for (unsigned int i = 0; i < keyCount; i++)
+    size_t startOffset = 0;
+    size_t endOffset = std::string::npos;
+
+    unsigned int* keyTimes = new unsigned int[keyCount];
+    for (size_t i = 0; i < keyCount; i++)
     {
     {
         endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset);
         endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset);
         if (endOffset != std::string::npos)
         if (endOffset != std::string::npos)
@@ -183,19 +183,19 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
     }
     }
 
 
     startOffset = 0;
     startOffset = 0;
-    endOffset = (unsigned int)std::string::npos;
-    
+    endOffset = std::string::npos;
+
     int componentCount = getAnimationPropertyComponentCount(propertyId);
     int componentCount = getAnimationPropertyComponentCount(propertyId);
     GP_ASSERT(componentCount > 0);
     GP_ASSERT(componentCount > 0);
-    
+
     unsigned int components = keyCount * componentCount;
     unsigned int components = keyCount * componentCount;
-    
+
     float* keyValues = new float[components];
     float* keyValues = new float[components];
     for (unsigned int i = 0; i < components; i++)
     for (unsigned int i = 0; i < components; i++)
     {
     {
         endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset);
         endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset);
         if (endOffset != std::string::npos)
         if (endOffset != std::string::npos)
-        {   
+        {
             keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str());
             keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str());
         }
         }
         else
         else
@@ -211,12 +211,12 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
     {
     {
         keyIn = new float[components];
         keyIn = new float[components];
         startOffset = 0;
         startOffset = 0;
-        endOffset = (unsigned int)std::string::npos;
+        endOffset = std::string::npos;
         for (unsigned int i = 0; i < components; i++)
         for (unsigned int i = 0; i < components; i++)
         {
         {
             endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset);
             endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset);
             if (endOffset != std::string::npos)
             if (endOffset != std::string::npos)
-            {   
+            {
                 keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str());
                 keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str());
             }
             }
             else
             else
@@ -226,19 +226,19 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
             startOffset = endOffset + 1;
             startOffset = endOffset + 1;
         }
         }
     }
     }
-    
+
     const char* keyOutStr = animationProperties->getString("keyOut");
     const char* keyOutStr = animationProperties->getString("keyOut");
     float* keyOut = NULL;
     float* keyOut = NULL;
     if (keyOutStr)
     if (keyOutStr)
-    {   
+    {
         keyOut = new float[components];
         keyOut = new float[components];
         startOffset = 0;
         startOffset = 0;
-        endOffset = (unsigned int)std::string::npos;
+        endOffset = std::string::npos;
         for (unsigned int i = 0; i < components; i++)
         for (unsigned int i = 0; i < components; i++)
         {
         {
             endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset);
             endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset);
             if (endOffset != std::string::npos)
             if (endOffset != std::string::npos)
-            {   
+            {
                 keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str());
                 keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str());
             }
             }
             else
             else
@@ -261,10 +261,10 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
         animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
     }
     }
 
 
-    SAFE_DELETE(keyOut);
-    SAFE_DELETE(keyIn);
-    SAFE_DELETE(keyValues);
-    SAFE_DELETE(keyTimes);
+    SAFE_DELETE_ARRAY(keyOut);
+    SAFE_DELETE_ARRAY(keyIn);
+    SAFE_DELETE_ARRAY(keyValues);
+    SAFE_DELETE_ARRAY(keyTimes);
 
 
     Properties* pClip = animationProperties->getNextNamespace();
     Properties* pClip = animationProperties->getNextNamespace();
     if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
     if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
@@ -325,7 +325,7 @@ Animation* AnimationTarget::getAnimation(const char* id) const
 int AnimationTarget::getPropertyId(TargetType type, const char* propertyIdStr)
 int AnimationTarget::getPropertyId(TargetType type, const char* propertyIdStr)
 {
 {
     GP_ASSERT(propertyIdStr);
     GP_ASSERT(propertyIdStr);
-    
+
     if (type == AnimationTarget::TRANSFORM)
     if (type == AnimationTarget::TRANSFORM)
     {
     {
         if (strcmp(propertyIdStr, "ANIMATE_SCALE") == 0)
         if (strcmp(propertyIdStr, "ANIMATE_SCALE") == 0)
@@ -467,7 +467,7 @@ void AnimationTarget::cloneInto(AnimationTarget* target, NodeCloneContext &conte
 void AnimationTarget::convertByValues(unsigned int propertyId, unsigned int componentCount, float* from, float* by)
 void AnimationTarget::convertByValues(unsigned int propertyId, unsigned int componentCount, float* from, float* by)
 {
 {
     if (_targetType == AnimationTarget::TRANSFORM)
     if (_targetType == AnimationTarget::TRANSFORM)
-    {    
+    {
         switch(propertyId)
         switch(propertyId)
         {
         {
             case Transform::ANIMATE_SCALE:
             case Transform::ANIMATE_SCALE:
@@ -497,7 +497,7 @@ void AnimationTarget::convertByValues(unsigned int propertyId, unsigned int comp
                 convertQuaternionByValues(from, by);
                 convertQuaternionByValues(from, by);
                 convertByValues(from + 4, by + 4, 3);
                 convertByValues(from + 4, by + 4, 3);
                 break;
                 break;
-            }   
+            }
             case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
             case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
             {
             {
                 convertScaleByValues(from, by, 3);
                 convertScaleByValues(from, by, 3);

+ 23 - 23
gameplay/src/AnimationTarget.h

@@ -23,9 +23,9 @@ class AnimationTarget
 public:
 public:
 
 
     /**
     /**
-     * Creates an animation on this target from a set of key value and key time pairs. 
+     * Creates an animation on this target from a set of key value and key time pairs.
      * Cannot use Curve::BEZIER or CURVE::HERMITE as the interpolation type since they require tangents/control points.
      * Cannot use Curve::BEZIER or CURVE::HERMITE as the interpolation type since they require tangents/control points.
-     * 
+     *
      * @param id The ID of the animation.
      * @param id The ID of the animation.
      * @param propertyId The property on this target to animate.
      * @param propertyId The property on this target to animate.
      * @param keyCount The number of keyframes in the animation. Must be greater than one.
      * @param keyCount The number of keyframes in the animation. Must be greater than one.
@@ -35,11 +35,11 @@ public:
      *
      *
      * @return The newly created animation.
      * @return The newly created animation.
      */
      */
-    Animation* createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type);
+    Animation* createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, Curve::InterpolationType type);
 
 
     /**
     /**
      * Creates an animation on this target from a set of key value and key time pairs.
      * Creates an animation on this target from a set of key value and key time pairs.
-     * 
+     *
      * @param id The ID of the animation.
      * @param id The ID of the animation.
      * @param propertyId The property on this target to animate.
      * @param propertyId The property on this target to animate.
      * @param keyCount The number of keyframes in the animation. Must be greater than one.
      * @param keyCount The number of keyframes in the animation. Must be greater than one.
@@ -51,13 +51,13 @@ public:
      *
      *
      * @return The newly created animation.
      * @return The newly created animation.
      */
      */
-    Animation* createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type);
+    Animation* createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type);
 
 
     /**
     /**
-     * Creates an animation on this target using the data from the Properties object defined at the specified URL, 
+     * Creates an animation on this target using the data from the Properties object defined at the specified URL,
      * where the URL is of the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
      * where the URL is of the format "<file-path>.<extension>#<namespace-id>/<namespace-id>/.../<namespace-id>"
-     * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional). 
-     * 
+     * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
+     *
      * @param id The ID of the animation.
      * @param id The ID of the animation.
      * @param url The URL pointing to the Properties object defining the animation data.
      * @param url The URL pointing to the Properties object defining the animation data.
      *
      *
@@ -66,8 +66,8 @@ public:
     Animation* createAnimation(const char* id, const char* url);
     Animation* createAnimation(const char* id, const char* url);
 
 
     /**
     /**
-     * Creates an animation on this target using the data from the given properties object. 
-     * 
+     * Creates an animation on this target using the data from the given properties object.
+     *
      * @param id The ID of the animation.
      * @param id The ID of the animation.
      * @param animationProperties The properties object defining the animation data.
      * @param animationProperties The properties object defining the animation data.
      *
      *
@@ -109,14 +109,14 @@ public:
      * Destroys the animation with the specified ID. Destroys the first animation if ID is NULL.
      * Destroys the animation with the specified ID. Destroys the first animation if ID is NULL.
      *
      *
      * @param id The ID of the animation to destroy.
      * @param id The ID of the animation to destroy.
-     */ 
+     */
     void destroyAnimation(const char* id = NULL);
     void destroyAnimation(const char* id = NULL);
 
 
     /**
     /**
      * Abstract method to return the property component count of the given property ID on the AnimationTarget.
      * Abstract method to return the property component count of the given property ID on the AnimationTarget.
-     * 
+     *
      * @param propertyId The ID of the property on the AnimationTarget to obtain the component count for.
      * @param propertyId The ID of the property on the AnimationTarget to obtain the component count for.
-     * 
+     *
      * @return The property component count of the given property.
      * @return The property component count of the given property.
      */
      */
     virtual unsigned int getAnimationPropertyComponentCount(int propertyId) const = 0;
     virtual unsigned int getAnimationPropertyComponentCount(int propertyId) const = 0;
@@ -131,14 +131,14 @@ public:
 
 
     /**
     /**
      * Abstract method for setting the animation property value for the given property ID on the AnimationTarget.
      * Abstract method for setting the animation property value for the given property ID on the AnimationTarget.
-     * 
+     *
      * @param propertyId The ID of the property on the AnimationTarget to set the animation property value on.
      * @param propertyId The ID of the property on the AnimationTarget to set the animation property value on.
      * @param value The container to set the animation property value in.
      * @param value The container to set the animation property value in.
      * @param blendWeight The blend weight.
      * @param blendWeight The blend weight.
      */
      */
     virtual void setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight = 1.0f) = 0;
     virtual void setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight = 1.0f) = 0;
 
 
-    /** 
+    /**
      * Gets the animation with the specified ID. If the ID is NULL, this function will return the first animation it finds.
      * Gets the animation with the specified ID. If the ID is NULL, this function will return the first animation it finds.
      *
      *
      * @param id The name of the animation to get.
      * @param id The name of the animation to get.
@@ -146,9 +146,9 @@ public:
     Animation* getAnimation(const char* id = NULL) const;
     Animation* getAnimation(const char* id = NULL) const;
 
 
 protected:
 protected:
-    
+
     /**
     /**
-     * The type of animation target. 
+     * The type of animation target.
      */
      */
     enum TargetType
     enum TargetType
     {
     {
@@ -168,14 +168,14 @@ protected:
 
 
     /**
     /**
      * Adds the given animation channel to this animation target.
      * Adds the given animation channel to this animation target.
-     * 
+     *
      * @param channel The animation channel to add.
      * @param channel The animation channel to add.
      */
      */
     void addChannel(Animation::Channel* channel);
     void addChannel(Animation::Channel* channel);
 
 
     /**
     /**
      * Removes the given animation channel from this animation target.
      * Removes the given animation channel from this animation target.
-     * 
+     *
      * @param channel The animation channel to delete.
      * @param channel The animation channel to delete.
      */
      */
     void removeChannel(Animation::Channel* channel);
     void removeChannel(Animation::Channel* channel);
@@ -189,14 +189,14 @@ protected:
 
 
     /**
     /**
      * Copies data from this animation target into the given target for the purpose of cloning.
      * Copies data from this animation target into the given target for the purpose of cloning.
-     * 
+     *
      * @param target The target to copy into.
      * @param target The target to copy into.
      * @param context The clone context.
      * @param context The clone context.
      */
      */
     void cloneInto(AnimationTarget* target, NodeCloneContext &context) const;
     void cloneInto(AnimationTarget* target, NodeCloneContext &context) const;
 
 
     /**
     /**
-     * The target's type. 
+     * The target's type.
      *
      *
      * @see TargetType::SCALAR
      * @see TargetType::SCALAR
      * @see TargetType::TRANSFORM
      * @see TargetType::TRANSFORM
@@ -212,7 +212,7 @@ private:
 
 
     /**
     /**
      * Gets the TargetType's property ID value for the specified property ID string.
      * Gets the TargetType's property ID value for the specified property ID string.
-     * 
+     *
      * @param type The TargetType of the AnimationTarget.
      * @param type The TargetType of the AnimationTarget.
      * @param propertyIdStr The property ID string.
      * @param propertyIdStr The property ID string.
      * @return The property ID value for teh property ID string; -1 if the propertyIdStr does not exist
      * @return The property ID value for teh property ID string; -1 if the propertyIdStr does not exist
@@ -241,7 +241,7 @@ private:
     void convertByValues(float* from, float* by, unsigned int componentCount);
     void convertByValues(float* from, float* by, unsigned int componentCount);
 
 
     std::vector<Animation::Channel*>* _animationChannels;   // Collection of all animation channels that target the AnimationTarget
     std::vector<Animation::Channel*>* _animationChannels;   // Collection of all animation channels that target the AnimationTarget
-    
+
 };
 };
 }
 }
 
 

+ 6 - 6
gameplay/src/AnimationValue.cpp

@@ -56,18 +56,18 @@ void AnimationValue::setFloat(unsigned int index, float value)
     _value[index] = value;
     _value[index] = value;
 }
 }
 
 
-void AnimationValue::getFloat(float* value, unsigned int offset, unsigned int length) const
+void AnimationValue::getFloats(unsigned int index, float* values, unsigned int count) const
 {
 {
-    GP_ASSERT(_value && value && offset < _componentCount && (offset + length) <= _componentCount);
+    GP_ASSERT(_value && values && index < _componentCount && (index + count) <= _componentCount);
 
 
-    memcpy(value + offset, _value, length * sizeof(float));
+    memcpy(values, &_value[index], count * sizeof(float));
 }
 }
 
 
-void AnimationValue::setFloat(float* value, unsigned int offset, unsigned int length)
+void AnimationValue::setFloats(unsigned int index, float* values, unsigned int count)
 {
 {
-    GP_ASSERT(_value && value && offset < _componentCount && (offset + length) <= _componentCount);
+    GP_ASSERT(_value && values && index < _componentCount && (index + count) <= _componentCount);
 
 
-    memcpy(_value, value + offset, length * sizeof(float));
+    memcpy(&_value[index], values, count * sizeof(float));
 }
 }
 
 
 }
 }

+ 10 - 10
gameplay/src/AnimationValue.h

@@ -33,22 +33,22 @@ public:
     void setFloat(unsigned int index, float value);
     void setFloat(unsigned int index, float value);
 
 
     /**
     /**
-     * Gets the value of the AnimationValue in a float array.
+     * Copies one or more float values from this AnimationValue into the specified array.
      *
      *
-     * @param value The array to populate with the AnimationValue's values.
-     * @param offset The offset into the value to start populating.
-     * @param length The number of values to copy into the array.
+     * @param index The index to start copying from.
+     * @param values Pointer to float array to copy values into.
+     * @param count Number of values to copy.
      */
      */
-    void getFloat(float* value, unsigned int offset, unsigned int length) const;
+    void getFloats(unsigned int index, float* values, unsigned int count) const;
 
 
     /**
     /**
-     * Sets the value of the AnimationValue.
+     * Copies one or more float values into the AnimationValue.
      *
      *
-     * @param value The array to populate the AnimationValue's values.
-     * @param offset The offset into the value array to start populating from.
-     * @param length The number of values to copy into the AnimationValue.
+     * @param index The index of the first component to set the value for.
+     * @param values Array of values to copy into the AnimationValue.
+     * @param count Number of values to in the array to copy in.
      */
      */
-    void setFloat(float* value, unsigned int offset, unsigned int length);
+    void setFloats(unsigned int index, float* values, unsigned int count);
 
 
 private:
 private:
 
 

+ 8 - 6
gameplay/src/AudioBuffer.cpp

@@ -100,8 +100,10 @@ AudioBuffer* AudioBuffer::create(const char* path)
         GP_ERROR("Unsupported audio file: %s", path);
         GP_ERROR("Unsupported audio file: %s", path);
         goto cleanup;
         goto cleanup;
     }
     }
-    
-    fclose(file);
+
+    //NOTE: loadOgg actually sets this null, so it is expected
+    if (file)    
+        fclose(file);
 
 
     buffer = new AudioBuffer(path, alBuffer);
     buffer = new AudioBuffer(path, alBuffer);
 
 
@@ -303,16 +305,16 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     }
     }
 }
 }
     
     
-bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
+bool AudioBuffer::loadOgg(FILE*& file, ALuint buffer)
 {
 {
     GP_ASSERT(file);
     GP_ASSERT(file);
 
 
     OggVorbis_File ogg_file;
     OggVorbis_File ogg_file;
     vorbis_info* info;
     vorbis_info* info;
     ALenum format;
     ALenum format;
-    int result;
+    long result;
     int section;
     int section;
-    unsigned int size = 0;
+    long size = 0;
 
 
     rewind(file);
     rewind(file);
 
 
@@ -331,7 +333,7 @@ bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
         format = AL_FORMAT_STEREO16;
         format = AL_FORMAT_STEREO16;
 
 
     // size = #samples * #channels * 2 (for 16 bit).
     // size = #samples * #channels * 2 (for 16 bit).
-    unsigned int data_size = ov_pcm_total(&ogg_file, -1) * info->channels * 2;
+    long data_size = ov_pcm_total(&ogg_file, -1) * info->channels * 2;
     char* data = new char[data_size];
     char* data = new char[data_size];
 
 
     while (size < data_size)
     while (size < data_size)

+ 1 - 1
gameplay/src/AudioBuffer.h

@@ -45,7 +45,7 @@ private:
     
     
     static bool loadWav(FILE* file, ALuint buffer);
     static bool loadWav(FILE* file, ALuint buffer);
     
     
-    static bool loadOgg(FILE* file, ALuint buffer);
+    static bool loadOgg(FILE*& file, ALuint buffer);
 
 
     std::string _filePath;
     std::string _filePath;
     ALuint _alBuffer;
     ALuint _alBuffer;

+ 16 - 0
gameplay/src/AudioListener.cpp

@@ -41,6 +41,11 @@ void AudioListener::setPosition(const Vector3& position)
     _position = position;
     _position = position;
 }
 }
 
 
+void AudioListener::setPosition(float x, float y, float z)
+{
+    _position.set(x, y, z);
+}
+
 const Vector3& AudioListener::getVelocity() const 
 const Vector3& AudioListener::getVelocity() const 
 { 
 { 
     return _velocity; 
     return _velocity; 
@@ -51,6 +56,11 @@ void AudioListener::setVelocity(const Vector3& velocity)
     _velocity = velocity;
     _velocity = velocity;
 }
 }
 
 
+void AudioListener::setVelocity(float x, float y, float z)
+{
+    _velocity.set(x, y, z);
+}
+
 const float* AudioListener::getOrientation() const
 const float* AudioListener::getOrientation() const
 {
 {
     return (const float*)&_orientation[0];
     return (const float*)&_orientation[0];
@@ -77,6 +87,12 @@ void AudioListener::setOrientation(const Vector3& forward, const Vector3& up)
     _orientation[1].z = up.z;
     _orientation[1].z = up.z;
 }
 }
 
 
+void AudioListener::setOrientation(float forwardX, float forwardY, float forwardZ, float upX, float upY, float upZ)
+{
+    _orientation[0].set(forwardX, forwardY, forwardZ);
+    _orientation[1].set(upX, upY, upZ);
+}
+
 Camera* AudioListener::getCamera() const
 Camera* AudioListener::getCamera() const
 {
 {
     return _camera;
     return _camera;

+ 30 - 0
gameplay/src/AudioListener.h

@@ -40,6 +40,15 @@ public:
      */
      */
     void setPosition(const Vector3& position);
     void setPosition(const Vector3& position);
 
 
+    /**
+     * Sets the position of the audio source.
+     * 
+     * @param x The x coordinate of the position.
+     * @param y The y coordinate of the position.
+     * @param z The z coordinate of the position.
+     */
+    void setPosition(float x, float y, float z);
+
     /**
     /**
      * Returns the gain of the audio listener.
      * Returns the gain of the audio listener.
      *
      *
@@ -68,6 +77,15 @@ public:
      */
      */
     void setVelocity(const Vector3& velocity);
     void setVelocity(const Vector3& velocity);
 
 
+    /**
+     * Sets the velocity of the audio source
+     * 
+     * @param x The x coordinate of the velocity.
+     * @param y The y coordinate of the velocity.
+     * @param z The z coordinate of the velocity.
+     */
+    void setVelocity(float x, float y, float z);
+
     /**
     /**
      * Gets the float pointer to the orientation of the audio listener.
      * Gets the float pointer to the orientation of the audio listener.
      * Orientation is represented as 6 floats. (forward.x, forward.y, forward.z, up.x, up.y, up.z).
      * Orientation is represented as 6 floats. (forward.x, forward.y, forward.z, up.x, up.y, up.z).
@@ -99,6 +117,18 @@ public:
      */
      */
     void setOrientation(const Vector3& forward, const Vector3& up);
     void setOrientation(const Vector3& forward, const Vector3& up);
 
 
+    /**
+     * Sets the orientation of the audio listener.
+     * 
+     * @param forwardX The x coordinate of the forward vector.
+     * @param forwardY The y coordinate of the forward vector.
+     * @param forwardZ The z coordinate of the forward vector.
+     * @param upX The x coordinate of the up vector.
+     * @param upY The y coordinate of the up vector.
+     * @param upZ The z coordinate of the up vector.
+     */
+    void setOrientation(float forwardX, float forwardY, float forwardZ, float upX, float upY, float upZ);
+
     /**
     /**
      * Gets the camera currently associated with the audio listener.
      * Gets the camera currently associated with the audio listener.
      *
      *

+ 7 - 2
gameplay/src/AudioSource.cpp

@@ -10,7 +10,7 @@ namespace gameplay
 {
 {
 
 
 AudioSource::AudioSource(AudioBuffer* buffer, ALuint source) 
 AudioSource::AudioSource(AudioBuffer* buffer, ALuint source) 
-    : _alSource(source), _buffer(buffer), _looped(true), _gain(1.0f), _pitch(1.0f), _node(NULL)
+    : _alSource(source), _buffer(buffer), _looped(false), _gain(1.0f), _pitch(1.0f), _node(NULL)
 {
 {
     GP_ASSERT(buffer);
     GP_ASSERT(buffer);
     AL_CHECK( alSourcei(_alSource, AL_BUFFER, buffer->_alBuffer) );
     AL_CHECK( alSourcei(_alSource, AL_BUFFER, buffer->_alBuffer) );
@@ -34,7 +34,7 @@ AudioSource* AudioSource::create(const char* url)
 {
 {
     // Load from a .audio file.
     // Load from a .audio file.
     std::string pathStr = url;
     std::string pathStr = url;
-    if (pathStr.find(".audio") != pathStr.npos)
+    if (pathStr.find(".audio") != std::string::npos)
     {
     {
         Properties* properties = Properties::create(url);
         Properties* properties = Properties::create(url);
         if (properties == NULL)
         if (properties == NULL)
@@ -233,6 +233,11 @@ void AudioSource::setVelocity(const Vector3& velocity)
     _velocity = velocity;
     _velocity = velocity;
 }
 }
 
 
+void AudioSource::setVelocity(float x, float y, float z)
+{
+    setVelocity(Vector3(x, y, z));
+}
+
 Node* AudioSource::getNode() const
 Node* AudioSource::getNode() const
 {
 {
     return _node;
     return _node;

+ 9 - 0
gameplay/src/AudioSource.h

@@ -141,6 +141,15 @@ public:
      */
      */
     void setVelocity(const Vector3& velocity);
     void setVelocity(const Vector3& velocity);
 
 
+    /**
+     * Sets the velocity of the audio source.
+     *
+     * @param x The x coordinate of the velocity.
+     * @param y The y coordinate of the velocity.
+     * @param z The z coordinate of the velocity.
+     */
+    void setVelocity(float x, float y, float z);
+
     /**
     /**
      * Gets the node that this source is attached to.
      * Gets the node that this source is attached to.
      * 
      * 

+ 27 - 11
gameplay/src/Base.h

@@ -15,6 +15,7 @@
 #include <ctime>
 #include <ctime>
 #include <iostream>
 #include <iostream>
 #include <string>
 #include <string>
+#include <cstring>
 #include <vector>
 #include <vector>
 #include <list>
 #include <list>
 #include <set>
 #include <set>
@@ -23,6 +24,8 @@
 #include <algorithm>
 #include <algorithm>
 #include <limits>
 #include <limits>
 #include <functional>
 #include <functional>
+#include <bitset>
+#include "Logger.h"
 
 
 // Bring common functions from C into global namespace
 // Bring common functions from C into global namespace
 using std::memcpy;
 using std::memcpy;
@@ -40,7 +43,6 @@ using std::min;
 using std::max;
 using std::max;
 using std::modf;
 using std::modf;
 
 
-
 // Common
 // Common
 #ifndef NULL
 #ifndef NULL
 #define NULL     0
 #define NULL     0
@@ -48,8 +50,11 @@ using std::modf;
 
 
 namespace gameplay
 namespace gameplay
 {
 {
-/** Print logging (implemented per platform). */
-extern void printError(const char* format, ...);
+/**
+ * Print logging (implemented per platform).
+ * @script{ignore}
+ */
+extern void print(const char* format, ...);
 }
 }
 
 
 // Current function macro.
 // Current function macro.
@@ -72,9 +77,9 @@ extern void printError(const char* format, ...);
 #else
 #else
 #define GP_ERROR(...) do \
 #define GP_ERROR(...) do \
     { \
     { \
-        printError("%s -- ", __current__func__); \
-        printError(__VA_ARGS__); \
-        printError("\n"); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, "%s -- ", __current__func__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, __VA_ARGS__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, "\n"); \
         assert(0); \
         assert(0); \
         std::exit(-1); \
         std::exit(-1); \
     } while (0)
     } while (0)
@@ -83,9 +88,9 @@ extern void printError(const char* format, ...);
 // Warning macro.
 // Warning macro.
 #define GP_WARN(...) do \
 #define GP_WARN(...) do \
     { \
     { \
-        printError("%s -- ", __current__func__); \
-        printError(__VA_ARGS__); \
-        printError("\n"); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "%s -- ", __current__func__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, __VA_ARGS__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "\n"); \
     } while (0)
     } while (0)
 
 
 // Bullet Physics
 // Bullet Physics
@@ -152,7 +157,13 @@ extern void printError(const char* format, ...);
 #endif
 #endif
 
 
 // Audio (OpenAL/Vorbis)
 // Audio (OpenAL/Vorbis)
-#if defined (__QNX__) || defined(__ANDROID__)
+#ifdef __QNX__
+#include <AL/al.h>
+#include <AL/alc.h>
+#elif __ANDROID__
+#include <AL/al.h>
+#include <AL/alc.h>
+#elif __linux__
 #include <AL/al.h>
 #include <AL/al.h>
 #include <AL/alc.h>
 #include <AL/alc.h>
 #elif WIN32
 #elif WIN32
@@ -190,7 +201,7 @@ using std::va_list;
         #define USE_NEON
         #define USE_NEON
     #endif
     #endif
 #elif __ANDROID__
 #elif __ANDROID__
-	#include <EGL/egl.h>
+    #include <EGL/egl.h>
     #include <GLES2/gl2.h>
     #include <GLES2/gl2.h>
     #include <GLES2/gl2ext.h>
     #include <GLES2/gl2ext.h>
     extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
     extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
@@ -202,8 +213,13 @@ using std::va_list;
     #define OPENGL_ES
     #define OPENGL_ES
 #elif WIN32
 #elif WIN32
     #define WIN32_LEAN_AND_MEAN
     #define WIN32_LEAN_AND_MEAN
+    #define GLEW_STATIC
     #include <GL/glew.h>
     #include <GL/glew.h>
     #define USE_VAO
     #define USE_VAO
+#elif __linux__
+        #define GLEW_STATIC
+        #include <GL/glew.h>
+        #define USE_VAO
 #elif __APPLE__
 #elif __APPLE__
     #include "TargetConditionals.h"
     #include "TargetConditionals.h"
     #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
     #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR

+ 11 - 0
gameplay/src/BoundingBox.cpp

@@ -15,6 +15,11 @@ BoundingBox::BoundingBox(const Vector3& min, const Vector3& max)
     set(min, max);
     set(min, max);
 }
 }
 
 
+BoundingBox::BoundingBox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
+{
+    set(minX, minY, minZ, maxX, maxY, maxZ);
+}
+
 BoundingBox::BoundingBox(const BoundingBox& copy)
 BoundingBox::BoundingBox(const BoundingBox& copy)
 {
 {
     set(copy);
     set(copy);
@@ -247,6 +252,12 @@ void BoundingBox::set(const Vector3& min, const Vector3& max)
     this->max = max;
     this->max = max;
 }
 }
 
 
+void BoundingBox::set(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
+{
+    min.set(minX, minY, minZ);
+    max.set(maxX, maxY, maxZ);
+}
+
 static void updateMinMax(Vector3* point, Vector3* min, Vector3* max)
 static void updateMinMax(Vector3* point, Vector3* min, Vector3* max)
 {
 {
     GP_ASSERT(point);
     GP_ASSERT(point);

+ 24 - 0
gameplay/src/BoundingBox.h

@@ -36,6 +36,18 @@ public:
      */
      */
     BoundingBox(const Vector3& min, const Vector3& max);
     BoundingBox(const Vector3& min, const Vector3& max);
 
 
+    /**
+     * Constructs a new bounding box from the specified values.
+     * 
+     * @param minX The x coordinate of the minimum point of the bounding box.
+     * @param minY The y coordinate of the minimum point of the bounding box.
+     * @param minZ The z coordinate of the minimum point of the bounding box.
+     * @param maxX The x coordinate of the maximum point of the bounding box.
+     * @param maxY The y coordinate of the maximum point of the bounding box.
+     * @param maxZ The z coordinate of the maximum point of the bounding box.
+     */
+    BoundingBox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
+
     /**
     /**
      * Constructs a new bounding box from the given bounding box.
      * Constructs a new bounding box from the given bounding box.
      *
      *
@@ -163,6 +175,18 @@ public:
      */
      */
     void set(const Vector3& min, const Vector3& max);
     void set(const Vector3& min, const Vector3& max);
 
 
+    /**
+     * Sets this bounding box to the specified values.
+     * 
+     * @param minX The x coordinate of the minimum point of the bounding box.
+     * @param minY The y coordinate of the minimum point of the bounding box.
+     * @param minZ The z coordinate of the minimum point of the bounding box.
+     * @param maxX The x coordinate of the maximum point of the bounding box.
+     * @param maxY The y coordinate of the maximum point of the bounding box.
+     * @param maxZ The z coordinate of the maximum point of the bounding box.
+     */
+    void set(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
+
     /**
     /**
      * Sets this bounding box to the specified bounding box.
      * Sets this bounding box to the specified bounding box.
      *
      *

+ 18 - 19
gameplay/src/Bundle.cpp

@@ -393,8 +393,8 @@ Scene* Bundle::loadScene(const char* id)
             return NULL;
             return NULL;
         }
         }
     }
     }
-    
-    Scene* scene = Scene::createScene();
+
+    Scene* scene = Scene::create();
     scene->setId(getIdFromOffset());
     scene->setId(getIdFromOffset());
 
 
     // Read the number of children.
     // Read the number of children.
@@ -505,7 +505,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                 SAFE_DELETE(_trackedNodes);
                 SAFE_DELETE(_trackedNodes);
                 return NULL;
                 return NULL;
             }
             }
-            
+
             // Read the number of animations in this object.
             // Read the number of animations in this object.
             unsigned int animationCount;
             unsigned int animationCount;
             if (!read(&animationCount))
             if (!read(&animationCount))
@@ -573,8 +573,8 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                             SAFE_DELETE(_trackedNodes);
                             SAFE_DELETE(_trackedNodes);
                             return NULL;
                             return NULL;
                         }
                         }
-                        
-                        // Skip the animation channel (passing a target attribute of 
+
+                        // Skip the animation channel (passing a target attribute of
                         // 0 causes the animation to not be created).
                         // 0 causes the animation to not be created).
                         readAnimationChannelData(NULL, id.c_str(), NULL, 0);
                         readAnimationChannelData(NULL, id.c_str(), NULL, 0);
                     }
                     }
@@ -636,7 +636,7 @@ bool Bundle::skipNode()
         GP_ERROR("Failed to skip node type for node '%s'.", id);
         GP_ERROR("Failed to skip node type for node '%s'.", id);
         return false;
         return false;
     }
     }
-    
+
     // Skip over the node's transform and parent ID.
     // Skip over the node's transform and parent ID.
     if (fseek(_file, sizeof(float) * 16, SEEK_CUR) != 0)
     if (fseek(_file, sizeof(float) * 16, SEEK_CUR) != 0)
     {
     {
@@ -660,7 +660,7 @@ bool Bundle::skipNode()
                 return false;
                 return false;
         }
         }
     }
     }
-    
+
     // Skip over the node's camera, light, and model attachments.
     // Skip over the node's camera, light, and model attachments.
     Camera* camera = readCamera(); SAFE_RELEASE(camera);
     Camera* camera = readCamera(); SAFE_RELEASE(camera);
     Light* light = readLight(); SAFE_RELEASE(light);
     Light* light = readLight(); SAFE_RELEASE(light);
@@ -1109,7 +1109,7 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
             Node* node = rootJoint;
             Node* node = rootJoint;
             GP_ASSERT(node);
             GP_ASSERT(node);
             Node* parent = node->getParent();
             Node* parent = node->getParent();
-            
+
             std::vector<Node*> loadedNodes;
             std::vector<Node*> loadedNodes;
             while (true)
             while (true)
             {
             {
@@ -1151,7 +1151,7 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
                             return;
                             return;
                         }
                         }
                         std::string parentID = readString(_file);
                         std::string parentID = readString(_file);
-                        
+
                         if (!parentID.empty())
                         if (!parentID.empty())
                             nodeId = parentID;
                             nodeId = parentID;
                         else
                         else
@@ -1259,11 +1259,11 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
 {
 {
     GP_ASSERT(id);
     GP_ASSERT(id);
 
 
-    std::vector<unsigned long> keyTimes;
+    std::vector<unsigned int> keyTimes;
     std::vector<float> values;
     std::vector<float> values;
     std::vector<float> tangentsIn;
     std::vector<float> tangentsIn;
     std::vector<float> tangentsOut;
     std::vector<float> tangentsOut;
-    std::vector<unsigned long> interpolation;
+    std::vector<unsigned int> interpolation;
 
 
     // Length of the arrays.
     // Length of the arrays.
     unsigned int keyTimesCount;
     unsigned int keyTimesCount;
@@ -1278,28 +1278,28 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
         GP_ERROR("Failed to read key times for animation '%s'.", id);
         GP_ERROR("Failed to read key times for animation '%s'.", id);
         return NULL;
         return NULL;
     }
     }
-    
+
     // Read key values.
     // Read key values.
     if (!readArray(&valuesCount, &values))
     if (!readArray(&valuesCount, &values))
     {
     {
         GP_ERROR("Failed to read key values for animation '%s'.", id);
         GP_ERROR("Failed to read key values for animation '%s'.", id);
         return NULL;
         return NULL;
     }
     }
-    
+
     // Read in-tangents.
     // Read in-tangents.
     if (!readArray(&tangentsInCount, &tangentsIn))
     if (!readArray(&tangentsInCount, &tangentsIn))
     {
     {
         GP_ERROR("Failed to read in tangents for animation '%s'.", id);
         GP_ERROR("Failed to read in tangents for animation '%s'.", id);
         return NULL;
         return NULL;
     }
     }
-    
+
     // Read out-tangents.
     // Read out-tangents.
     if (!readArray(&tangentsOutCount, &tangentsOut))
     if (!readArray(&tangentsOutCount, &tangentsOut))
     {
     {
         GP_ERROR("Failed to read out tangents for animation '%s'.", id);
         GP_ERROR("Failed to read out tangents for animation '%s'.", id);
         return NULL;
         return NULL;
     }
     }
-    
+
     // Read interpolations.
     // Read interpolations.
     if (!readArray(&interpolationCount, &interpolation, sizeof(unsigned int)))
     if (!readArray(&interpolationCount, &interpolation, sizeof(unsigned int)))
     {
     {
@@ -1307,7 +1307,6 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
         return NULL;
         return NULL;
     }
     }
 
 
-    // TODO: Handle other target attributes later.
     if (targetAttribute > 0)
     if (targetAttribute > 0)
     {
     {
         GP_ASSERT(target);
         GP_ASSERT(target);
@@ -1520,7 +1519,7 @@ Bundle::MeshData* Bundle::readMeshData()
 
 
         partData->primitiveType = (Mesh::PrimitiveType)pType;
         partData->primitiveType = (Mesh::PrimitiveType)pType;
         partData->indexFormat = (Mesh::IndexFormat)iFormat;
         partData->indexFormat = (Mesh::IndexFormat)iFormat;
-        
+
         unsigned int indexSize = 0;
         unsigned int indexSize = 0;
         switch (partData->indexFormat)
         switch (partData->indexFormat)
         {
         {
@@ -1684,7 +1683,7 @@ Font* Bundle::loadFont(const char* id)
         SAFE_DELETE_ARRAY(glyphs);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
         return NULL;
     }
     }
-    
+
     // Read texture data.
     // Read texture data.
     unsigned char* textureData = new unsigned char[textureByteCount];
     unsigned char* textureData = new unsigned char[textureByteCount];
     if (fread(textureData, 1, textureByteCount, _file) != textureByteCount)
     if (fread(textureData, 1, textureByteCount, _file) != textureByteCount)
@@ -1750,7 +1749,7 @@ unsigned int Bundle::getObjectCount() const
     return _referenceCount;
     return _referenceCount;
 }
 }
 
 
-const char* Bundle::getObjectID(unsigned int index) const
+const char* Bundle::getObjectId(unsigned int index) const
 {
 {
     GP_ASSERT(_references);
     GP_ASSERT(_references);
     return (index >= _referenceCount ? NULL : _references[index].id.c_str());
     return (index >= _referenceCount ? NULL : _references[index].id.c_str());

+ 1 - 1
gameplay/src/Bundle.h

@@ -95,7 +95,7 @@ public:
      * 
      * 
      * @return The ID of the object at the given index, or NULL if index is invalid.
      * @return The ID of the object at the given index, or NULL if index is invalid.
      */
      */
-    const char* getObjectID(unsigned int index) const;
+    const char* getObjectId(unsigned int index) const;
 
 
 private:
 private:
 
 

+ 27 - 26
gameplay/src/Button.cpp

@@ -40,41 +40,42 @@ bool Button::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contac
     case Touch::TOUCH_PRESS:
     case Touch::TOUCH_PRESS:
         if (_contactIndex == INVALID_CONTACT_INDEX)
         if (_contactIndex == INVALID_CONTACT_INDEX)
         {
         {
-			if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-				y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-			{
-				_contactIndex = (int) contactIndex;
+            if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                _contactIndex = (int) contactIndex;
 
 
-				setState(Control::ACTIVE);
+                setState(Control::ACTIVE);
 
 
-				notifyListeners(Listener::PRESS);
+                notifyListeners(Listener::PRESS);
 
 
-				return _consumeInputEvents;
-			}
-			else
-			{
-				setState(Control::NORMAL);
-			}
+                return _consumeInputEvents;
+            }
+            else
+            {
+                setState(Control::NORMAL);
+            }
         }
         }
         break;
         break;
 
 
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
         if (_contactIndex == (int) contactIndex)
         if (_contactIndex == (int) contactIndex)
         {
         {
-			_contactIndex = INVALID_CONTACT_INDEX;
-			notifyListeners(Listener::RELEASE);
-			if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-				y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-			{
-				setState(Control::FOCUS);
-
-				notifyListeners(Listener::CLICK);
-			}
-			else
-			{
-				setState(Control::NORMAL);
-			}
-			return _consumeInputEvents;
+            _contactIndex = INVALID_CONTACT_INDEX;
+            notifyListeners(Listener::RELEASE);
+            if (!_parent->isScrolling() &&
+                x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                setState(Control::FOCUS);
+
+                notifyListeners(Listener::CLICK);
+            }
+            else
+            {
+                setState(Control::NORMAL);
+            }
+            return _consumeInputEvents;
         }
         }
         break;
         break;
     case Touch::TOUCH_MOVE:
     case Touch::TOUCH_MOVE:

+ 1 - 0
gameplay/src/Button.h

@@ -1,6 +1,7 @@
 #ifndef BUTTON_H_
 #ifndef BUTTON_H_
 #define BUTTON_H_
 #define BUTTON_H_
 
 
+#include "Container.h"
 #include "Label.h"
 #include "Label.h"
 #include "Touch.h"
 #include "Touch.h"
 #include "Theme.h"
 #include "Theme.h"

+ 10 - 9
gameplay/src/CheckBox.cpp

@@ -84,15 +84,16 @@ bool CheckBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int cont
     switch (evt)
     switch (evt)
     {
     {
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
-		if (_contactIndex == (int) contactIndex && _state == Control::ACTIVE)
-		{
-			if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-				y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-			{
-				_checked = !_checked;
-				notifyListeners(Control::Listener::VALUE_CHANGED);
-			}
-		}
+        if (_contactIndex == (int) contactIndex && _state == Control::ACTIVE)
+        {
+            if (!_parent->isScrolling() &&
+                x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                _checked = !_checked;
+                notifyListeners(Control::Listener::VALUE_CHANGED);
+            }
+        }
         break;
         break;
     }
     }
 
 

+ 159 - 81
gameplay/src/Container.cpp

@@ -20,6 +20,8 @@ namespace gameplay
 static const long SCROLL_INERTIA_DELAY = 100L;
 static const long SCROLL_INERTIA_DELAY = 100L;
 // Factor to multiply friction by before applying to velocity.
 // Factor to multiply friction by before applying to velocity.
 static const float SCROLL_FRICTION_FACTOR = 5.0f;
 static const float SCROLL_FRICTION_FACTOR = 5.0f;
+// Distance that must be scrolled before isScrolling() will return true, used e.g. to cancel button-click events.
+static const float SCROLL_THRESHOLD = 10.0f;
 
 
 /**
 /**
  * Sort function for use with _controls.sort(), based on Z-Order.
  * Sort function for use with _controls.sort(), based on Z-Order.
@@ -41,7 +43,7 @@ Container::Container()
       _scrollingRight(false), _scrollingDown(false),
       _scrollingRight(false), _scrollingDown(false),
       _scrollingMouseVertically(false), _scrollingMouseHorizontally(false),
       _scrollingMouseVertically(false), _scrollingMouseHorizontally(false),
       _scrollBarOpacityClip(NULL), _zIndexDefault(0), _focusIndexDefault(0), _focusIndexMax(0), _totalWidth(0), _totalHeight(0),
       _scrollBarOpacityClip(NULL), _zIndexDefault(0), _focusIndexDefault(0), _focusIndexMax(0), _totalWidth(0), _totalHeight(0),
-      _contactIndices(0)
+      _contactIndices(0), _initializedWithScroll(false)
 {
 {
 }
 }
 
 
@@ -172,6 +174,7 @@ void Container::addControls(Theme* theme, Properties* properties)
         if (control)
         if (control)
         {
         {
             addControl(control);
             addControl(control);
+            control->release();
 
 
             if (control->getZIndex() == -1)
             if (control->getZIndex() == -1)
             {
             {
@@ -204,32 +207,78 @@ Layout* Container::getLayout()
 unsigned int Container::addControl(Control* control)
 unsigned int Container::addControl(Control* control)
 {
 {
     GP_ASSERT(control);
     GP_ASSERT(control);
-    _controls.push_back(control);
 
 
-    return _controls.size() - 1;
+    if (control->_parent && control->_parent != this)
+    {
+        control->_parent->removeControl(control);
+    }
+
+    if (control->_parent != this)
+    {
+        _controls.push_back(control);
+        control->addRef();
+        control->_parent = this;
+        return _controls.size() - 1;
+    }
+    else
+    {
+        // Control is already in this container.
+        // Do nothing but determine and return control's index.
+        const size_t size = _controls.size();
+        for (size_t i = 0; i < size; ++i)
+        {
+            Control* c = _controls[i];
+            if (c == control)
+            {
+                return i;
+            }
+        }
+
+        // Should never reach this.
+        GP_ASSERT(false);
+        return 0;
+    }
 }
 }
 
 
 void Container::insertControl(Control* control, unsigned int index)
 void Container::insertControl(Control* control, unsigned int index)
 {
 {
     GP_ASSERT(control);
     GP_ASSERT(control);
-    std::vector<Control*>::iterator it = _controls.begin() + index;
-    _controls.insert(it, control);
+
+    if (control->_parent && control->_parent != this)
+    {
+        control->_parent->removeControl(control);
+    }
+
+    if (control->_parent != this)
+    {
+        std::vector<Control*>::iterator it = _controls.begin() + index;
+        _controls.insert(it, control);
+        control->addRef();
+        control->_parent = this;
+    }
 }
 }
 
 
 void Container::removeControl(unsigned int index)
 void Container::removeControl(unsigned int index)
 {
 {
+    GP_ASSERT(index < _controls.size());
+
     std::vector<Control*>::iterator it = _controls.begin() + index;
     std::vector<Control*>::iterator it = _controls.begin() + index;
     _controls.erase(it);
     _controls.erase(it);
+    Control* control = *it;
+    control->_parent = NULL;
+    SAFE_RELEASE(control);
 }
 }
 
 
 void Container::removeControl(const char* id)
 void Container::removeControl(const char* id)
 {
 {
+    GP_ASSERT(id);
     std::vector<Control*>::iterator it;
     std::vector<Control*>::iterator it;
     for (it = _controls.begin(); it < _controls.end(); it++)
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
     {
         Control* c = *it;
         Control* c = *it;
         if (strcmp(id, c->getId()) == 0)
         if (strcmp(id, c->getId()) == 0)
         {
         {
+            SAFE_RELEASE(c);
             _controls.erase(it);
             _controls.erase(it);
             return;
             return;
         }
         }
@@ -244,6 +293,7 @@ void Container::removeControl(Control* control)
     {
     {
         if (*it == control)
         if (*it == control)
         {
         {
+            SAFE_RELEASE(control);
             _controls.erase(it);
             _controls.erase(it);
             return;
             return;
         }
         }
@@ -313,6 +363,16 @@ bool Container::isScrollBarsAutoHide() const
     return _scrollBarsAutoHide;
     return _scrollBarsAutoHide;
 }
 }
 
 
+bool Container::isScrolling() const
+{
+    if (_parent && _parent->isScrolling())
+        return true;
+
+    return (_scrolling &&
+            (abs(_scrollingLastX - _scrollingFirstX) > SCROLL_THRESHOLD ||
+             abs(_scrollingLastY - _scrollingFirstY) > SCROLL_THRESHOLD));
+}
+
 Animation* Container::getAnimation(const char* id) const
 Animation* Container::getAnimation(const char* id) const
 {
 {
     std::vector<Control*>::const_iterator itr = _controls.begin();
     std::vector<Control*>::const_iterator itr = _controls.begin();
@@ -533,6 +593,11 @@ bool Container::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 
 
 bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
 bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
 {
 {
+    // This event may run untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this container, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     std::vector<Control*>::const_iterator it;
     std::vector<Control*>::const_iterator it;
     for (it = _controls.begin(); it < _controls.end(); it++)
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
     {
@@ -547,7 +612,8 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
         {
         {
             if (control->keyEvent(evt, key))
             if (control->keyEvent(evt, key))
             {
             {
-                return _consumeInputEvents;
+                release();
+                return true;
             }
             }
             else if (evt == Keyboard::KEY_CHAR && key == Keyboard::KEY_TAB)
             else if (evt == Keyboard::KEY_CHAR && key == Keyboard::KEY_TAB)
             {
             {
@@ -566,6 +632,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
                     if (nextControl->getFocusIndex() == focusIndex)
                     if (nextControl->getFocusIndex() == focusIndex)
                     {
                     {
                         nextControl->setState(Control::FOCUS);
                         nextControl->setState(Control::FOCUS);
+                        release();
                         return _consumeInputEvents;
                         return _consumeInputEvents;
                     }
                     }
                 }
                 }
@@ -573,6 +640,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
         }
         }
     }
     }
 
 
+    release();
     return false;
     return false;
 }
 }
 
 
@@ -602,10 +670,6 @@ Layout::Type Container::getLayoutType(const char* layoutString)
     {
     {
         return Layout::LAYOUT_FLOW;
         return Layout::LAYOUT_FLOW;
     }
     }
-    else if (layoutName == "LAYOUT_SCROLL")
-    {
-        return Layout::LAYOUT_SCROLL;
-    }
     else
     else
     {
     {
         // Default.
         // Default.
@@ -615,6 +679,12 @@ Layout::Type Container::getLayoutType(const char* layoutString)
 
 
 void Container::updateScroll()
 void Container::updateScroll()
 {
 {
+    if (!_initializedWithScroll)
+    {
+        _initializedWithScroll = true;
+        _layout->update(this, _scrollPosition);
+    }
+
     // Update Time.
     // Update Time.
     static double lastFrameTime = Game::getGameTime();
     static double lastFrameTime = Game::getGameTime();
     double frameTime = Game::getGameTime();
     double frameTime = Game::getGameTime();
@@ -730,26 +800,26 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
     switch(evt)
     switch(evt)
     {
     {
     case Touch::TOUCH_PRESS:
     case Touch::TOUCH_PRESS:
-    	if (_contactIndex == INVALID_CONTACT_INDEX)
-    	{
-    		_contactIndex = (int) contactIndex;
-    		_contactIndices++;
-			_scrollingLastX = _scrollingFirstX = x;
-			_scrollingLastY = _scrollingFirstY = y;
-			_scrollingVelocity.set(0, 0);
-			_scrolling = true;
-			_scrollingStartTimeX = _scrollingStartTimeY = 0;
-
-			if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
-			{
-				_scrollBarOpacityClip->stop();
-				_scrollBarOpacityClip = NULL;
-			}
-			_scrollBarOpacity = 1.0f;
+        if (_contactIndex == INVALID_CONTACT_INDEX)
+        {
+            _contactIndex = (int) contactIndex;
+            _contactIndices++;
+            _scrollingLastX = _scrollingFirstX = x;
+            _scrollingLastY = _scrollingFirstY = y;
+            _scrollingVelocity.set(0, 0);
+            _scrolling = true;
+            _scrollingStartTimeX = _scrollingStartTimeY = 0;
+
+            if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
+            {
+                _scrollBarOpacityClip->stop();
+                _scrollBarOpacityClip = NULL;
+            }
+            _scrollBarOpacity = 1.0f;
             _dirty = true;
             _dirty = true;
-			return _consumeInputEvents;
-    	}
-		break;
+            return _consumeInputEvents;
+        }
+        break;
     case Touch::TOUCH_MOVE:
     case Touch::TOUCH_MOVE:
         if (_scrolling && _contactIndex == (int) contactIndex)
         if (_scrolling && _contactIndex == (int) contactIndex)
         {
         {
@@ -814,58 +884,58 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         break;
         break;
 
 
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
-    	if (_contactIndex == (int) contactIndex)
-    	{
-    		_contactIndex = INVALID_CONTACT_INDEX;
-    		_contactIndices--;
-			_scrolling = false;
-			double gameTime = Game::getAbsoluteTime();
-			float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
-			if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
-			{
-				_scrollingVelocity.set(0, 0);
-				_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+        if (_contactIndex == (int) contactIndex)
+        {
+            _contactIndex = INVALID_CONTACT_INDEX;
+            _contactIndices--;
+            _scrolling = false;
+            double gameTime = Game::getAbsoluteTime();
+            float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
+            if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
+            {
+                _scrollingVelocity.set(0, 0);
+                _scrollingMouseVertically = _scrollingMouseHorizontally = false;
                 _dirty = true;
                 _dirty = true;
-				return _consumeInputEvents;
-			}
-
-			int dx = _scrollingLastX - _scrollingFirstX;
-			int dy = _scrollingLastY - _scrollingFirstY;
-
-			float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
-			float elapsedSecsX = timeTakenX * 0.001f;
-			float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
-			float elapsedSecsY = timeTakenY * 0.001f;
-
-			float vx = dx;
-			float vy = dy;
-			if (elapsedSecsX > 0)
-				vx = (float)dx / elapsedSecsX;
-			if (elapsedSecsY > 0)
-				vy = (float)dy / elapsedSecsY;
-
-			if (_scrollingMouseVertically)
-			{
-				float yRatio = _totalHeight / _absoluteBounds.height;
-				vy *= yRatio;
-				_scrollingVelocity.set(0, -vy);
-			}
-			else if (_scrollingMouseHorizontally)
-			{
-				float xRatio = _totalWidth / _absoluteBounds.width;
-				vx *= xRatio;
-				_scrollingVelocity.set(-vx, 0);
-			}
-			else
-			{
-				_scrollingVelocity.set(vx, vy);
-			}
-
-			_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+                return _consumeInputEvents;
+            }
+
+            int dx = _scrollingLastX - _scrollingFirstX;
+            int dy = _scrollingLastY - _scrollingFirstY;
+
+            float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
+            float elapsedSecsX = timeTakenX * 0.001f;
+            float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
+            float elapsedSecsY = timeTakenY * 0.001f;
+
+            float vx = dx;
+            float vy = dy;
+            if (elapsedSecsX > 0)
+                vx = (float)dx / elapsedSecsX;
+            if (elapsedSecsY > 0)
+                vy = (float)dy / elapsedSecsY;
+
+            if (_scrollingMouseVertically)
+            {
+                float yRatio = _totalHeight / _absoluteBounds.height;
+                vy *= yRatio;
+                _scrollingVelocity.set(0, -vy);
+            }
+            else if (_scrollingMouseHorizontally)
+            {
+                float xRatio = _totalWidth / _absoluteBounds.width;
+                vx *= xRatio;
+                _scrollingVelocity.set(-vx, 0);
+            }
+            else
+            {
+                _scrollingVelocity.set(vx, vy);
+            }
+
+            _scrollingMouseVertically = _scrollingMouseHorizontally = false;
             _dirty = true;
             _dirty = true;
-			return _consumeInputEvents;
-    	}
-    	break;
+            return _consumeInputEvents;
+        }
+        break;
     }
     }
 
 
     return false;
     return false;
@@ -955,6 +1025,11 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         return false;
         return false;
     }
     }
 
 
+    // This event may run untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this container, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     bool eventConsumed = false;
     bool eventConsumed = false;
     const Theme::Border& border = getBorder(_state);
     const Theme::Border& border = getBorder(_state);
     const Theme::Padding& padding = getPadding();
     const Theme::Padding& padding = getPadding();
@@ -987,8 +1062,8 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         }
         }
 
 
         Control::State currentState = control->getState();
         Control::State currentState = control->getState();
-        if ((control->isContainer() && currentState == Control::FOCUS) || 
-            (currentState != Control::NORMAL) ||// && control->_contactIndex == data) ||
+        if ((control->isContainer() && currentState == Control::FOCUS) ||
+            (currentState != Control::NORMAL) ||
             ((evt == Touch::TOUCH_PRESS ||
             ((evt == Touch::TOUCH_PRESS ||
               evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
               evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
               evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
               evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
@@ -1008,6 +1083,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
 
 
     if (!isEnabled())
     if (!isEnabled())
     {
     {
+        release();
         return (_consumeInputEvents | eventConsumed);
         return (_consumeInputEvents | eventConsumed);
     }
     }
     
     
@@ -1027,6 +1103,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         {
         {
             setState(Control::NORMAL);
             setState(Control::NORMAL);
             _contactIndex = INVALID_CONTACT_INDEX;
             _contactIndex = INVALID_CONTACT_INDEX;
+            release();
             return false;
             return false;
         }
         }
         break;
         break;
@@ -1050,6 +1127,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         }
         }
     }
     }
 
 
+    release();
     return (_consumeInputEvents | eventConsumed);
     return (_consumeInputEvents | eventConsumed);
 }
 }
 
 

+ 9 - 0
gameplay/src/Container.h

@@ -175,6 +175,13 @@ public:
      */
      */
     bool isScrollBarsAutoHide() const;
     bool isScrollBarsAutoHide() const;
 
 
+    /**
+     * Whether this container is currently being scrolled.
+     *
+     * @return Whether this container is currently being scrolled.
+     */
+    bool isScrolling() const;
+
     /**
     /**
      * @see AnimationTarget::getAnimation
      * @see AnimationTarget::getAnimation
      */
      */
@@ -507,6 +514,8 @@ private:
     float _totalHeight;
     float _totalHeight;
 
 
     int _contactIndices;
     int _contactIndices;
+
+    bool _initializedWithScroll;
 };
 };
 
 
 }
 }

+ 39 - 14
gameplay/src/Control.cpp

@@ -7,8 +7,8 @@ namespace gameplay
 
 
 Control::Control()
 Control::Control()
     : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
     : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
-    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _listeners(NULL),
-    _contactIndex(INVALID_CONTACT_INDEX), _styleOverridden(false), _skin(NULL)
+    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _alignment(ALIGN_TOP_LEFT), _autoWidth(false), _autoHeight(false), _listeners(NULL),
+    _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(0), _parent(NULL), _styleOverridden(false), _skin(NULL)
 {
 {
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
 }
 }
@@ -41,7 +41,7 @@ void Control::initialize(Theme::Style* style, Properties* properties)
     _autoWidth = properties->getBool("autoWidth");
     _autoWidth = properties->getBool("autoWidth");
     _autoHeight = properties->getBool("autoHeight");
     _autoHeight = properties->getBool("autoHeight");
 
 
-    _consumeInputEvents = properties->getBool("consumeEvents", true);
+    _consumeInputEvents = properties->getBool("consumeInputEvents", true);
 
 
     if (properties->exists("zIndex"))
     if (properties->exists("zIndex"))
     {
     {
@@ -153,6 +153,24 @@ void Control::setSize(float width, float height)
     }
     }
 }
 }
 
 
+void Control::setWidth(float width)
+{
+    if (width != _bounds.width)
+    {
+        _bounds.width = width;
+        _dirty = true;
+    }
+}
+
+void Control::setHeight(float height)
+{
+    if (height != _bounds.height)
+    {
+        _bounds.height = height;
+        _dirty = true;
+    }
+}
+
 void Control::setBounds(const Rectangle& bounds)
 void Control::setBounds(const Rectangle& bounds)
 {
 {
     if (bounds != _bounds)
     if (bounds != _bounds)
@@ -726,20 +744,20 @@ bool Control::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
         if (_contactIndex == (int)contactIndex)
         if (_contactIndex == (int)contactIndex)
         {
         {
-			_contactIndex = INVALID_CONTACT_INDEX;
+            _contactIndex = INVALID_CONTACT_INDEX;
 
 
-			// Always trigger Listener::RELEASE
-			notifyListeners(Listener::RELEASE);
+            // Always trigger Listener::RELEASE
+            notifyListeners(Listener::RELEASE);
 
 
-			// Only trigger Listener::CLICK if both PRESS and RELEASE took place within the control's bounds.
-			if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-				y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-			{
-				// Leave this control in the FOCUS state.
-				notifyListeners(Listener::CLICK);
-			}
+            // Only trigger Listener::CLICK if both PRESS and RELEASE took place within the control's bounds.
+            if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                // Leave this control in the FOCUS state.
+                notifyListeners(Listener::CLICK);
+            }
 
 
-			return _consumeInputEvents;
+            return _consumeInputEvents;
         }
         }
         break;
         break;
     }
     }
@@ -780,6 +798,11 @@ bool Control::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 
 
 void Control::notifyListeners(Listener::EventType eventType)
 void Control::notifyListeners(Listener::EventType eventType)
 {
 {
+    // This method runs untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this control, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     if (_listeners)
     if (_listeners)
     {
     {
         std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->find(eventType);
         std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->find(eventType);
@@ -795,6 +818,8 @@ void Control::notifyListeners(Listener::EventType eventType)
     }
     }
 
 
     fireScriptEvent<void>("controlEvent", this, eventType);
     fireScriptEvent<void>("controlEvent", this, eventType);
+
+    release();
 }
 }
 
 
 void Control::update(const Control* container, const Vector2& offset)
 void Control::update(const Control* container, const Vector2& offset)

+ 21 - 0
gameplay/src/Control.h

@@ -15,6 +15,8 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
+class Container;
+
 /**
 /**
  * Base class for UI controls.
  * Base class for UI controls.
  */
  */
@@ -212,6 +214,20 @@ public:
      */
      */
     virtual void setSize(float width, float height);
     virtual void setSize(float width, float height);
 
 
+    /** 
+     * Set the desired width of the control, including it's border and padding, before clipping.
+     *
+     * @param width The width.
+     */
+    virtual void setWidth(float width);
+
+    /** 
+     * Set the desired height of the control, including it's border and padding, before clipping.
+     *
+     * @param height The height.
+     */
+    virtual void setHeight(float height);
+
     /**
     /**
      * Set the bounds of this control, relative to its parent container and including its
      * Set the bounds of this control, relative to its parent container and including its
      * border and padding, before clipping.
      * border and padding, before clipping.
@@ -990,6 +1006,11 @@ protected:
      */
      */
     int _focusIndex;
     int _focusIndex;
 
 
+    /**
+     * The control's parent container.
+     */
+    Container* _parent;
+
 private:
 private:
 
 
     /*
     /*

部分文件因文件數量過多而無法顯示