Преглед изворни кода

Merging with upstream/next

Adam Blake пре 13 година
родитељ
комит
a81cf4d3be
72 измењених фајлова са 1220 додато и 364 уклоњено
  1. 3 1
      CHANGES.md
  2. 1 1
      README.md
  3. 15 1
      gameplay-api/header.html
  4. 4 0
      gameplay-encoder/CMakeLists.txt
  5. 3 2
      gameplay-newproject.bat
  6. 1 0
      gameplay-newproject.sh
  7. BIN
      gameplay-template/[email protected]
  8. 16 12
      gameplay-template/gameplay-template-CMakeLists.txt
  9. 128 110
      gameplay-template/gameplay-template.xcodeproj/project.pbxproj
  10. 17 36
      gameplay.doxyfile
  11. 36 38
      gameplay/gameplay.xcodeproj/project.pbxproj
  12. 1 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme
  13. 1 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme
  14. 6 0
      gameplay/src/Animation.cpp
  15. 0 1
      gameplay/src/AnimationClip.cpp
  16. 18 1
      gameplay/src/AnimationTarget.cpp
  17. 3 2
      gameplay/src/Base.h
  18. 1 1
      gameplay/src/Button.h
  19. 1 1
      gameplay/src/CheckBox.h
  20. 2 2
      gameplay/src/Container.h
  21. 1 1
      gameplay/src/Control.h
  22. 46 7
      gameplay/src/DepthStencilTarget.cpp
  23. 2 1
      gameplay/src/DepthStencilTarget.h
  24. 2 2
      gameplay/src/FrameBuffer.cpp
  25. 1 0
      gameplay/src/Game.cpp
  26. 20 1
      gameplay/src/Game.h
  27. 10 0
      gameplay/src/Game.inl
  28. 89 3
      gameplay/src/Joint.cpp
  29. 26 7
      gameplay/src/Joint.h
  30. 1 1
      gameplay/src/Joystick.h
  31. 1 1
      gameplay/src/Layout.h
  32. 3 0
      gameplay/src/MaterialParameter.cpp
  33. 66 0
      gameplay/src/MeshBatch.cpp
  34. 25 1
      gameplay/src/MeshBatch.h
  35. 1 56
      gameplay/src/MeshBatch.inl
  36. 2 2
      gameplay/src/MeshSkin.cpp
  37. 1 0
      gameplay/src/MeshSkin.h
  38. 1 0
      gameplay/src/Model.h
  39. 8 7
      gameplay/src/Node.cpp
  40. 1 1
      gameplay/src/Node.h
  41. 19 0
      gameplay/src/Platform.h
  42. 52 12
      gameplay/src/PlatformAndroid.cpp
  43. 26 0
      gameplay/src/PlatformBlackBerry.cpp
  44. 30 1
      gameplay/src/PlatformLinux.cpp
  45. 27 0
      gameplay/src/PlatformMacOSX.mm
  46. 36 1
      gameplay/src/PlatformWindows.cpp
  47. 97 3
      gameplay/src/PlatformiOS.mm
  48. 1 1
      gameplay/src/RadioButton.h
  49. 58 21
      gameplay/src/RenderState.cpp
  50. 28 1
      gameplay/src/RenderState.h
  51. 24 0
      gameplay/src/Scene.cpp
  52. 17 15
      gameplay/src/Scene.h
  53. 1 1
      gameplay/src/ScriptController.h
  54. 1 1
      gameplay/src/Slider.h
  55. 5 0
      gameplay/src/Terrain.cpp
  56. 4 0
      gameplay/src/TerrainPatch.cpp
  57. 2 0
      gameplay/src/TerrainPatch.h
  58. 1 1
      gameplay/src/TextBox.h
  59. 10 0
      gameplay/src/Vector2.h
  60. 5 0
      gameplay/src/Vector2.inl
  61. 10 0
      gameplay/src/Vector3.h
  62. 5 0
      gameplay/src/Vector3.inl
  63. 10 0
      gameplay/src/Vector4.h
  64. 5 0
      gameplay/src/Vector4.inl
  65. 73 0
      gameplay/src/lua/lua_Game.cpp
  66. 2 0
      gameplay/src/lua/lua_Game.h
  67. 1 0
      gameplay/src/lua/lua_Gamepad.cpp
  68. 1 1
      gameplay/src/lua/lua_Global.cpp
  69. 98 0
      gameplay/src/lua/lua_MeshBatch.cpp
  70. 1 0
      gameplay/src/lua/lua_MeshBatch.h
  71. 5 5
      gameplay/src/lua/lua_RenderStateBlend.cpp
  72. 1 0
      gameplay/src/lua/lua_Terrain.cpp

+ 3 - 1
CHANGES.md

@@ -1,4 +1,5 @@
 ## v1.6.0
+
 - Adds file Stream interface for reading/writing files instead of using fread/fwrite. 
 - Adds Terrain class to support for heightmap based terrains featuring LOD, multiple surface layers, loading from PNG, RAW8/16, full transform, physics, patch culling and verticle skirt for cracks.
 - Adds object-space normal map generation to gameplay-encoder for terrain normal map generation.
@@ -23,7 +24,8 @@
 - Adds support for preprocessor directive NO_LUA_BINDINGS in the gameplay project to omit inclusion of generated lua bindings in compilation for developer mode value. 
 - Adds optimizations to Lua generator to only write generated files if they differ from existing files, reducing both build times and committing of unchanged script binding files.
 - Adds changes to Slider for setValueTextVisible, setValueTextAlignment, setValueTextPrecision and getters.
-- Adds Windows 7 64-bit support.
+- Adds Microsoft Windows 7 64-bit support.
+- Adds Apple iOS 6 support.
 - Fixes to external-deps to reduce the size of the libraries on Windows.
 - Fixes for Android to no longer need to copy files to the SD card before reading them. None of the Android samples require an SD card.
 - Fixes for animation of opacity on UI and fonts.

+ 1 - 1
README.md

@@ -12,7 +12,7 @@ GamePlay3D is an open-source, cross-platform 3D native C++ game framework making
 
 ## Supported Mobile Platforms
 - [BlackBerry 10 and PlayBook](https://github.com/blackberry/GamePlay/wiki/BlackBerry-Setup) (using BlackBerry Native SDK)
-- [Apple iOS 5](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
+- [Apple iOS 5+](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
 - [Google Android 2.3+](https://github.com/blackberry/GamePlay/wiki/Android-NDK-Setup) (using Google Android NDK)
 
 ## Supported Desktop Platforms

+ 15 - 1
gameplay-api/header.html

@@ -7,6 +7,7 @@
 
 <link href="tabs.css" rel="stylesheet" type="text/css"/>
 <link href="doxygen.css" rel="stylesheet" type="text/css" />
+<link href="custom.css" rel="stylesheet" type="text/css" />
 
 <link href="search/search.css" rel="stylesheet" type="text/css"/>
 <script type="text/javascript" src="jquery.js"></script>
@@ -17,4 +18,17 @@
 
 </head>
 <body>
-<div id="top"><!-- do not remove this div! -->
+<div id="top"><!-- do not remove this div! -->
+<table class="header" border="0">
+<tbody>
+<tr>
+<td id="logo"><a href="http://gameplay3d.org/"><img src="images/logo.png" alt="gameplay" border="0" height="64px"/></a></td>
+<td width="100%"/>
+<td><a href="http://gameplay3d.org/"><span class="button">overview</span></a></td><td width="12px"/>
+<td><a href="https://github.com/blackberry/GamePlay/wiki"><span class="button">wiki</span></a></td><td width="12px"/>
+<td><a href="http://blackberry.github.com/GamePlay/api/index.html"><span class="button">api&nbsp;reference</span></a></td><td width="12px"/>
+<td><a href="http://www.gameplay3d.org/forums"><span class="button">forums</span></a></td>
+<td><a href="https://github.com/blackberry/GamePlay"><span class="button">download</span></a></td>
+</tr>
+</tbody>
+</table>

+ 4 - 0
gameplay-encoder/CMakeLists.txt

@@ -77,6 +77,8 @@ set(APP_SRC
 	src/GPBFile.h
 	src/Heightmap.cpp
 	src/Heightmap.h
+	src/Image.cpp
+	src/Image.h
 	src/Light.cpp
 	src/Light.h
 	src/main.cpp
@@ -98,6 +100,8 @@ set(APP_SRC
 	src/Model.h
 	src/Node.cpp
 	src/Node.h
+	src/NormalMapGenerator.cpp
+	src/NormalMapGenerator.h
 	src/Object.cpp
 	src/Object.h
 	src/Quaternion.cpp

+ 3 - 2
gameplay-newproject.bat

@@ -171,7 +171,7 @@ copy gameplay-template\gameplay-template.vcxproj.user "%projPath%\%projName%.vcx
 call:replace "%projPath%\%projName%.vcxproj.user" GAMEPLAY_PATH "%gpPath%"
 
 REM Copy Apple XCode project files
-mkdir "%projPath%\%projName%.xcodeproj"
+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%"
@@ -181,7 +181,8 @@ copy gameplay-template\TEMPLATE_PROJECT-macosx.plist "%projPath%\%projName%-maco
 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"
+copy gameplay-template\TEMPLATE_PROJECT-ios.plist "%projPath%\%projName%-ios.plist"
+copy gameplay-template\[email protected] "%projPath%\[email protected]"
 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%"

+ 1 - 0
gameplay-newproject.sh

@@ -198,6 +198,7 @@ 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/[email protected]" "$projPath/[email protected]"
 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"


+ 16 - 12
gameplay-template/gameplay-template-CMakeLists.txt

@@ -37,21 +37,25 @@ macro (append_gameplay_ext_lib listToAppend libName libDirName)
     message(STATUS "Library Found: ${libName} Path: ${FOUND_LIB_${libName}}")
 endmacro (append_gameplay_ext_lib)
 
-macro(copy_files TARGET_NAME GLOBPAT SOURCE DESTINATION)
-  file(GLOB_RECURSE COPY_FILES
-    RELATIVE ${SOURCE}
-    "${SOURCE}/${GLOBPAT}")
-  add_custom_target(${TARGET_NAME} ALL
-    COMMENT "Copying files: ${SOURCE}/${GLOBPAT}")
+macro(copy_files TARGET_NAME GLOBPAT SOURCE DESTINATION RECUR)
+    IF(${RECUR})
+        SET(RECURSE_PARAM GLOB_RECURSE)
+    ELSEIF(NOT ${RECUR})
+        SET(RECURSE_PARAM GLOB)
+    ENDIF(${RECUR})
+    file(${RECURSE_PARAM} COPY_FILES RELATIVE ${SOURCE} "${SOURCE}/${GLOBPAT}")
+
+  add_custom_target(${TARGET_NAME} ALL COMMENT "Copying files: ${SOURCE}/${GLOBPAT}")
 
   foreach(FILENAME ${COPY_FILES})
     set(SRC "${SOURCE}/${FILENAME}")
     set(DST "${DESTINATION}/${FILENAME}")
 
-    add_custom_command(
-      TARGET ${TARGET_NAME}
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC} ${DST}
-      )
+    IF(IS_DIRECTORY ${SRC})
+        add_custom_command(TARGET ${TARGET_NAME} COMMAND ${CMAKE_COMMAND} -E make_directory ${DST})
+    ELSE(IS_DIRECTORY ${SRC})
+        add_custom_command(TARGET ${TARGET_NAME} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC} ${DST})
+    ENDIF(IS_DIRECTORY ${SRC})
   endforeach(FILENAME)
 endmacro(copy_files)
 
@@ -109,5 +113,5 @@ set_target_properties(${GAME_NAME} PROPERTIES
 #TODO: Copy res files to the bin dir, it is done that way so we can make post
 #processing to the the res files in the future like zipping or preparation to
 #per platfom format.
-copy_files(CopyRes * "${CMAKE_SOURCE_DIR}/res" "${GAME_OUTPUT_DIR}/res")
-copy_files(CopyConfig *.config "${CMAKE_SOURCE_DIR}" "${GAME_OUTPUT_DIR}")
+copy_files(CopyRes * "${CMAKE_SOURCE_DIR}/res" "${GAME_OUTPUT_DIR}/res" 1)
+copy_files(CopyConfig *.config "${CMAKE_SOURCE_DIR}" "${GAME_OUTPUT_DIR}" 0)

+ 128 - 110
gameplay-template/gameplay-template.xcodeproj/project.pbxproj

@@ -7,7 +7,30 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
+		42049B5816ADBB61005DD1F9 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5216ADBB61005DD1F9 /* CoreMotion.framework */; };
+		42049B5916ADBB61005DD1F9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5316ADBB61005DD1F9 /* Foundation.framework */; };
+		42049B5A16ADBB61005DD1F9 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5416ADBB61005DD1F9 /* OpenAL.framework */; };
+		42049B5B16ADBB61005DD1F9 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5516ADBB61005DD1F9 /* OpenGLES.framework */; };
+		42049B5C16ADBB61005DD1F9 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5616ADBB61005DD1F9 /* QuartzCore.framework */; };
+		42049B5D16ADBB61005DD1F9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5716ADBB61005DD1F9 /* UIKit.framework */; };
+		42049B5F16ADBBF5005DD1F9 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5E16ADBBF5005DD1F9 /* libz.dylib */; };
+		42049B6116ADBC0F005DD1F9 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6016ADBC0F005DD1F9 /* libbullet.a */; };
+		42049B6316ADBC30005DD1F9 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6216ADBC30005DD1F9 /* libbullet.a */; };
+		42049B6516ADBC47005DD1F9 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6416ADBC47005DD1F9 /* liblua.a */; };
+		42049B6A16ADBC63005DD1F9 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6616ADBC63005DD1F9 /* libogg.a */; };
+		42049B6B16ADBC63005DD1F9 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6716ADBC63005DD1F9 /* libvorbis.a */; };
+		42049B6C16ADBC63005DD1F9 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6816ADBC63005DD1F9 /* libvorbisenc.a */; };
+		42049B6D16ADBC63005DD1F9 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6916ADBC63005DD1F9 /* libvorbisfile.a */; };
+		42049B6F16ADBC7A005DD1F9 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6E16ADBC7A005DD1F9 /* libpng.a */; };
+		42049B7116ADBC8B005DD1F9 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7016ADBC8B005DD1F9 /* libpng.a */; };
+		42049B7316ADBCAB005DD1F9 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7216ADBCAB005DD1F9 /* liblua.a */; };
+		42049B7816ADBCC3005DD1F9 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7416ADBCC3005DD1F9 /* libogg.a */; };
+		42049B7916ADBCC3005DD1F9 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7516ADBCC3005DD1F9 /* libvorbis.a */; };
+		42049B7A16ADBCC3005DD1F9 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */; };
+		42049B7B16ADBCC3005DD1F9 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */; };
+		42049B7D16ADBCDB005DD1F9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 42049B7C16ADBCDB005DD1F9 /* [email protected] */; };
+		421539CA16ADC583001308A3 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 421539C916ADC583001308A3 /* libgameplay.a */; };
+		421539CD16ADC592001308A3 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 421539CC16ADC592001308A3 /* libgameplay.a */; };
 		424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424CC03B161FCBDD00577827 /* IOKit.framework */; };
 		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
@@ -19,34 +42,35 @@
 		42C9331F1491A67F0098216A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331E1491A67F0098216A /* OpenAL.framework */; };
 		42C9332F1491A78D0098216A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		5B61611614CCC24C0073B857 /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
-		5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
 		5B61612614CCC24C0073B857 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		5B61612714CCC24C0073B857 /* res in Resources */ = {isa = PBXBuildFile; fileRef = 42C932F21491A53E0098216A /* res */; };
-		5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */; };
-		5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2068152F2DDD003E2AC3 /* Foundation.framework */; };
-		5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */; };
-		5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */; };
-		5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */; };
-		5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206C152F2DDD003E2AC3 /* UIKit.framework */; };
-		F1F49B8B16AD8E02008715A2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8A16AD8E02008715A2 /* libz.dylib */; };
-		F1F49B8D16AD8F1B008715A2 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8C16AD8F1B008715A2 /* libbullet.a */; };
-		F1F49B8F16AD8F3F008715A2 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49B8E16AD8F3F008715A2 /* libbullet.a */; };
-		F1F49BC616AD94EE008715A2 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC216AD94EE008715A2 /* libogg.a */; };
-		F1F49BC716AD94EE008715A2 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC316AD94EE008715A2 /* libvorbis.a */; };
-		F1F49BC816AD94EE008715A2 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC416AD94EE008715A2 /* libvorbisenc.a */; };
-		F1F49BC916AD94EE008715A2 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BC516AD94EE008715A2 /* libvorbisfile.a */; };
-		F1F49BCC16AD9502008715A2 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCB16AD9502008715A2 /* libpng.a */; };
-		F1F49BD116AD951A008715A2 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCD16AD951A008715A2 /* libogg.a */; };
-		F1F49BD216AD951A008715A2 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCE16AD951A008715A2 /* libvorbis.a */; };
-		F1F49BD316AD951A008715A2 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BCF16AD951A008715A2 /* libvorbisenc.a */; };
-		F1F49BD416AD951A008715A2 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BD016AD951A008715A2 /* libvorbisfile.a */; };
-		F1F49BD616AD9535008715A2 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BD516AD9535008715A2 /* libpng.a */; };
-		F1F49BEE16AD9BD4008715A2 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BED16AD9BD4008715A2 /* liblua.a */; };
-		F1F49BF116AD9BFB008715A2 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1F49BF016AD9BFB008715A2 /* liblua.a */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
-		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>"; };
+		42049B5216ADBB61005DD1F9 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5316ADBB61005DD1F9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5416ADBB61005DD1F9 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5516ADBB61005DD1F9 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5616ADBB61005DD1F9 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5716ADBB61005DD1F9 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5E16ADBBF5005DD1F9 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		42049B6016ADBC0F005DD1F9 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/ios/armv7/libbullet.a"; sourceTree = "<group>"; };
+		42049B6216ADBC30005DD1F9 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
+		42049B6416ADBC47005DD1F9 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/external-deps/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
+		42049B6616ADBC63005DD1F9 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
+		42049B6716ADBC63005DD1F9 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
+		42049B6816ADBC63005DD1F9 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisenc.a"; sourceTree = "<group>"; };
+		42049B6916ADBC63005DD1F9 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisfile.a"; sourceTree = "<group>"; };
+		42049B6E16ADBC7A005DD1F9 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+		42049B7016ADBC8B005DD1F9 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/ios/armv7/libpng.a"; sourceTree = "<group>"; };
+		42049B7216ADBCAB005DD1F9 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/external-deps/lua/lib/ios/armv7/liblua.a"; sourceTree = "<group>"; };
+		42049B7416ADBCC3005DD1F9 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libogg.a"; sourceTree = "<group>"; };
+		42049B7516ADBCC3005DD1F9 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbis.a"; sourceTree = "<group>"; };
+		42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbisenc.a"; sourceTree = "<group>"; };
+		42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbisfile.a"; sourceTree = "<group>"; };
+		42049B7C16ADBCDB005DD1F9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
+		421539C916ADC583001308A3 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
+		421539CC16ADC592001308A3 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos/libgameplay.a"; sourceTree = "<group>"; };
 		424CC03B161FCBDD00577827 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
 		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -62,29 +86,8 @@
 		5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-macosx.plist"; sourceTree = "<group>"; };
 		5B61612C14CCC24C0073B857 /* TEMPLATE_PROJECT-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		5B61612E14CCC24D0073B857 /* TEMPLATE_PROJECT-ios.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-ios.plist"; sourceTree = "<group>"; };
-		5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2068152F2DDD003E2AC3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206C152F2DDD003E2AC3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gameplay.xcodeproj; path = GAMEPLAY_PATH/gameplay/gameplay.xcodeproj; sourceTree = SOURCE_ROOT; };
 		5BC4E849150F911D00CBE1C0 /* shaders */ = {isa = PBXFileReference; lastKnownFileType = text; name = shaders; path = GAMEPLAY_PATH/gameplay/res/shaders; sourceTree = SOURCE_ROOT; };
-		F1F49B8A16AD8E02008715A2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
-		F1F49B8C16AD8F1B008715A2 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = GAMEPLAY_PATH/bullet/lib/macosx/libbullet.a; sourceTree = "<group>"; };
-		F1F49B8E16AD8F3F008715A2 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/bullet/lib/ios/$(CURRENT_ARCH)/libbullet.a"; sourceTree = "<group>"; };
-		F1F49BC216AD94EE008715A2 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libogg.a; sourceTree = "<group>"; };
-		F1F49BC316AD94EE008715A2 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbis.a; sourceTree = "<group>"; };
-		F1F49BC416AD94EE008715A2 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbisenc.a; sourceTree = "<group>"; };
-		F1F49BC516AD94EE008715A2 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = GAMEPLAY_PATH/oggvorbis/lib/macosx/libvorbisfile.a; sourceTree = "<group>"; };
-		F1F49BCB16AD9502008715A2 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = GAMEPLAY_PATH/libpng/lib/macosx/libpng.a; sourceTree = "<group>"; };
-		F1F49BCD16AD951A008715A2 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libogg.a"; sourceTree = "<group>"; };
-		F1F49BCE16AD951A008715A2 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbis.a"; sourceTree = "<group>"; };
-		F1F49BCF16AD951A008715A2 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbisenc.a"; sourceTree = "<group>"; };
-		F1F49BD016AD951A008715A2 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/oggvorbis/lib/ios/$(CURRENT_ARCH)/libvorbisfile.a"; sourceTree = "<group>"; };
-		F1F49BD516AD9535008715A2 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/libpng/lib/ios/$(CURRENT_ARCH)/libpng.a"; sourceTree = "<group>"; };
-		F1F49BED16AD9BD4008715A2 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
-		F1F49BF016AD9BFB008715A2 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/lua/lib/ios/$(CURRENT_ARCH)/liblua.a"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -92,14 +95,14 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */,
-				F1F49B8D16AD8F1B008715A2 /* libbullet.a in Frameworks */,
-				F1F49BEE16AD9BD4008715A2 /* liblua.a in Frameworks */,
-				F1F49BC616AD94EE008715A2 /* libogg.a in Frameworks */,
-				F1F49BC716AD94EE008715A2 /* libvorbis.a in Frameworks */,
-				F1F49BC816AD94EE008715A2 /* libvorbisenc.a in Frameworks */,
-				F1F49BC916AD94EE008715A2 /* libvorbisfile.a in Frameworks */,
-				F1F49BCC16AD9502008715A2 /* libpng.a in Frameworks */,
+				421539CA16ADC583001308A3 /* libgameplay.a in Frameworks */,
+				42049B6316ADBC30005DD1F9 /* libbullet.a in Frameworks */,
+				42049B6516ADBC47005DD1F9 /* liblua.a in Frameworks */,
+				42049B6F16ADBC7A005DD1F9 /* libpng.a in Frameworks */,
+				42049B6A16ADBC63005DD1F9 /* libogg.a in Frameworks */,
+				42049B6B16ADBC63005DD1F9 /* libvorbis.a in Frameworks */,
+				42049B6C16ADBC63005DD1F9 /* libvorbisenc.a in Frameworks */,
+				42049B6D16ADBC63005DD1F9 /* libvorbisfile.a in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
 				424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
@@ -113,21 +116,21 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */,
-				F1F49B8F16AD8F3F008715A2 /* libbullet.a in Frameworks */,
-				F1F49BF116AD9BFB008715A2 /* liblua.a in Frameworks */,
-				F1F49BD116AD951A008715A2 /* libogg.a in Frameworks */,
-				F1F49BD216AD951A008715A2 /* libvorbis.a in Frameworks */,
-				F1F49BD316AD951A008715A2 /* libvorbisenc.a in Frameworks */,
-				F1F49BD416AD951A008715A2 /* libvorbisfile.a in Frameworks */,
-				F1F49BD616AD9535008715A2 /* libpng.a in Frameworks */,
-				F1F49B8B16AD8E02008715A2 /* libz.dylib in Frameworks */,
-				5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */,
-				5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */,
-				5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */,
-				5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */,
-				5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */,
-				5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */,
+				421539CD16ADC592001308A3 /* libgameplay.a in Frameworks */,
+				42049B6116ADBC0F005DD1F9 /* libbullet.a in Frameworks */,
+				42049B7316ADBCAB005DD1F9 /* liblua.a in Frameworks */,
+				42049B7116ADBC8B005DD1F9 /* libpng.a in Frameworks */,
+				42049B7816ADBCC3005DD1F9 /* libogg.a in Frameworks */,
+				42049B7916ADBCC3005DD1F9 /* libvorbis.a in Frameworks */,
+				42049B7A16ADBCC3005DD1F9 /* libvorbisenc.a in Frameworks */,
+				42049B7B16ADBCC3005DD1F9 /* libvorbisfile.a in Frameworks */,
+				42049B5F16ADBBF5005DD1F9 /* libz.dylib in Frameworks */,
+				42049B5816ADBB61005DD1F9 /* CoreMotion.framework in Frameworks */,
+				42049B5916ADBB61005DD1F9 /* Foundation.framework in Frameworks */,
+				42049B5A16ADBB61005DD1F9 /* OpenAL.framework in Frameworks */,
+				42049B5B16ADBB61005DD1F9 /* OpenGLES.framework in Frameworks */,
+				42049B5C16ADBB61005DD1F9 /* QuartzCore.framework in Frameworks */,
+				42049B5D16ADBB61005DD1F9 /* UIKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -137,6 +140,7 @@
 		42C932B11491A0DB0098216A = {
 			isa = PBXGroup;
 			children = (
+				42049B7C16ADBCDB005DD1F9 /* [email protected] */,
 				5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */,
 				5B61612E14CCC24D0073B857 /* TEMPLATE_PROJECT-ios.plist */,
 				42C932ED1491A4CB0098216A /* icon.png */,
@@ -179,7 +183,6 @@
 		42C932DD1491A1050098216A /* Libraries */ = {
 			isa = PBXGroup;
 			children = (
-				42438B521491AD2000D218B8 /* libgameplay.a */,
 				5BC4E825150F8CE600CBE1C0 /* GamePlay */,
 				F1F49B8516AD8C22008715A2 /* MacOSX */,
 				F1F49B8716AD8C30008715A2 /* iOS */,
@@ -190,12 +193,12 @@
 		5B61613914CCC3560073B857 /* iOS */ = {
 			isa = PBXGroup;
 			children = (
-				5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */,
-				5BAF2068152F2DDD003E2AC3 /* Foundation.framework */,
-				5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */,
-				5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */,
-				5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */,
-				5BAF206C152F2DDD003E2AC3 /* UIKit.framework */,
+				42049B5216ADBB61005DD1F9 /* CoreMotion.framework */,
+				42049B5316ADBB61005DD1F9 /* Foundation.framework */,
+				42049B5416ADBB61005DD1F9 /* OpenAL.framework */,
+				42049B5516ADBB61005DD1F9 /* OpenGLES.framework */,
+				42049B5616ADBB61005DD1F9 /* QuartzCore.framework */,
+				42049B5716ADBB61005DD1F9 /* UIKit.framework */,
 			);
 			name = iOS;
 			sourceTree = "<group>";
@@ -215,8 +218,8 @@
 		5BC4E825150F8CE600CBE1C0 /* GamePlay */ = {
 			isa = PBXGroup;
 			children = (
-				5BC4E849150F911D00CBE1C0 /* shaders */,
 				5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */,
+				5BC4E849150F911D00CBE1C0 /* shaders */,
 			);
 			name = GamePlay;
 			sourceTree = "<group>";
@@ -224,13 +227,14 @@
 		F1F49B8516AD8C22008715A2 /* MacOSX */ = {
 			isa = PBXGroup;
 			children = (
-				F1F49B8C16AD8F1B008715A2 /* libbullet.a */,
-				F1F49BED16AD9BD4008715A2 /* liblua.a */,
-				F1F49BC216AD94EE008715A2 /* libogg.a */,
-				F1F49BC316AD94EE008715A2 /* libvorbis.a */,
-				F1F49BC416AD94EE008715A2 /* libvorbisenc.a */,
-				F1F49BC516AD94EE008715A2 /* libvorbisfile.a */,
-				F1F49BCB16AD9502008715A2 /* libpng.a */,
+				421539C916ADC583001308A3 /* libgameplay.a */,
+				42049B6216ADBC30005DD1F9 /* libbullet.a */,
+				42049B6416ADBC47005DD1F9 /* liblua.a */,
+				42049B6616ADBC63005DD1F9 /* libogg.a */,
+				42049B6716ADBC63005DD1F9 /* libvorbis.a */,
+				42049B6816ADBC63005DD1F9 /* libvorbisenc.a */,
+				42049B6916ADBC63005DD1F9 /* libvorbisfile.a */,
+				42049B6E16ADBC7A005DD1F9 /* libpng.a */,
 				42C9332D1491A7810098216A /* libz.dylib */,
 			);
 			name = MacOSX;
@@ -239,14 +243,15 @@
 		F1F49B8716AD8C30008715A2 /* iOS */ = {
 			isa = PBXGroup;
 			children = (
-				F1F49B8E16AD8F3F008715A2 /* libbullet.a */,
-				F1F49BF016AD9BFB008715A2 /* liblua.a */,
-				F1F49BCD16AD951A008715A2 /* libogg.a */,
-				F1F49BCE16AD951A008715A2 /* libvorbis.a */,
-				F1F49BCF16AD951A008715A2 /* libvorbisenc.a */,
-				F1F49BD016AD951A008715A2 /* libvorbisfile.a */,
-				F1F49BD516AD9535008715A2 /* libpng.a */,
-				F1F49B8A16AD8E02008715A2 /* libz.dylib */,
+				421539CC16ADC592001308A3 /* libgameplay.a */,
+				42049B6016ADBC0F005DD1F9 /* libbullet.a */,
+				42049B7216ADBCAB005DD1F9 /* liblua.a */,
+				42049B7016ADBC8B005DD1F9 /* libpng.a */,
+				42049B7416ADBCC3005DD1F9 /* libogg.a */,
+				42049B7516ADBCC3005DD1F9 /* libvorbis.a */,
+				42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */,
+				42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */,
+				42049B5E16ADBBF5005DD1F9 /* libz.dylib */,
 			);
 			name = iOS;
 			sourceTree = "<group>";
@@ -296,7 +301,7 @@
 		42C932B31491A0DB0098216A /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0420;
+				LastUpgradeCheck = 0450;
 			};
 			buildConfigurationList = 42C932B61491A0DB0098216A /* Build configuration list for PBXProject "gameplay-template" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -333,6 +338,7 @@
 			files = (
 				5B61612614CCC24C0073B857 /* icon.png in Resources */,
 				5B61612714CCC24C0073B857 /* res in Resources */,
+				42049B7D16ADBCDB005DD1F9 /* [email protected] in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -413,6 +419,7 @@
 				ONLY_ACTIVE_ARCH = YES;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
+				VALID_ARCHS = "armv7 armv7s i386 x86_64";
 			};
 			name = Debug;
 		};
@@ -435,6 +442,7 @@
 				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
+				VALID_ARCHS = "armv7 armv7s i386 x86_64";
 			};
 			name = Release;
 		};
@@ -442,26 +450,29 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-macosx.plist";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
-					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
+				VALID_ARCHS = "i386 x86_64";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Debug;
@@ -470,26 +481,29 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-macosx.plist";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
-					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
+				VALID_ARCHS = "i386 x86_64";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Release;
@@ -504,23 +518,25 @@
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
-					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos\"",
 				);
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
+				VALID_ARCHS = "armv7 armv7s";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Debug;
@@ -535,23 +551,25 @@
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
-					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos\"",
 				);
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
+				VALID_ARCHS = "armv7 armv7s";
 				WRAPPER_EXTENSION = app;
 			};
 			name = Release;

+ 17 - 36
gameplay.doxyfile

@@ -1,4 +1,4 @@
-# Doxyfile 1.8.0
+# Doxyfile 1.7.6.1
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
@@ -250,15 +250,6 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 
 EXTENSION_MAPPING      = 
 
-# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 
-# comments according to the Markdown format, which allows for more readable 
-# documentation. See http://daringfireball.net/projects/markdown/ for details. 
-# The output of markdown processing is further processed by doxygen, so you 
-# can mix doxygen, HTML, and XML commands with Markdown formatting. 
-# Disable only in case of backward compatibilities issues.
-
-MARKDOWN_SUPPORT       = YES
-
 # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
 # to include (a tag file for) the STL sources as input, then you should 
 # set this tag to YES in order to let doxygen match functions declarations and 
@@ -372,11 +363,6 @@ EXTRACT_ALL            = NO
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
-# scope will be included in the documentation.
-
-EXTRACT_PACKAGE        = NO
-
 # If the EXTRACT_STATIC tag is set to YES all static members of a file 
 # will be included in the documentation.
 
@@ -1182,7 +1168,7 @@ FORMULA_TRANSPARENT    = YES
 # (see http://www.mathjax.org) which uses client side Javascript for the 
 # rendering instead of using prerendered bitmaps. Use this if you do not 
 # have LaTeX installed or if you want to formulas look prettier in the HTML 
-# output. When enabled you may also need to install MathJax separately and 
+# output. When enabled you also need to install MathJax separately and 
 # configure the path to it using the MATHJAX_RELPATH option.
 
 USE_MATHJAX            = NO
@@ -1191,10 +1177,10 @@ USE_MATHJAX            = NO
 # HTML output directory using the MATHJAX_RELPATH option. The destination 
 # directory should contain the MathJax.js script. For instance, if the mathjax 
 # directory is located at the same level as the HTML output directory, then 
-# MATHJAX_RELPATH should be ../mathjax. The default value points to 
-# the MathJax Content Delivery Network so you can quickly see the result without 
-# installing MathJax.  However, it is strongly recommended to install a local 
-# copy of MathJax from http://www.mathjax.org before deployment.
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
+# mathjax.org site, so you can quickly see the result without installing 
+# MathJax, but it is strongly recommended to install a local copy of MathJax 
+# before deployment.
 
 MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
 
@@ -1542,16 +1528,20 @@ SKIP_FUNCTION_MACROS   = YES
 # Configuration::additions related to external references
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles. For each 
-# tag file the location of the external documentation should be added. The 
-# format of a tag file without this location is as follows: 
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
 #   TAGFILES = file1 file2 ... 
 # Adding location for the tag files is done as follows: 
 #   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths 
-# or URLs. Note that each tag file must have a unique name (where the name does 
-# NOT include the path). If a tag file is not located in the directory in which 
-# doxygen is run, you must also specify the path to the tagfile here.
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
 
 TAGFILES               = 
 
@@ -1664,15 +1654,6 @@ GROUP_GRAPHS           = YES
 
 UML_LOOK               = NO
 
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside 
-# the class node. If there are many fields or methods and many nodes the 
-# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 
-# threshold limits the number of items for each type to make the size more 
-# managable. Set this to 0 for no limit. Note that the threshold may be 
-# exceeded by 50% before the limit is enforced.
-
-UML_LIMIT_NUM_FIELDS   = 10
-
 # If set to YES, the inheritance and collaboration graphs will show the 
 # relations between templates and their instances.
 

+ 36 - 38
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -836,6 +836,13 @@
 		42CD0EC8147D8FF60000361E /* VertexAttributeBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 42CD0E41147D8FF50000361E /* VertexAttributeBinding.h */; };
 		42CD0EC9147D8FF60000361E /* VertexFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42CD0E42147D8FF50000361E /* VertexFormat.cpp */; };
 		42CD0ECA147D8FF60000361E /* VertexFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 42CD0E43147D8FF50000361E /* VertexFormat.h */; };
+		42DFAB5016AD8ECD0000F342 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB4F16AD8ECD0000F342 /* libz.dylib */; };
+		42DFAB5A16AD8F310000F342 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5316AD8F310000F342 /* CoreMotion.framework */; };
+		42DFAB5B16AD8F310000F342 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5416AD8F310000F342 /* Foundation.framework */; };
+		42DFAB5C16AD8F310000F342 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5516AD8F310000F342 /* OpenAL.framework */; };
+		42DFAB5D16AD8F310000F342 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5616AD8F310000F342 /* OpenGLES.framework */; };
+		42DFAB5E16AD8F310000F342 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5716AD8F310000F342 /* QuartzCore.framework */; };
+		42DFAB5F16AD8F310000F342 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DFAB5816AD8F310000F342 /* UIKit.framework */; };
 		42F4B7D715994CED00B5A78D /* Gamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42F4B7D515994CED00B5A78D /* Gamepad.cpp */; };
 		42F4B7D815994CED00B5A78D /* Gamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42F4B7D515994CED00B5A78D /* Gamepad.cpp */; };
 		42F4B7D915994CED00B5A78D /* Gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 42F4B7D615994CED00B5A78D /* Gamepad.h */; };
@@ -975,13 +982,6 @@
 		5B2BC7601512514500D176CD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC75E1512514500D176CD /* OpenGL.framework */; };
 		5B2BC7621512514D00D176CD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7611512514D00D176CD /* QuartzCore.framework */; };
 		5B2BC7641512516B00D176CD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7631512516B00D176CD /* libz.dylib */; };
-		5BAF2027152F2AF0003E2AC3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2020152F2AF0003E2AC3 /* CoreGraphics.framework */; };
-		5BAF2028152F2AF0003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2021152F2AF0003E2AC3 /* CoreMotion.framework */; };
-		5BAF2029152F2AF0003E2AC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2022152F2AF0003E2AC3 /* Foundation.framework */; };
-		5BAF202A152F2AF0003E2AC3 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2023152F2AF0003E2AC3 /* OpenAL.framework */; };
-		5BAF202B152F2AF0003E2AC3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2024152F2AF0003E2AC3 /* OpenGLES.framework */; };
-		5BAF202C152F2AF0003E2AC3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2025152F2AF0003E2AC3 /* QuartzCore.framework */; };
-		5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2026152F2AF0003E2AC3 /* UIKit.framework */; };
 		5BB0823D14C6FEC40019975F /* Mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BB0823C14C6FEC40019975F /* Mouse.h */; };
 		5BB0823E14C6FEC40019975F /* Mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BB0823C14C6FEC40019975F /* Mouse.h */; };
 		5BBAD0F315F5251E004C9639 /* lua_Gesture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */; };
@@ -1620,6 +1620,13 @@
 		42CD0E41147D8FF50000361E /* VertexAttributeBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexAttributeBinding.h; path = src/VertexAttributeBinding.h; sourceTree = SOURCE_ROOT; };
 		42CD0E42147D8FF50000361E /* VertexFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexFormat.cpp; path = src/VertexFormat.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0E43147D8FF50000361E /* VertexFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexFormat.h; path = src/VertexFormat.h; sourceTree = SOURCE_ROOT; };
+		42DFAB4F16AD8ECD0000F342 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		42DFAB5316AD8F310000F342 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
+		42DFAB5416AD8F310000F342 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		42DFAB5516AD8F310000F342 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		42DFAB5616AD8F310000F342 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+		42DFAB5716AD8F310000F342 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+		42DFAB5816AD8F310000F342 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		42F4B7D515994CED00B5A78D /* Gamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gamepad.cpp; path = src/Gamepad.cpp; sourceTree = SOURCE_ROOT; };
 		42F4B7D615994CED00B5A78D /* Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Gamepad.h; path = src/Gamepad.h; sourceTree = SOURCE_ROOT; };
 		5B04C5CA14BFCFE100EB0071 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1635,14 +1642,6 @@
 		5B5DB93214C25BA5007755DB /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbis.a"; sourceTree = "<group>"; };
 		5B5DB93314C25BA5007755DB /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbisenc.a"; sourceTree = "<group>"; };
 		5B5DB93414C25BA5007755DB /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbisfile.a"; sourceTree = "<group>"; };
-		5BAF201E152F2A6D003E2AC3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
-		5BAF2020152F2AF0003E2AC3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2021152F2AF0003E2AC3 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2022152F2AF0003E2AC3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2023152F2AF0003E2AC3 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2024152F2AF0003E2AC3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2025152F2AF0003E2AC3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2026152F2AF0003E2AC3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		5BB0823C14C6FEC40019975F /* Mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mouse.h; path = src/Mouse.h; sourceTree = SOURCE_ROOT; };
 		5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_Gesture.cpp; sourceTree = "<group>"; };
 		5BBAD0F015F5251D004C9639 /* lua_Gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_Gesture.h; sourceTree = "<group>"; };
@@ -1728,13 +1727,13 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				5BAF2027152F2AF0003E2AC3 /* CoreGraphics.framework in Frameworks */,
-				5BAF2028152F2AF0003E2AC3 /* CoreMotion.framework in Frameworks */,
-				5BAF2029152F2AF0003E2AC3 /* Foundation.framework in Frameworks */,
-				5BAF202A152F2AF0003E2AC3 /* OpenAL.framework in Frameworks */,
-				5BAF202B152F2AF0003E2AC3 /* OpenGLES.framework in Frameworks */,
-				5BAF202C152F2AF0003E2AC3 /* QuartzCore.framework in Frameworks */,
-				5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */,
+				42DFAB5016AD8ECD0000F342 /* libz.dylib in Frameworks */,
+				42DFAB5A16AD8F310000F342 /* CoreMotion.framework in Frameworks */,
+				42DFAB5B16AD8F310000F342 /* Foundation.framework in Frameworks */,
+				42DFAB5C16AD8F310000F342 /* OpenAL.framework in Frameworks */,
+				42DFAB5D16AD8F310000F342 /* OpenGLES.framework in Frameworks */,
+				42DFAB5E16AD8F310000F342 /* QuartzCore.framework in Frameworks */,
+				42DFAB5F16AD8F310000F342 /* UIKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2366,13 +2365,12 @@
 		5B04C5FD14BFE52300EB0071 /* iOS */ = {
 			isa = PBXGroup;
 			children = (
-				5BAF2020152F2AF0003E2AC3 /* CoreGraphics.framework */,
-				5BAF2021152F2AF0003E2AC3 /* CoreMotion.framework */,
-				5BAF2022152F2AF0003E2AC3 /* Foundation.framework */,
-				5BAF2023152F2AF0003E2AC3 /* OpenAL.framework */,
-				5BAF2024152F2AF0003E2AC3 /* OpenGLES.framework */,
-				5BAF2025152F2AF0003E2AC3 /* QuartzCore.framework */,
-				5BAF2026152F2AF0003E2AC3 /* UIKit.framework */,
+				42DFAB5316AD8F310000F342 /* CoreMotion.framework */,
+				42DFAB5416AD8F310000F342 /* Foundation.framework */,
+				42DFAB5516AD8F310000F342 /* OpenAL.framework */,
+				42DFAB5616AD8F310000F342 /* OpenGLES.framework */,
+				42DFAB5716AD8F310000F342 /* QuartzCore.framework */,
+				42DFAB5816AD8F310000F342 /* UIKit.framework */,
 			);
 			name = iOS;
 			sourceTree = "<group>";
@@ -2399,7 +2397,7 @@
 				5B5DB93314C25BA5007755DB /* libvorbisenc.a */,
 				5B5DB93414C25BA5007755DB /* libvorbisfile.a */,
 				5B5DB92F14C25B94007755DB /* libpng.a */,
-				5BAF201E152F2A6D003E2AC3 /* libz.dylib */,
+				42DFAB4F16AD8ECD0000F342 /* libz.dylib */,
 			);
 			name = iOS;
 			sourceTree = "<group>";
@@ -3610,7 +3608,7 @@
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = macosx;
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
-				VALID_ARCHS = "armv7 armv6 i386 x86_64";
+				VALID_ARCHS = "armv7 armv7s i386 x86_64";
 			};
 			name = Debug;
 		};
@@ -3619,7 +3617,7 @@
 			buildSettings = {
 				SDKROOT = macosx;
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
-				VALID_ARCHS = "armv7 armv6 i386 x86_64";
+				VALID_ARCHS = "armv7 armv7s i386 x86_64";
 			};
 			name = Release;
 		};
@@ -3650,9 +3648,9 @@
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
+					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/libpng/include",
-					"../external-deps/bullet/include",
 					"../external-deps/oggvorbis/include",
 					./gameplay,
 				);
@@ -3689,9 +3687,9 @@
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
+					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/libpng/include",
-					"../external-deps/bullet/include",
 					"../external-deps/oggvorbis/include",
 					./gameplay,
 				);
@@ -3730,9 +3728,9 @@
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
+					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/libpng/include",
-					"../external-deps/bullet/include",
 					"../external-deps/oggvorbis/include",
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
@@ -3746,7 +3744,7 @@
 				SHARED_PRECOMPS_DIR = "";
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
 				USER_HEADER_SEARCH_PATHS = "";
-				VALID_ARCHS = "armv7 armv6";
+				VALID_ARCHS = "armv7 armv7s ";
 			};
 			name = Debug;
 		};
@@ -3772,9 +3770,9 @@
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
+					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/libpng/include",
-					"../external-deps/bullet/include",
 					"../external-deps/oggvorbis/include",
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
@@ -3787,7 +3785,7 @@
 				SHARED_PRECOMPS_DIR = "";
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
 				USER_HEADER_SEARCH_PATHS = "";
-				VALID_ARCHS = "armv7 armv6";
+				VALID_ARCHS = "armv7 armv7s ";
 			};
 			name = Release;
 		};

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

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0450"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

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

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0450"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 6 - 0
gameplay/src/Animation.cpp

@@ -453,6 +453,12 @@ Animation* Animation::clone(Channel* channel, AnimationTarget* target)
     GP_ASSERT(animation->getRefCount() == 1);
 
     // Clone the clips
+    
+    if (_defaultClip)
+    {
+        animation->_defaultClip = _defaultClip->clone(animation);
+    }
+    
     if (_clips)
     {
         for (std::vector<AnimationClip*>::iterator it = _clips->begin(); it != _clips->end(); ++it)

+ 0 - 1
gameplay/src/AnimationClip.cpp

@@ -598,7 +598,6 @@ AnimationClip* AnimationClip::clone(Animation* animation) const
 {
     // Don't clone the elapsed time, listeners or crossfade information.
     AnimationClip* newClip = new AnimationClip(getId(), animation, getStartTime(), getEndTime());
-    newClip->setRepeatCount(getRepeatCount());
     newClip->setSpeed(getSpeed());
     newClip->setRepeatCount(getRepeatCount());
     newClip->setBlendWeight(getBlendWeight());

+ 18 - 1
gameplay/src/AnimationTarget.cpp

@@ -4,6 +4,8 @@
 #include "Game.h"
 #include "Node.h"
 
+#define ANIMATION_TARGET_INDEFINITE_STR "INDEFINITE"
+
 namespace gameplay
 {
 
@@ -261,6 +263,21 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
     }
 
+    const char* repeat = animationProperties->getString("repeatCount");
+    if (repeat)
+    {
+        if (strcmp(repeat, ANIMATION_TARGET_INDEFINITE_STR) == 0)
+        {
+            animation->getClip()->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
+        }
+        else
+        {
+            float value;
+            sscanf(repeat, "%f", &value);
+            animation->getClip()->setRepeatCount(value);
+        }
+    }
+    
     SAFE_DELETE_ARRAY(keyOut);
     SAFE_DELETE_ARRAY(keyIn);
     SAFE_DELETE_ARRAY(keyValues);
@@ -277,7 +294,7 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         }
         animation->createClips(animationProperties, (unsigned int) frameCount);
     }
-
+    
     return animation;
 }
 

+ 3 - 2
gameplay/src/Base.h

@@ -27,6 +27,7 @@
 #include <limits>
 #include <functional>
 #include <bitset>
+#include <typeinfo>
 #include "Logger.h"
 
 // Bring common functions from C into global namespace
@@ -279,9 +280,9 @@ typedef GLuint FrameBufferHandle;
 typedef GLuint RenderBufferHandle;
 
 /** Gamepad handle definitions vary by platform. */
-#if defined(__QNX__) && defined (USE_BLACKBERRY_GAMEPAD)
+#if defined(__QNX__) && defined(USE_BLACKBERRY_GAMEPAD)
     typedef screen_device_t GamepadHandle;
-#elif USE_XINPUT
+#elif defined(USE_XINPUT)
     typedef unsigned long GamepadHandle;
 #else
     typedef unsigned int GamepadHandle;

+ 1 - 1
gameplay/src/Button.h

@@ -77,7 +77,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 1 - 1
gameplay/src/CheckBox.h

@@ -123,7 +123,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 2 - 2
gameplay/src/Container.h

@@ -259,7 +259,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by a control within this container.
      *
@@ -340,7 +340,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by scrolling within this container.
      *

+ 1 - 1
gameplay/src/Control.h

@@ -805,7 +805,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by this control.
      *

+ 46 - 7
gameplay/src/DepthStencilTarget.cpp

@@ -1,21 +1,30 @@
 #include "Base.h"
 #include "DepthStencilTarget.h"
 
+#ifndef GL_DEPTH24_STENCIL8_OES
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif
+#ifndef GL_DEPTH_COMPONENT24
+#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
+#endif
+
 namespace gameplay
 {
 
 static std::vector<DepthStencilTarget*> __depthStencilTargets;
 
 DepthStencilTarget::DepthStencilTarget(const char* id, Format format, unsigned int width, unsigned int height)
-    : _id(id ? id : ""), _format(format), _renderBuffer(0), _width(width), _height(height)
+    : _id(id ? id : ""), _format(format), _depthBuffer(0), _stencilBuffer(0), _width(width), _height(height)
 {
 }
 
 DepthStencilTarget::~DepthStencilTarget()
 {
     // Destroy GL resources.
-    if (_renderBuffer)
-        GL_ASSERT( glDeleteTextures(1, &_renderBuffer) );
+    if (_depthBuffer)
+        GL_ASSERT( glDeleteRenderbuffers(1, &_depthBuffer) );
+    if (_stencilBuffer)
+        GL_ASSERT( glDeleteRenderbuffers(1, &_stencilBuffer) );
 
     // Remove from vector.
     std::vector<DepthStencilTarget*>::iterator it = std::find(__depthStencilTargets.begin(), __depthStencilTargets.end(), this);
@@ -30,11 +39,41 @@ DepthStencilTarget* DepthStencilTarget::create(const char* id, Format format, un
     // Create the depth stencil target.
     DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, format, width, height);
 
-    // Create a render buffer for this new depth stencil target
-    GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_renderBuffer) );
-    GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_renderBuffer) );
-    GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height) );
+    // Create a render buffer for this new depth+stencil target
+    GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_depthBuffer) );
+    GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_depthBuffer) );
+
+    // First try to add storage for the most common standard GL_DEPTH24_STENCIL8 
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
 
+    // Fall back to less common GLES2 extension combination for seperate depth24 + stencil8 or depth16 + stencil8
+    __gl_error_code = glGetError();
+    if ( __gl_error_code != GL_NO_ERROR)
+    {
+        const char* extString = (const char*)glGetString(GL_EXTENSIONS);
+
+        if (strstr(extString, "GL_OES_packed_depth_stencil") != 0)
+        {
+            GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height) );
+        }
+        else
+        {
+            if (strstr(extString, "GL_OES_depth24") != 0)
+            {
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height) );
+            }
+            else
+            {
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height) );
+            }
+            if (format == DepthStencilTarget::DEPTH_STENCIL)
+            {
+                GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_stencilBuffer) );
+                GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_stencilBuffer) );
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height) );
+            }
+        }
+    }
     // Add it to the cache.
     __depthStencilTargets.push_back(depthStencilTarget);
 

+ 2 - 1
gameplay/src/DepthStencilTarget.h

@@ -101,7 +101,8 @@ private:
 
     std::string _id;
     Format _format;
-    RenderBufferHandle _renderBuffer;
+    RenderBufferHandle _depthBuffer;
+    RenderBufferHandle _stencilBuffer;
     unsigned int _width;
     unsigned int _height;
 };

+ 2 - 2
gameplay/src/FrameBuffer.cpp

@@ -218,10 +218,10 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
 
         // Attach the render buffer to the framebuffer
-        GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_renderBuffer) );
+        GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_depthBuffer) );
         if (target->getFormat() == DepthStencilTarget::DEPTH_STENCIL)
         {
-            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_renderBuffer) );
+            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_stencilBuffer) );
         }
 
         // Check the framebuffer is good to go.

+ 1 - 0
gameplay/src/Game.cpp

@@ -577,6 +577,7 @@ void Game::loadGamepads()
     {
         // Check if there are any virtual gamepads included in the .config file.
         // If there are, create and initialize them.
+        _properties->rewind();
         Properties* inner = _properties->getNextNamespace();
         while (inner != NULL)
         {

+ 20 - 1
gameplay/src/Game.h

@@ -295,7 +295,7 @@ public:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @see Touch::TouchEvent
      */
@@ -453,12 +453,31 @@ public:
      * The gamepad index can change when connected and disconnected so you
      * cannot rely on this other than iterating through them all to display
      * them or poll them.
+     * 
+     * The preferPhysical will bump over virtual gamepads if physical gamepads are
+     * connected and return the request index of the first or second physcial and then 
+     * return back to the first virtual after.
      *
      * @param index The index of the gamepad to retrieve.
+     * @param preferPhysical true if you prefer return a physical if exist; false if only virtual.
      * @return The gamepad at the specified index.
      */
     inline Gamepad* getGamepad(unsigned int index, bool preferPhysical = true) const;
 
+    /**
+	 * Sets whether multi-sampling is to be enabled/disabled. Default is disabled.
+	 *
+	 * @param enabled true sets multi-sampling to be enabled, false to be disabled.
+	 */
+	inline void setMultiSampling(bool enabled);
+
+	/*
+	 * Is multi-sampling enabled.
+	 *
+	 * @return true if multi-sampling is enabled.
+	 */
+	inline bool isMultiSampling() const;
+
     /**
      * Sets multi-touch is to be enabled/disabled. Default is disabled.
      *

+ 10 - 0
gameplay/src/Game.inl

@@ -96,6 +96,16 @@ inline bool Game::isCursorVisible()
     return Platform::isCursorVisible();
 }
 
+inline void Game::setMultiSampling(bool enabled)
+{
+    Platform::setMultiSampling(enabled);
+}
+
+inline bool Game::isMultiSampling() const
+{
+    return Platform::isMultiSampling();
+}
+
 inline void Game::setMultiTouch(bool enabled)
 {
     Platform::setMultiTouch(enabled);

+ 89 - 3
gameplay/src/Joint.cpp

@@ -6,7 +6,7 @@ namespace gameplay
 {
 
 Joint::Joint(const char* id)
-    : Node(id), _jointMatrixDirty(true), _skinCount(0)
+    : Node(id), _jointMatrixDirty(true)
 {
 }
 
@@ -25,7 +25,6 @@ Node* Joint::cloneSingleNode(NodeCloneContext &context) const
     GP_ASSERT(copy);
     context.registerClonedNode(this, copy);
     copy->_bindPose = _bindPose;
-    copy->_skinCount = _skinCount;
     Node::cloneInto(copy, context);
     return copy;
 }
@@ -35,6 +34,27 @@ Node::Type Joint::getType() const
     return Node::JOINT;
 }
 
+Scene* Joint::getScene() const
+{
+    // Overrides Node::getScene() to search the node our skins.
+    for (const SkinReference* itr = &_skin; itr && itr->skin; itr = itr->next)
+    {
+        Model* model = itr->skin ? itr->skin->getModel() : NULL;
+        if (model)
+        {
+            Node* node = model->getNode();
+            if (node)
+            {
+                Scene* scene = node->getScene();
+                if (scene)
+                    return scene;
+            }
+        }
+    }
+
+    return Node::getScene();
+}
+
 void Joint::transformChanged()
 {
     Node::transformChanged();
@@ -47,7 +67,7 @@ void Joint::updateJointMatrix(const Matrix& bindShape, Vector4* matrixPalette)
     // the _jointMatrixDirty optimization since updateJointMatrix() may be
     // called multiple times a frame with different bindShape matrices (and
     // different matrixPallete pointers).
-    if (_skinCount > 1 || _jointMatrixDirty)
+    if (_skin.next || _jointMatrixDirty)
     {
         _jointMatrixDirty = false;
 
@@ -73,4 +93,70 @@ void Joint::setInverseBindPose(const Matrix& m)
     _jointMatrixDirty = true;
 }
 
+void Joint::addSkin(MeshSkin* skin)
+{
+    if (!_skin.skin)
+    {
+        // Store skin in root reference
+        _skin.skin = skin;
+    }
+    else
+    {
+        // Add a new SkinReference to the end of our list
+        SkinReference* ref = &_skin;
+        while (ref->next)
+        {
+            ref = ref->next;
+        }
+        ref->next = new SkinReference();
+        ref->next->skin = skin;
+    }
+}
+
+void Joint::removeSkin(MeshSkin* skin)
+{
+    if (_skin.skin == skin)
+    {
+        // Skin is our root referenced skin
+        _skin.skin = NULL;
+
+        // Shift the next skin reference down to the root
+        if (_skin.next)
+        {
+            SkinReference* tmp = _skin.next;
+            _skin.skin = tmp->skin;
+            _skin.next = tmp->next;
+            tmp->next = NULL; // prevent deletion
+            SAFE_DELETE(tmp);
+        }
+    }
+    else
+    {
+        // Search for the entry referencing this skin
+        SkinReference* ref = &_skin;
+        while (SkinReference* tmp = ref->next)
+        {
+            if (tmp->skin == skin)
+            {
+                // Link this refernce out
+                ref->next = tmp->next;
+                tmp->next = NULL; // prevent deletion
+                SAFE_DELETE(tmp);
+                break;
+            }
+            ref = tmp;
+        }
+    }
+}
+
+Joint::SkinReference::SkinReference()
+    : skin(NULL), next(NULL)
+{
+}
+
+Joint::SkinReference::~SkinReference()
+{
+    SAFE_DELETE(next);
+}
+
 }

+ 26 - 7
gameplay/src/Joint.h

@@ -25,6 +25,11 @@ public:
      */
     Node::Type getType() const;
 
+    /**
+     * @see Node::getScene()
+     */
+    Scene* getScene() const;
+
     /**
      * Returns the inverse bind pose matrix for this joint.
      * 
@@ -85,6 +90,18 @@ protected:
 
 private:
 
+    /**
+     * Internal structure to track mesh skins referencing a joint.
+     */
+    struct SkinReference
+    {
+        MeshSkin* skin;
+        SkinReference* next;
+
+        SkinReference();
+        ~SkinReference();
+    };
+
     /**
      * Constructor.
      */
@@ -95,22 +112,24 @@ private:
      */
     Joint& operator=(const Joint&);
 
-protected:
+    void addSkin(MeshSkin* skin);
+
+    void removeSkin(MeshSkin* skin);
 
     /** 
      * The Matrix representation of the Joint's bind pose.
      */
     Matrix _bindPose;
-    
-    /** 
+
+    /**
      * Flag used to mark if the Joint's matrix is dirty.
      */
     bool _jointMatrixDirty;
-    
-    /** 
-     * The number of MeshSkin's influencing the Joint.
+
+    /**
+     * Linked list of mesh skins that are referenced by this joint.
      */
-    unsigned int _skinCount;
+    SkinReference _skin;
 };
 
 }

+ 1 - 1
gameplay/src/Joystick.h

@@ -153,7 +153,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 1 - 1
gameplay/src/Layout.h

@@ -80,7 +80,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @see Touch::TouchEvent
      */

+ 3 - 0
gameplay/src/MaterialParameter.cpp

@@ -663,6 +663,9 @@ void MaterialParameter::cloneInto(MaterialParameter* materialParameter) const
         GP_ERROR("Unsupported material parameter type(%d).", _type);
         break;
     }
+    
+    NodeCloneContext context;
+    this->AnimationTarget::cloneInto(materialParameter, context);
 }
 
 }

+ 66 - 0
gameplay/src/MeshBatch.cpp

@@ -1,5 +1,6 @@
 #include "Base.h"
 #include "MeshBatch.h"
+#include "Material.h"
 
 namespace gameplay
 {
@@ -42,6 +43,66 @@ MeshBatch* MeshBatch::create(const VertexFormat& vertexFormat, Mesh::PrimitiveTy
     return batch;
 }
 
+void MeshBatch::add(void* vertices, size_t size, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount)
+{
+    GP_ASSERT(vertices);
+    
+    unsigned int newVertexCount = _vertexCount + vertexCount;
+    unsigned int newIndexCount = _indexCount + indexCount;
+    if (_primitiveType == Mesh::TRIANGLE_STRIP && _vertexCount > 0)
+        newIndexCount += 2; // need an extra 2 indices for connecting strips with degenerate triangles
+    
+    // Do we need to grow the batch?
+    while (newVertexCount > _vertexCapacity || (_indexed && newIndexCount > _indexCapacity))
+    {
+        if (_growSize == 0)
+            return; // growing disabled, just clip batch
+        if (!resize(_capacity + _growSize))
+            return; // failed to grow
+    }
+    
+    // Copy vertex data.
+    GP_ASSERT(_verticesPtr);
+    unsigned int vBytes = vertexCount * _vertexFormat.getVertexSize();
+    memcpy(_verticesPtr, vertices, vBytes);
+    
+    // Copy index data.
+    if (_indexed)
+    {
+        GP_ASSERT(indices);
+        GP_ASSERT(_indicesPtr);
+
+        if (_vertexCount == 0)
+        {
+            // Simply copy values directly into the start of the index array.
+            memcpy(_indicesPtr, indices, indexCount * sizeof(unsigned short));
+        }
+        else
+        {
+            if (_primitiveType == Mesh::TRIANGLE_STRIP)
+            {
+                // Create a degenerate triangle to connect separate triangle strips
+                // by duplicating the previous and next vertices.
+                _indicesPtr[0] = *(_indicesPtr-1);
+                _indicesPtr[1] = _vertexCount;
+                _indicesPtr += 2;
+            }
+            
+            // Loop through all indices and insert them, with their values offset by
+            // 'vertexCount' so that they are relative to the first newly inserted vertex.
+            for (unsigned int i = 0; i < indexCount; ++i)
+            {
+                _indicesPtr[i] = indices[i] + _vertexCount;
+            }
+        }
+        _indicesPtr += indexCount;
+        _indexCount = newIndexCount;
+    }
+    
+    _verticesPtr += vBytes;
+    _vertexCount = newVertexCount;
+}
+
 void MeshBatch::updateVertexAttributeBinding()
 {
     GP_ASSERT(_material);
@@ -155,6 +216,11 @@ bool MeshBatch::resize(unsigned int capacity)
 
     return true;
 }
+
+void MeshBatch::add(float* vertices, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount)
+{
+    add(vertices, sizeof(float), vertexCount, indices, indexCount);
+}
     
 void MeshBatch::start()
 {

+ 25 - 1
gameplay/src/MeshBatch.h

@@ -2,11 +2,12 @@
 #define MESHBATCH_H_
 
 #include "Mesh.h"
-#include "Material.h"
 
 namespace gameplay
 {
 
+class Material;
+
 /**
  * Defines a class for rendering multiple mesh into a single draw call on the graphics device.
  */
@@ -92,6 +93,27 @@ public:
     template <class T>
     void add(T* vertices, unsigned int vertexCount, unsigned short* indices = NULL, unsigned int indexCount = 0);
 
+    /**
+     * Adds a group of primitives to the batch.
+     *
+     * The vertex list passed in should be a pointer of floats where every X floats represent a
+     * single vertex (e.g. {x,y,z,u,v}).
+     *
+     * If the batch was created with 'indexed' set to true, then valid index data should be
+     * passed in this method. However, if 'indexed' was set to false, the indices and indexCount
+     * parameters can be omitted since only vertex data will be used.
+     *
+     * If the batch created to draw triangle strips, this method assumes that separate calls to
+     * add specify separate triangle strips. In this case, this method will automatically stitch
+     * separate triangle strips together using degenerate (zero-area) triangles.
+     *
+     * @param vertices Array of vertices.
+     * @param vertexCount Number of vertices.
+     * @param indices Array of indices into the vertex array (should be NULL for non-indexed batches).
+     * @param indexCount Number of indices (should be zero for non-indexed batches).
+     */
+    void add(float* vertices, unsigned int vertexCount, unsigned short* indices = NULL, unsigned int indexCount = 0);
+
     /**
      * Starts batching.
      *
@@ -131,6 +153,8 @@ private:
      */
     MeshBatch& operator=(const MeshBatch&);
 
+    void add(void* vertices, size_t size, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount);
+
     void updateVertexAttributeBinding();
 
     bool resize(unsigned int capacity);

+ 1 - 56
gameplay/src/MeshBatch.inl

@@ -11,63 +11,8 @@ Material* MeshBatch::getMaterial() const
 template <class T>
 void MeshBatch::add(T* vertices, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount)
 {
-    GP_ASSERT(vertices);
     GP_ASSERT(sizeof(T) == _vertexFormat.getVertexSize());
-    
-    unsigned int newVertexCount = _vertexCount + vertexCount;
-    unsigned int newIndexCount = _indexCount + indexCount;
-    if (_primitiveType == Mesh::TRIANGLE_STRIP && _vertexCount > 0)
-        newIndexCount += 2; // need an extra 2 indices for connecting strips with degenerate triangles
-    
-    // Do we need to grow the batch?
-    while (newVertexCount > _vertexCapacity || (_indexed && newIndexCount > _indexCapacity))
-    {
-        if (_growSize == 0)
-            return; // growing disabled, just clip batch
-        if (!resize(_capacity + _growSize))
-            return; // failed to grow
-    }
-    
-    // Copy vertex data.
-    GP_ASSERT(_verticesPtr);
-    unsigned int vBytes = vertexCount * _vertexFormat.getVertexSize();
-    memcpy(_verticesPtr, vertices, vBytes);
-    
-    // Copy index data.
-    if (_indexed)
-    {
-        GP_ASSERT(indices);
-        GP_ASSERT(_indicesPtr);
-
-        if (_vertexCount == 0)
-        {
-            // Simply copy values directly into the start of the index array.
-            memcpy(_indicesPtr, indices, indexCount * sizeof(unsigned short));
-        }
-        else
-        {
-            if (_primitiveType == Mesh::TRIANGLE_STRIP)
-            {
-                // Create a degenerate triangle to connect separate triangle strips
-                // by duplicating the previous and next vertices.
-                _indicesPtr[0] = *(_indicesPtr-1);
-                _indicesPtr[1] = _vertexCount;
-                _indicesPtr += 2;
-            }
-            
-            // Loop through all indices and insert them, with their values offset by
-            // 'vertexCount' so that they are relative to the first newly inserted vertex.
-            for (unsigned int i = 0; i < indexCount; ++i)
-            {
-                _indicesPtr[i] = indices[i] + _vertexCount;
-            }
-        }
-        _indicesPtr += indexCount;
-        _indexCount = newIndexCount;
-    }
-    
-    _verticesPtr += vBytes;
-    _vertexCount = newVertexCount;
+    add(vertices, sizeof(T), vertexCount, indices, indexCount);
 }
 
 }

+ 2 - 2
gameplay/src/MeshSkin.cpp

@@ -141,7 +141,7 @@ void MeshSkin::setJoint(Joint* joint, unsigned int index)
 
     if (_joints[index])
     {
-        _joints[index]->_skinCount--;
+        _joints[index]->removeSkin(this);
         SAFE_RELEASE(_joints[index]);
     }
 
@@ -150,7 +150,7 @@ void MeshSkin::setJoint(Joint* joint, unsigned int index)
     if (joint)
     {
         joint->addRef();
-        joint->_skinCount++;
+        joint->addSkin(this);
     }
 }
 

+ 1 - 0
gameplay/src/MeshSkin.h

@@ -21,6 +21,7 @@ class MeshSkin : public Transform::Listener
     friend class Model;
     friend class Joint;
     friend class Node;
+    friend class Scene;
 
 public:
 

+ 1 - 0
gameplay/src/Model.h

@@ -20,6 +20,7 @@ class NodeCloneContext;
 class Model : public Ref
 {
     friend class Node;
+    friend class Scene;
     friend class Mesh;
     friend class Bundle;
 

+ 8 - 7
gameplay/src/Node.cpp

@@ -376,13 +376,15 @@ unsigned int Node::findNodes(const char* id, std::vector<Node*>& nodes, bool rec
 
 Scene* Node::getScene() const
 {
-    // Search for a scene in our parents.
-    for (Node* n = const_cast<Node*>(this); n != NULL; n = n->getParent())
+    if (_scene)
+        return _scene;
+
+    // Search our parent for the scene
+    if (_parent)
     {
-        if (n->_scene)
-        {
-            return n->_scene;
-        }
+        Scene* scene = _parent->getScene();
+        if (scene)
+            return scene;
     }
 
     return NULL;
@@ -933,7 +935,6 @@ const BoundingSphere& Node::getBoundingSphere() const
     return _bounds;
 }
 
-
 Node* Node::clone() const
 {
     NodeCloneContext context;

+ 1 - 1
gameplay/src/Node.h

@@ -223,7 +223,7 @@ public:
      *
      * @return The scene.
      */
-    Scene* getScene() const;
+    virtual Scene* getScene() const;
 
     /**
      * Gets the top level node in this node's parent hierarchy.

+ 19 - 0
gameplay/src/Platform.h

@@ -127,6 +127,18 @@ private:
      */
     static void sleep(long ms);
 
+    /**
+     * Set if multi-sampling is enabled on the platform.
+     *
+     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
+     */
+    static void setMultiSampling(bool enabled);
+
+   /**
+    * Is multi-sampling mode enabled.
+    */
+    static bool isMultiSampling();
+
     /**
      * Set if multi-touch is enabled on the platform.
      *
@@ -297,6 +309,13 @@ public:
      */
     static void pollGamepadState(Gamepad* gamepad);
 
+   /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void shutdownInternal();
+
 private:
 
     Game* _game;                // The game this platform is interfacing with.

+ 52 - 12
gameplay/src/PlatformAndroid.cpp

@@ -32,6 +32,7 @@ static ASensorEventQueue* __sensorEventQueue;
 static ASensorEvent __sensorEvent;
 static const ASensor* __accelerometerSensor;
 static int __orientationAngle = 90;
+static bool __multiSampling = false;
 static bool __multiTouch = false;
 static int __primaryTouchId = -1;
 static bool __displayKeyboard = false;
@@ -176,6 +177,7 @@ static bool initEGL()
         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
         EGL_NONE
     };
+    __multiSampling = samples > 0;
     
     EGLint eglConfigCount;
     const EGLint eglContextAttrs[] =
@@ -237,6 +239,9 @@ static bool initEGL()
                         break;
                     }
                 }
+
+                __multiSampling = sampleCount > 0;
+
                 if (validConfig)
                     break;
             }
@@ -974,22 +979,35 @@ int Platform::enterMessagePump()
     }
     GP_ASSERT(env);
 
-    // Get the package name for this app from Java.
-    jclass clazz = env->GetObjectClass(activity->clazz);
-    jmethodID methodID = env->GetMethodID(clazz, "getPackageName", "()Ljava/lang/String;");
-    jobject result = env->CallObjectMethod(activity->clazz, methodID);
-    
-    const char* packageName;
+    /* Get external files directory on Android; this will result in a directory where all app files
+     * should be stored, like /mnt/sdcard/android/<package-name>/files/
+     */
     jboolean isCopy;
-    packageName = env->GetStringUTFChars((jstring)result, &isCopy);
-    jvm->DetachCurrentThread();
+
+    jclass clazz = env->GetObjectClass(activity->clazz);
+    jmethodID methodGetExternalStorage = env->GetMethodID(clazz, "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
+
+    jclass clazzFile = env->FindClass("java/io/File");
+    jmethodID methodGetPath = env->GetMethodID(clazzFile, "getPath", "()Ljava/lang/String;");
+
+    // Now has java.io.File object pointing to directory
+    jobject objectFile  = env->CallObjectMethod(activity->clazz, methodGetExternalStorage, NULL);
     
+    // Now has String object containing path to directory
+    jstring stringExternalPath = static_cast<jstring>(env->CallObjectMethod(objectFile, methodGetPath));
+    const char* externalPath = env->GetStringUTFChars(stringExternalPath, &isCopy);
+
     // Set the default path to store the resources.
-    std::string assetsPath = "/mnt/sdcard/android/data/";
-    assetsPath += packageName;
-    assetsPath += "/";
+    std::string assetsPath(externalPath);
+    if (externalPath[strlen(externalPath)-1] != '/')
+        assetsPath += "/";
+
     FileSystem::setResourcePath(assetsPath.c_str());    
-        
+
+    // Release string data
+    env->ReleaseStringUTFChars(stringExternalPath, externalPath);
+    jvm->DetachCurrentThread();
+    
     // Get the asset manager to get the resources from the .apk file.
     __assetManager = activity->assetManager; 
     
@@ -1132,6 +1150,23 @@ void Platform::sleep(long ms)
     usleep(ms * 1000);
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    //todo
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
 void Platform::setMultiTouch(bool enabled)
 {
     __multiTouch = enabled;
@@ -1263,6 +1298,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     // Pinch currently not implemented

+ 26 - 0
gameplay/src/PlatformBlackBerry.cpp

@@ -41,6 +41,7 @@ static EGLSurface __eglSurface = EGL_NO_SURFACE;
 static EGLConfig __eglConfig = 0;
 static int __orientationAngle;
 static bool __multiTouch = false;
+static bool __multiSampling = false;
 static float __pitch;
 static float __roll;
 static const char* __glExtensions;
@@ -745,6 +746,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
         EGL_NONE
     };
+    __multiSampling = samples > 0;
 
     const EGLint eglContextAttrs[] =
     {
@@ -929,6 +931,8 @@ Platform* Platform::create(Game* game, void* attachToWindow)
             }
         }
 
+        __multiSampling = samples > 0;
+
         if (!success)
         {
             checkErrorEGL("eglChooseConfig");
@@ -1400,6 +1404,23 @@ void Platform::sleep(long ms)
     usleep(ms * 1000);
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    //todo
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
 void Platform::setMultiTouch(bool enabled)
 {
     __multiTouch = enabled;
@@ -1532,6 +1553,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     // All are supported no need to test the bitset

+ 30 - 1
gameplay/src/PlatformLinux.cpp

@@ -27,6 +27,7 @@ static float __roll;
 static bool __mouseCaptured = false;
 static float __mouseCapturePointX = 0;
 static float __mouseCapturePointY = 0;
+static bool __multiSampling = false;
 static bool __cursorVisible = true;
 static Display* __display;
 static Window   __window;
@@ -513,7 +514,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
      
     // Get the window configuration values
     const char *title = NULL;
-    int __x = 0, __y = 0, __width = 1280, __height = 800;
+    int __x = 0, __y = 0, __width = 1280, __height = 800, __samples = 0;
     bool fullscreen = false;
     if (game->getConfig())
     {
@@ -528,6 +529,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
             int y = config->getInt("y");
             int width = config->getInt("width");
             int height = config->getInt("height");
+            int samples = config->getInt("samples");
             fullscreen = config->getBool("fullscreen");
 
             if (fullscreen && width == 0 && height == 0)
@@ -541,6 +543,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
             if (y != 0) __y = y;
             if (width != 0) __width = width;
             if (height != 0) __height = height;
+            if (samples != 0) __samples = samples;
         }
     }
 
@@ -578,8 +581,12 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         GLX_GREEN_SIZE,     8,
         GLX_BLUE_SIZE,      8,
         GLX_DOUBLEBUFFER,   True,
+        GLX_SAMPLE_BUFFERS, __samples > 0 ? 1 : 0,
+        GLX_SAMPLES,        __samples,
         0
     };
+    __multiSampling = __samples > 0;
+
     GLXFBConfig* configs;
     int configCount = 0;
     configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
@@ -995,6 +1002,23 @@ void Platform::sleep(long ms)
     usleep(ms * 1000);
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    //todo
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
 void Platform::setMultiTouch(bool enabled)
 {
     // not supported
@@ -1130,6 +1154,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     return false;

+ 27 - 0
gameplay/src/PlatformMacOSX.mm

@@ -51,6 +51,7 @@ static void* __attachToWindow = NULL;
 static bool __mouseCaptured = false;
 static bool __mouseCapturedFirstPass = false;
 static CGPoint __mouseCapturePoint;
+static bool __multiSampling = false;
 static bool __cursorVisible = true;
 static View* __view = NULL;
 
@@ -780,6 +781,8 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
     };
     NSOpenGLPixelFormatAttribute* attrs = __fullscreen ? fullscreenAttrs : windowedAttrs;
     
+    __multiSampling = samples > 0;
+
     // Try to choose a supported pixel format
     NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
     if (!pf)
@@ -797,6 +800,8 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
                 break;
             }
         }
+
+        __multiSampling = samples > 0;
         
         if (!valid)
         {
@@ -1669,6 +1674,23 @@ void Platform::sleep(long ms)
     usleep(ms * 1000);
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    //todo
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
 void Platform::setMultiTouch(bool enabled)
 {
 }
@@ -1802,6 +1824,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     // Swipe unsupported as it is considered moving mouse cursor

+ 36 - 1
gameplay/src/PlatformWindows.cpp

@@ -36,6 +36,7 @@ static HDC __hdc = 0;
 static HGLRC __hrc = 0;
 static bool __mouseCaptured = false;
 static POINT __mouseCapturePoint = { 0, 0 };
+static bool __multiSampling = false;
 static bool __cursorVisible = true;
 static unsigned int __gamepadsConnected = 0;
 
@@ -354,6 +355,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         return 0;
 
     case WM_DESTROY:
+        gameplay::Platform::shutdownInternal();
         PostQuitMessage(0);
         return 0;
 
@@ -662,6 +664,8 @@ bool initializeGL(WindowCreationParams* params)
         WGL_STENCIL_BITS_ARB, DEFAULT_STENCIL_BUFFER_SIZE,
         0
     };
+    __multiSampling = params->samples > 0;
+
     UINT numFormats;
     if (!wglChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats) || numFormats == 0)
     {
@@ -681,6 +685,8 @@ bool initializeGL(WindowCreationParams* params)
                     break;
                 }
             }
+
+            __multiSampling = params->samples > 0;
         }
 
         if (!valid)
@@ -966,7 +972,7 @@ int Platform::enterMessagePump()
 
             if (msg.message == WM_QUIT)
             {
-                _game->exit();
+                gameplay::Platform::shutdownInternal();
                 return msg.wParam;
             }
         }
@@ -1063,6 +1069,30 @@ void Platform::sleep(long ms)
     Sleep(ms);
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    if (enabled == __multiSampling)
+    {
+        return;
+    }
+
+    if (enabled)
+    {
+        glEnable(GL_MULTISAMPLE);
+    }
+    else
+    {
+        glDisable(GL_MULTISAMPLE);
+    }
+
+    __multiSampling = enabled;
+}
+
+bool Platform::isMultiSampling()
+{
+    return __multiSampling;
+}
+
 void Platform::setMultiTouch(bool enabled)
 {
     // not supported
@@ -1291,6 +1321,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::launchURL(const char* url)
 {
     if (url == NULL || *url == '\0')

+ 97 - 3
gameplay/src/PlatformiOS.mm

@@ -38,6 +38,27 @@ extern const int WINDOW_SCALE = [[UIScreen mainScreen] scale];
 static AppDelegate *__appDelegate = NULL;
 static View* __view = NULL;
 
+class TouchPoint
+{
+public:
+    unsigned int hashId;
+    int x;
+    int y;
+    bool down;
+    
+    TouchPoint()
+    {
+        hashId = 0;
+        x = 0;
+        y = 0;
+        down = false;
+    }
+};
+
+// more than we'd ever need, to be safe
+#define TOUCH_POINTS_MAX (10)
+static TouchPoint __touchPoints[TOUCH_POINTS_MAX];
+
 static double __timeStart;
 static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
@@ -259,6 +280,8 @@ int getUnicode(int key);
             samples /= 2;
         }
         
+        //todo: __multiSampling = samples > 0;
+
         // Re-bind the default framebuffer
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer) );
         
@@ -516,7 +539,27 @@ int getUnicode(int key);
         {
             touchID = [touch hash];
         }
-        Platform::touchEventInternal(Touch::TOUCH_PRESS, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
+
+        // Nested loop efficiency shouldn't be a concern since both loop sizes are small (<= 10)
+        int i = 0;
+        while (i < TOUCH_POINTS_MAX && __touchPoints[i].down)
+        {
+            i++;
+        }
+
+        if (i < TOUCH_POINTS_MAX)
+        {
+            __touchPoints[i].hashId = touchID;
+            __touchPoints[i].x = touchPoint.x * WINDOW_SCALE;
+            __touchPoints[i].y = touchPoint.y * WINDOW_SCALE;
+            __touchPoints[i].down = true;
+
+            Platform::touchEventInternal(Touch::TOUCH_PRESS, __touchPoints[i].x, __touchPoints[i].y, i);
+        }
+        else
+        {
+            print("touchesBegan: unable to find free element in __touchPoints");
+        }
     }
 }
 
@@ -528,7 +571,32 @@ int getUnicode(int key);
         CGPoint touchPoint = [touch locationInView:self];
         if(self.multipleTouchEnabled == YES) 
             touchID = [touch hash];
-        Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
+
+        // Nested loop efficiency shouldn't be a concern since both loop sizes are small (<= 10)
+        bool found = false;
+        for (int i = 0; !found && i < TOUCH_POINTS_MAX; i++)
+        {
+            if (__touchPoints[i].down && __touchPoints[i].hashId == touchID)
+            {
+                __touchPoints[i].down = false;
+                Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, i);
+                found = true;
+            }
+        }
+        
+        if (!found)
+        {
+            // It seems possible to receive an ID not in the array.
+            // The best we can do is clear the whole array.
+            for (int i = 0; i < TOUCH_POINTS_MAX; i++)
+            {
+                if (__touchPoints[i].down)
+                {
+                    __touchPoints[i].down = false;
+                    Platform::touchEventInternal(Touch::TOUCH_RELEASE, __touchPoints[i].x, __touchPoints[i].y, i);
+                }
+            }
+        }
     }
 }
 
@@ -546,7 +614,18 @@ int getUnicode(int key);
         CGPoint touchPoint = [touch locationInView:self];
         if(self.multipleTouchEnabled == YES) 
             touchID = [touch hash];
-        Platform::touchEventInternal(Touch::TOUCH_MOVE, touchPoint.x * WINDOW_SCALE, touchPoint.y * WINDOW_SCALE, touchID);
+
+        // Nested loop efficiency shouldn't be a concern since both loop sizes are small (<= 10)
+        for (int i = 0; i < TOUCH_POINTS_MAX; i++)
+        {
+            if (__touchPoints[i].down && __touchPoints[i].hashId == touchID)
+            {
+                __touchPoints[i].x = touchPoint.x * WINDOW_SCALE;
+                __touchPoints[i].y = touchPoint.y * WINDOW_SCALE;
+                Platform::touchEventInternal(Touch::TOUCH_MOVE, __touchPoints[i].x, __touchPoints[i].y, i);
+                break;
+            }
+        }
     }
 }
 
@@ -1331,6 +1410,16 @@ bool Platform::isCursorVisible()
     return false;
 }
 
+void Platform::setMultiSampling(bool enabled)
+{
+    //todo
+}
+
+bool Platform::isMultiSampling()
+{
+    return false; //todo
+}
+
 void Platform::setMultiTouch(bool enabled) 
 {
     __view.multipleTouchEnabled = enabled;
@@ -1401,6 +1490,11 @@ void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
     Gamepad::remove(handle);
 }
 
+void Platform::shutdownInternal()
+{
+    Game::getInstance()->shutdown();
+}
+
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     return true;

+ 1 - 1
gameplay/src/RadioButton.h

@@ -136,7 +136,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 58 - 21
gameplay/src/RenderState.cpp

@@ -208,6 +208,8 @@ void RenderState::setNodeBinding(Node* node)
 
 void RenderState::applyAutoBinding(const char* uniformName, const char* autoBinding)
 {
+    GP_ASSERT(_nodeBinding);
+
     MaterialParameter* param = getParameter(uniformName);
     GP_ASSERT(param);
 
@@ -264,31 +266,19 @@ void RenderState::applyAutoBinding(const char* uniformName, const char* autoBind
     }
     else if (strcmp(autoBinding, "MATRIX_PALETTE") == 0)
     {
-        Model* model = _nodeBinding->getModel();
-        MeshSkin* skin = model ? model->getSkin() : NULL;
-        if (skin)
-        {
-            GP_ASSERT(param);
-            param->bindValue(skin, &MeshSkin::getMatrixPalette, &MeshSkin::getMatrixPaletteSize);
-        }
+        param->bindValue(this, &RenderState::autoBindingGetMatrixPalette, &RenderState::autoBindingGetMatrixPaletteSize);
     }
     else if (strcmp(autoBinding, "SCENE_AMBIENT_COLOR") == 0)
     {
-        Scene* scene = _nodeBinding->getScene();
-        if (scene)
-            param->bindValue(scene, &Scene::getAmbientColor);
+        param->bindValue(this, &RenderState::autoBindingGetAmbientColor);
     }
     else if (strcmp(autoBinding, "SCENE_LIGHT_COLOR") == 0)
     {
-        Scene* scene = _nodeBinding->getScene();
-        if (scene)
-            param->bindValue(scene, &Scene::getLightColor);
+        param->bindValue(this, &RenderState::autoBindingGetLightColor);
     }
     else if (strcmp(autoBinding, "SCENE_LIGHT_DIRECTION") == 0)
     {
-        Scene* scene = _nodeBinding->getScene();
-        if (scene)
-            param->bindValue(scene, &Scene::getLightDirection);
+        param->bindValue(this, &RenderState::autoBindingGetLightDirection);
     }
     else
     {
@@ -296,6 +286,39 @@ void RenderState::applyAutoBinding(const char* uniformName, const char* autoBind
     }
 }
 
+const Vector4* RenderState::autoBindingGetMatrixPalette() const
+{
+    Model* model = _nodeBinding ? _nodeBinding->getModel() : NULL;
+    MeshSkin* skin = model ? model->getSkin() : NULL;
+    return skin ? skin->getMatrixPalette() : NULL;
+}
+
+const Vector3& RenderState::autoBindingGetAmbientColor() const
+{
+    Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
+    return scene ? scene->getAmbientColor() : Vector3::zero();
+}
+
+const Vector3& RenderState::autoBindingGetLightColor() const
+{
+    Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
+    return scene ? scene->getLightColor() : Vector3::one();
+}
+
+const Vector3& RenderState::autoBindingGetLightDirection() const
+{
+    static Vector3 down(0, -1, 0);
+    Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
+    return scene ? scene->getLightDirection() : down;
+}
+
+unsigned int RenderState::autoBindingGetMatrixPaletteSize() const
+{
+    Model* model = _nodeBinding ? _nodeBinding->getModel() : NULL;
+    MeshSkin* skin = model ? model->getSkin() : NULL;
+    return skin ? skin->getMatrixPaletteSize() : 0;
+}
+
 void RenderState::bind(Pass* pass)
 {
     GP_ASSERT(pass);
@@ -359,6 +382,7 @@ void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context)
 {
     GP_ASSERT(renderState);
 
+    // Clone parameters
     for (std::map<std::string, std::string>::const_iterator it = _autoBindings.begin(); it != _autoBindings.end(); ++it)
     {
         renderState->setParameterAutoBinding(it->first.c_str(), it->second.c_str());
@@ -373,17 +397,22 @@ void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context)
 
         renderState->_parameters.push_back(paramCopy);
     }
-    renderState->_parent = _parent;
+
+    // Clone our state block
     if (_state)
     {
-        renderState->setStateBlock(_state);
+        // StateBlock contains only simple primitive data, so use the default assignment
+        // operator to do a memberwise copy.
+        *renderState->getStateBlock() = *_state;
     }
-
-    // Note that _nodeBinding is not set here, it should be set by the caller.
+    
+    // Notes:
+    // 1. _nodeBinding should not be set here, it should be set by the caller.
+    // 2. _parent should not be set here, since it's set in the constructor of Technique and Pass.
 }
 
 RenderState::StateBlock::StateBlock()
-    : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(false), _depthFunction(RenderState::DEPTH_LESS),
+    : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(true), _depthFunction(RenderState::DEPTH_LESS),
       _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
       _bits(0L)
 {
@@ -556,6 +585,14 @@ static RenderState::Blend parseBlend(const char* value)
         return RenderState::BLEND_ZERO;
     else if (upper == "ONE")
         return RenderState::BLEND_ONE;
+    else if (upper == "SRC_COLOR")
+        return RenderState::BLEND_SRC_COLOR;
+    else if (upper == "ONE_MINUS_SRC_COLOR")
+        return RenderState::BLEND_ONE_MINUS_SRC_COLOR;
+    else if (upper == "DST_COLOR")
+        return RenderState::BLEND_DST_COLOR;
+    else if (upper == "ONE_MINUS_DST_COLOR")
+        return RenderState::BLEND_ONE_MINUS_DST_COLOR;
     else if (upper == "SRC_ALPHA")
         return RenderState::BLEND_SRC_ALPHA;
     else if (upper == "ONE_MINUS_SRC_ALPHA")

+ 28 - 1
gameplay/src/RenderState.h

@@ -2,6 +2,8 @@
 #define RENDERSTATE_H_
 
 #include "Ref.h"
+#include "Vector3.h"
+#include "Vector4.h"
 
 namespace gameplay
 {
@@ -134,7 +136,7 @@ public:
         BLEND_ZERO = GL_ZERO,
         BLEND_ONE = GL_ONE,
         BLEND_SRC_COLOR = GL_SRC_COLOR,
-        BLEN_ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
+        BLEND_ONE_MINUS_SRC_COLOR = GL_ONE_MINUS_SRC_COLOR,
         BLEND_DST_COLOR = GL_DST_COLOR,
         BLEND_ONE_MINUS_DST_COLOR = GL_ONE_MINUS_DST_COLOR,
         BLEND_SRC_ALPHA = GL_SRC_ALPHA,
@@ -461,6 +463,31 @@ private:
      */
     RenderState& operator=(const RenderState&);
 
+    /**
+     * Internal auto binding handler.
+     */
+    const Vector3& autoBindingGetAmbientColor() const;
+
+    /**
+     * Internal auto binding handler.
+     */
+    const Vector3& autoBindingGetLightColor() const;
+
+    /**
+     * Internal auto binding handler.
+     */
+    const Vector3& autoBindingGetLightDirection() const;
+
+    /**
+     * Internal auto binding handler.
+     */
+    const Vector4* autoBindingGetMatrixPalette() const;
+
+    /**
+     * Internal auto binding handler.
+     */
+    unsigned int autoBindingGetMatrixPaletteSize() const;
+
 protected:
 
     /**

+ 24 - 0
gameplay/src/Scene.cpp

@@ -136,6 +136,30 @@ unsigned int Scene::findNodes(const char* id, std::vector<Node*>& nodes, bool re
     return count;
 }
 
+void Scene::visitNode(Node* node, const char* visitMethod)
+{
+    ScriptController* sc = Game::getInstance()->getScriptController();
+
+    // Invoke the visit method for this node.
+    if (!sc->executeFunction<bool>(visitMethod, "<Node>", node))
+        return;
+
+    // If this node has a model with a mesh skin, visit the joint hierarchy within it
+    // since we don't add joint hierarcies directly to the scene. If joints are never
+    // visited, it's possible that nodes embedded within the joint hierarchy that contain
+    // models will never get visited (and therefore never get drawn).
+    if (node->_model && node->_model->_skin && node->_model->_skin->_rootNode)
+    {
+        visitNode(node->_model->_skin->_rootNode, visitMethod);
+    }
+
+    // Recurse for all children.
+    for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
+    {
+        visitNode(child, visitMethod);
+    }
+}
+
 Node* Scene::addNode(const char* id)
 {
     Node* node = Node::create(id);

+ 17 - 15
gameplay/src/Scene.h

@@ -333,7 +333,7 @@ private:
     /**
      * Visits the given node and all of its children recursively.
      */
-    inline void visitNode(Node* node, const char* visitMethod);
+    void visitNode(Node* node, const char* visitMethod);
 
     std::string _id;
     Camera* _activeCamera;
@@ -356,7 +356,6 @@ void Scene::visit(T* instance, bool (T::*visitMethod)(Node*))
     }
 }
 
-
 template <class T, class C>
 void Scene::visit(T* instance, bool (T::*visitMethod)(Node*,C), C cookie)
 {
@@ -381,6 +380,15 @@ void Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*))
     if (!(instance->*visitMethod)(node))
         return;
 
+    // If this node has a model with a mesh skin, visit the joint hierarchy within it
+    // since we don't add joint hierarcies directly to the scene. If joints are never
+    // visited, it's possible that nodes embedded within the joint hierarchy that contain
+    // models will never get visited (and therefore never get drawn).
+    if (node->_model && node->_model->_skin && node->_model->_skin->_rootNode)
+    {
+        visitNode(node->_model->_skin->_rootNode, instance, visitMethod);
+    }
+
     // Recurse for all children.
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     {
@@ -395,25 +403,19 @@ void Scene::visitNode(Node* node, T* instance, bool (T::*visitMethod)(Node*,C),
     if (!(instance->*visitMethod)(node, cookie))
         return;
 
-    // Recurse for all children.
-    for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
+    // If this node has a model with a mesh skin, visit the joint hierarchy within it
+    // since we don't add joint hierarcies directly to the scene. If joints are never
+    // visited, it's possible that nodes embedded within the joint hierarchy that contain
+    // models will never get visited (and therefore never get drawn).
+    if (node->_model && node->_model->_skin && node->_model->_skin->_rootNode)
     {
-        visitNode(child, instance, visitMethod, cookie);
+        visitNode(node->_model->_skin->_rootNode, instance, visitMethod, cookie);
     }
-}
-
-inline void Scene::visitNode(Node* node, const char* visitMethod)
-{
-    ScriptController* sc = Game::getInstance()->getScriptController();
-
-    // Invoke the visit method for this node.
-    if (!sc->executeFunction<bool>(visitMethod, "<Node>", node))
-        return;
 
     // Recurse for all children.
     for (Node* child = node->getFirstChild(); child != NULL; child = child->getNextSibling())
     {
-        visitNode(child, visitMethod);
+        visitNode(child, instance, visitMethod, cookie);
     }
 }
 

+ 1 - 1
gameplay/src/ScriptController.h

@@ -811,7 +811,7 @@ private:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @see Touch::TouchEvent
      */

+ 1 - 1
gameplay/src/Slider.h

@@ -192,7 +192,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 5 - 0
gameplay/src/Terrain.cpp

@@ -38,6 +38,11 @@ Terrain::Terrain() :
 
 Terrain::~Terrain()
 {
+    for (size_t i = 0, count = _patches.size(); i < count; ++i)
+    {
+        SAFE_DELETE(_patches[i]);
+    }
+
     if (_node)
         _node->removeListener(this);
 

+ 4 - 0
gameplay/src/TerrainPatch.cpp

@@ -667,6 +667,10 @@ TerrainPatch::Layer::~Layer()
 {
 }
 
+TerrainPatch::Level::Level() : model(NULL)
+{
+}
+
 bool TerrainPatch::LayerCompare::operator() (const Layer* lhs, const Layer* rhs) const
 {
     return (lhs->index < rhs->index);

+ 2 - 0
gameplay/src/TerrainPatch.h

@@ -41,6 +41,8 @@ private:
     struct Level
     {
         Model* model;
+
+        Level();
     };
 
     struct LayerCompare

+ 1 - 1
gameplay/src/TextBox.h

@@ -102,7 +102,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex An integer to identify this contact point within the currently active touch set.
+     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 10 - 0
gameplay/src/Vector2.h

@@ -392,6 +392,16 @@ public:
      * @return This vector, after the scale occurs.
      */
     inline Vector2& operator*=(float x);
+    
+    /**
+     * Returns the components of this vector divided by the given constant
+     *
+     * Note: this does not modify this vector.
+     *
+     * @param x the constant to divide this vector with
+     * @return a smaller vector
+     */
+    inline const Vector2 operator/(float x) const;
 
     /**
      * Determines if this vector is less than the given vector.

+ 5 - 0
gameplay/src/Vector2.inl

@@ -49,6 +49,11 @@ inline Vector2& Vector2::operator*=(float x)
     return *this;
 }
 
+inline const Vector2 Vector2::operator/(const float x) const
+{
+    return Vector2(this->x / x, this->y / x);
+}
+
 inline bool Vector2::operator<(const Vector2& v) const
 {
     if (x == v.x)

+ 10 - 0
gameplay/src/Vector3.h

@@ -422,6 +422,16 @@ public:
      * @return This vector, after the scale occurs.
      */
     inline Vector3& operator*=(float x);
+    
+    /**
+     * Returns the components of this vector divided by the given constant
+     *
+     * Note: this does not modify this vector.
+     *
+     * @param x the constant to divide this vector with
+     * @return a smaller vector
+     */
+    inline const Vector3 operator/(float x) const;
 
     /**
      * Determines if this vector is less than the given vector.

+ 5 - 0
gameplay/src/Vector3.inl

@@ -50,6 +50,11 @@ inline Vector3& Vector3::operator*=(float x)
     return *this;
 }
 
+inline const Vector3 Vector3::operator/(const float x) const
+{
+    return Vector3(this->x / x, this->y / x, this->z / x);
+}
+
 inline bool Vector3::operator<(const Vector3& v) const
 {
     if (x == v.x)

+ 10 - 0
gameplay/src/Vector4.h

@@ -404,6 +404,16 @@ public:
      * @return This vector, after the scale occurs.
      */
     inline Vector4& operator*=(float x);
+    
+    /**
+     * Returns the components of this vector divided by the given constant
+     *
+     * Note: this does not modify this vector.
+     *
+     * @param x the constant to divide this vector with
+     * @return a smaller vector
+     */
+    inline const Vector4 operator/(float x) const;
 
     /**
      * Determines if this vector is less than the given vector.

+ 5 - 0
gameplay/src/Vector4.inl

@@ -50,6 +50,11 @@ inline Vector4& Vector4::operator*=(float x)
     return *this;
 }
 
+inline const Vector4 Vector4::operator/(const float x) const
+{
+    return Vector4(this->x / x, this->y / x, this->z / x, this->w / x);
+}
+
 inline bool Vector4::operator<(const Vector4& v) const
 {
     if (x == v.x)

+ 73 - 0
gameplay/src/lua/lua_Game.cpp

@@ -54,6 +54,7 @@ void luaRegister_Game()
         {"isGestureSupported", lua_Game_isGestureSupported},
         {"isInitialized", lua_Game_isInitialized},
         {"isMouseCaptured", lua_Game_isMouseCaptured},
+        {"isMultiSampling", lua_Game_isMultiSampling},
         {"isMultiTouch", lua_Game_isMultiTouch},
         {"keyEvent", lua_Game_keyEvent},
         {"launchURL", lua_Game_launchURL},
@@ -66,6 +67,7 @@ void luaRegister_Game()
         {"schedule", lua_Game_schedule},
         {"setCursorVisible", lua_Game_setCursorVisible},
         {"setMouseCaptured", lua_Game_setMouseCaptured},
+        {"setMultiSampling", lua_Game_setMultiSampling},
         {"setMultiTouch", lua_Game_setMultiTouch},
         {"setViewport", lua_Game_setViewport},
         {"touchEvent", lua_Game_touchEvent},
@@ -1441,6 +1443,41 @@ int lua_Game_isMouseCaptured(lua_State* state)
     return 0;
 }
 
+int lua_Game_isMultiSampling(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                bool result = instance->isMultiSampling();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_isMultiSampling - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Game_isMultiTouch(lua_State* state)
 {
     // Get the number of parameters.
@@ -1885,6 +1922,42 @@ int lua_Game_setMouseCaptured(lua_State* state)
     return 0;
 }
 
+int lua_Game_setMultiSampling(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = ScriptUtil::luaCheckBool(state, 2);
+
+                Game* instance = getInstance(state);
+                instance->setMultiSampling(param1);
+
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Game_setMultiSampling - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Game_setMultiTouch(lua_State* state)
 {
     // Get the number of parameters.

+ 2 - 0
gameplay/src/lua/lua_Game.h

@@ -37,6 +37,7 @@ int lua_Game_isGestureRegistered(lua_State* state);
 int lua_Game_isGestureSupported(lua_State* state);
 int lua_Game_isInitialized(lua_State* state);
 int lua_Game_isMouseCaptured(lua_State* state);
+int lua_Game_isMultiSampling(lua_State* state);
 int lua_Game_isMultiTouch(lua_State* state);
 int lua_Game_keyEvent(lua_State* state);
 int lua_Game_launchURL(lua_State* state);
@@ -49,6 +50,7 @@ int lua_Game_run(lua_State* state);
 int lua_Game_schedule(lua_State* state);
 int lua_Game_setCursorVisible(lua_State* state);
 int lua_Game_setMouseCaptured(lua_State* state);
+int lua_Game_setMultiSampling(lua_State* state);
 int lua_Game_setMultiTouch(lua_State* state);
 int lua_Game_setViewport(lua_State* state);
 int lua_Game_static_getAbsoluteTime(lua_State* state);

+ 1 - 0
gameplay/src/lua/lua_Gamepad.cpp

@@ -5,6 +5,7 @@
 #include "Button.h"
 #include "Game.h"
 #include "Gamepad.h"
+#include "Platform.h"
 #include "lua_GamepadButtonMapping.h"
 
 namespace gameplay

+ 1 - 1
gameplay/src/lua/lua_Global.cpp

@@ -730,7 +730,7 @@ void luaRegister_lua_Global()
         ScriptUtil::registerConstantString("BLEND_ZERO", "BLEND_ZERO", scopePath);
         ScriptUtil::registerConstantString("BLEND_ONE", "BLEND_ONE", scopePath);
         ScriptUtil::registerConstantString("BLEND_SRC_COLOR", "BLEND_SRC_COLOR", scopePath);
-        ScriptUtil::registerConstantString("BLEN_ONE_MINUS_SRC_COLOR", "BLEN_ONE_MINUS_SRC_COLOR", scopePath);
+        ScriptUtil::registerConstantString("BLEND_ONE_MINUS_SRC_COLOR", "BLEND_ONE_MINUS_SRC_COLOR", scopePath);
         ScriptUtil::registerConstantString("BLEND_DST_COLOR", "BLEND_DST_COLOR", scopePath);
         ScriptUtil::registerConstantString("BLEND_ONE_MINUS_DST_COLOR", "BLEND_ONE_MINUS_DST_COLOR", scopePath);
         ScriptUtil::registerConstantString("BLEND_SRC_ALPHA", "BLEND_SRC_ALPHA", scopePath);

+ 98 - 0
gameplay/src/lua/lua_MeshBatch.cpp

@@ -2,6 +2,7 @@
 #include "ScriptController.h"
 #include "lua_MeshBatch.h"
 #include "Base.h"
+#include "Material.h"
 #include "MeshBatch.h"
 #include "lua_MeshPrimitiveType.h"
 
@@ -12,6 +13,7 @@ void luaRegister_MeshBatch()
 {
     const luaL_Reg lua_members[] = 
     {
+        {"add", lua_MeshBatch_add},
         {"draw", lua_MeshBatch_draw},
         {"finish", lua_MeshBatch_finish},
         {"getCapacity", lua_MeshBatch_getCapacity},
@@ -75,6 +77,102 @@ int lua_MeshBatch__gc(lua_State* state)
     return 0;
 }
 
+int lua_MeshBatch_add(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                ScriptUtil::LuaArray<float> param1 = ScriptUtil::getFloatPointer(2);
+
+                // Get parameter 2 off the stack.
+                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                MeshBatch* instance = getInstance(state);
+                instance->add(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_MeshBatch_add - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                ScriptUtil::LuaArray<float> param1 = ScriptUtil::getFloatPointer(2);
+
+                // Get parameter 2 off the stack.
+                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                // Get parameter 3 off the stack.
+                ScriptUtil::LuaArray<unsigned short> param3 = ScriptUtil::getUnsignedShortPointer(4);
+
+                MeshBatch* instance = getInstance(state);
+                instance->add(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_MeshBatch_add - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 5:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA) &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA) &&
+                lua_type(state, 5) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                ScriptUtil::LuaArray<float> param1 = ScriptUtil::getFloatPointer(2);
+
+                // Get parameter 2 off the stack.
+                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                // Get parameter 3 off the stack.
+                ScriptUtil::LuaArray<unsigned short> param3 = ScriptUtil::getUnsignedShortPointer(4);
+
+                // Get parameter 4 off the stack.
+                unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 5);
+
+                MeshBatch* instance = getInstance(state);
+                instance->add(param1, param2, param3, param4);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_MeshBatch_add - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3, 4 or 5).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_MeshBatch_draw(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_MeshBatch.h

@@ -6,6 +6,7 @@ namespace gameplay
 
 // Lua bindings for MeshBatch.
 int lua_MeshBatch__gc(lua_State* state);
+int lua_MeshBatch_add(lua_State* state);
 int lua_MeshBatch_draw(lua_State* state);
 int lua_MeshBatch_finish(lua_State* state);
 int lua_MeshBatch_getCapacity(lua_State* state);

+ 5 - 5
gameplay/src/lua/lua_RenderStateBlend.cpp

@@ -9,7 +9,7 @@ static const char* enumStringEmpty = "";
 static const char* luaEnumString_RenderStateBlend_BLEND_ZERO = "BLEND_ZERO";
 static const char* luaEnumString_RenderStateBlend_BLEND_ONE = "BLEND_ONE";
 static const char* luaEnumString_RenderStateBlend_BLEND_SRC_COLOR = "BLEND_SRC_COLOR";
-static const char* luaEnumString_RenderStateBlend_BLEN_ONE_MINUS_SRC_COLOR = "BLEN_ONE_MINUS_SRC_COLOR";
+static const char* luaEnumString_RenderStateBlend_BLEND_ONE_MINUS_SRC_COLOR = "BLEND_ONE_MINUS_SRC_COLOR";
 static const char* luaEnumString_RenderStateBlend_BLEND_DST_COLOR = "BLEND_DST_COLOR";
 static const char* luaEnumString_RenderStateBlend_BLEND_ONE_MINUS_DST_COLOR = "BLEND_ONE_MINUS_DST_COLOR";
 static const char* luaEnumString_RenderStateBlend_BLEND_SRC_ALPHA = "BLEND_SRC_ALPHA";
@@ -28,8 +28,8 @@ RenderState::Blend lua_enumFromString_RenderStateBlend(const char* s)
         return RenderState::BLEND_ONE;
     if (strcmp(s, luaEnumString_RenderStateBlend_BLEND_SRC_COLOR) == 0)
         return RenderState::BLEND_SRC_COLOR;
-    if (strcmp(s, luaEnumString_RenderStateBlend_BLEN_ONE_MINUS_SRC_COLOR) == 0)
-        return RenderState::BLEN_ONE_MINUS_SRC_COLOR;
+    if (strcmp(s, luaEnumString_RenderStateBlend_BLEND_ONE_MINUS_SRC_COLOR) == 0)
+        return RenderState::BLEND_ONE_MINUS_SRC_COLOR;
     if (strcmp(s, luaEnumString_RenderStateBlend_BLEND_DST_COLOR) == 0)
         return RenderState::BLEND_DST_COLOR;
     if (strcmp(s, luaEnumString_RenderStateBlend_BLEND_ONE_MINUS_DST_COLOR) == 0)
@@ -60,8 +60,8 @@ const char* lua_stringFromEnum_RenderStateBlend(RenderState::Blend e)
         return luaEnumString_RenderStateBlend_BLEND_ONE;
     if (e == RenderState::BLEND_SRC_COLOR)
         return luaEnumString_RenderStateBlend_BLEND_SRC_COLOR;
-    if (e == RenderState::BLEN_ONE_MINUS_SRC_COLOR)
-        return luaEnumString_RenderStateBlend_BLEN_ONE_MINUS_SRC_COLOR;
+    if (e == RenderState::BLEND_ONE_MINUS_SRC_COLOR)
+        return luaEnumString_RenderStateBlend_BLEND_ONE_MINUS_SRC_COLOR;
     if (e == RenderState::BLEND_DST_COLOR)
         return luaEnumString_RenderStateBlend_BLEND_DST_COLOR;
     if (e == RenderState::BLEND_ONE_MINUS_DST_COLOR)

+ 1 - 0
gameplay/src/lua/lua_Terrain.cpp

@@ -11,6 +11,7 @@
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "Terrain.h"
+#include "TerrainPatch.h"
 #include "Transform.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_TerrainFlags.h"