Przeglądaj źródła

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

Conflicts:
	gameplay/src/PlatformWin32.cpp
Steve Grenier 13 lat temu
rodzic
commit
559eaeaac4
100 zmienionych plików z 3498 dodań i 967 usunięć
  1. 57 3
      .gitignore
  2. 18 0
      CHANGES.md
  3. 1 1
      gameplay-encoder/src/AnimationChannel.cpp
  4. 1 0
      gameplay-encoder/src/Camera.cpp
  5. 4 5
      gameplay-encoder/src/DAESceneEncoder.cpp
  6. 1 1
      gameplay-encoder/src/DAEUtil.cpp
  7. 0 1
      gameplay-encoder/src/EncoderArguments.cpp
  8. 0 2
      gameplay-encoder/src/FBXSceneEncoder.cpp
  9. 1 1
      gameplay-encoder/src/GPBFile.cpp
  10. 2 2
      gameplay-encoder/src/Mesh.cpp
  11. 6 6
      gameplay-encoder/src/MeshSkin.cpp
  12. 1 1
      gameplay-encoder/src/Quaternion.cpp
  13. 4 4
      gameplay-encoder/src/TTFFontEncoder.cpp
  14. 1 1
      gameplay-encoder/src/Vector4.cpp
  15. 24 2
      gameplay.sln
  16. 6 0
      gameplay.xcworkspace/contents.xcworkspacedata
  17. 13 0
      gameplay/CMakeLists.txt
  18. 4 0
      gameplay/android/jni/Android.mk
  19. 8 0
      gameplay/gameplay.vcxproj
  20. 24 0
      gameplay/gameplay.vcxproj.filters
  21. 72 26
      gameplay/gameplay.xcodeproj/project.pbxproj
  22. 2 2
      gameplay/src/Animation.cpp
  23. 4 4
      gameplay/src/AnimationTarget.cpp
  24. 1 1
      gameplay/src/AudioBuffer.cpp
  25. 1 1
      gameplay/src/Base.h
  26. 10 10
      gameplay/src/BoundingBox.h
  27. 26 26
      gameplay/src/Button.cpp
  28. 9 9
      gameplay/src/CheckBox.cpp
  29. 69 69
      gameplay/src/Container.cpp
  30. 11 11
      gameplay/src/Control.cpp
  31. 16 2
      gameplay/src/FileSystem.cpp
  32. 5 8
      gameplay/src/Font.cpp
  33. 1 1
      gameplay/src/Form.cpp
  34. 5 0
      gameplay/src/Game.cpp
  35. 16 2
      gameplay/src/Game.h
  36. 5 0
      gameplay/src/Game.inl
  37. 2 2
      gameplay/src/Gesture.h
  38. 4 4
      gameplay/src/Joystick.cpp
  39. 1 4
      gameplay/src/Material.cpp
  40. 7 0
      gameplay/src/MaterialParameter.cpp
  41. 7 0
      gameplay/src/MaterialParameter.h
  42. 13 13
      gameplay/src/MathUtil.h
  43. 123 123
      gameplay/src/MathUtil.inl
  44. 185 185
      gameplay/src/MathUtilNeon.inl
  45. 2 2
      gameplay/src/Matrix.cpp
  46. 5 5
      gameplay/src/Mesh.cpp
  47. 5 1
      gameplay/src/Mesh.h
  48. 55 0
      gameplay/src/Node.cpp
  49. 52 5
      gameplay/src/Node.h
  50. 65 70
      gameplay/src/PhysicsCharacter.cpp
  51. 21 13
      gameplay/src/PhysicsCharacter.h
  52. 10 0
      gameplay/src/PhysicsCollisionObject.h
  53. 4 4
      gameplay/src/PhysicsController.cpp
  54. 1 0
      gameplay/src/PhysicsController.h
  55. 3 3
      gameplay/src/PhysicsRigidBody.cpp
  56. 8 4
      gameplay/src/PhysicsRigidBody.h
  57. 258 0
      gameplay/src/PhysicsVehicle.cpp
  58. 205 0
      gameplay/src/PhysicsVehicle.h
  59. 401 0
      gameplay/src/PhysicsVehicleWheel.cpp
  60. 336 0
      gameplay/src/PhysicsVehicleWheel.h
  61. 7 0
      gameplay/src/Platform.h
  62. 205 29
      gameplay/src/PlatformAndroid.cpp
  63. 31 26
      gameplay/src/PlatformLinux.cpp
  64. 71 3
      gameplay/src/PlatformMacOSX.mm
  65. 86 72
      gameplay/src/PlatformQNX.cpp
  66. 5 1
      gameplay/src/PlatformWin32.cpp
  67. 119 15
      gameplay/src/PlatformiOS.mm
  68. 8 14
      gameplay/src/Properties.cpp
  69. 1 1
      gameplay/src/Quaternion.cpp
  70. 12 12
      gameplay/src/RadioButton.cpp
  71. 1 1
      gameplay/src/Rectangle.cpp
  72. 1 1
      gameplay/src/Rectangle.h
  73. 1 1
      gameplay/src/RenderState.cpp
  74. 1 1
      gameplay/src/RenderTarget.cpp
  75. 3 9
      gameplay/src/SceneLoader.cpp
  76. 1 1
      gameplay/src/SceneLoader.h
  77. 13 13
      gameplay/src/ScriptController.cpp
  78. 55 55
      gameplay/src/ScriptController.h
  79. 32 32
      gameplay/src/ScriptController.inl
  80. 1 4
      gameplay/src/Slider.cpp
  81. 4 4
      gameplay/src/SpriteBatch.h
  82. 11 11
      gameplay/src/TextBox.cpp
  83. 1 1
      gameplay/src/TextBox.h
  84. 1 0
      gameplay/src/Texture.cpp
  85. 5 7
      gameplay/src/Theme.cpp
  86. 2 2
      gameplay/src/Transform.cpp
  87. 1 1
      gameplay/src/Vector4.cpp
  88. 1 1
      gameplay/src/gameplay-main-ios.mm
  89. 1 1
      gameplay/src/gameplay-main-macosx.mm
  90. 2 0
      gameplay/src/gameplay.h
  91. 80 0
      gameplay/src/lua/lua_Game.cpp
  92. 2 0
      gameplay/src/lua/lua_Game.h
  93. 6 6
      gameplay/src/lua/lua_GestureGestureEvent.cpp
  94. 5 1
      gameplay/src/lua/lua_Global.cpp
  95. 130 0
      gameplay/src/lua/lua_Joint.cpp
  96. 3 0
      gameplay/src/lua/lua_Joint.h
  97. 47 0
      gameplay/src/lua/lua_MaterialParameter.cpp
  98. 1 0
      gameplay/src/lua/lua_MaterialParameter.h
  99. 209 1
      gameplay/src/lua/lua_Mesh.cpp
  100. 130 0
      gameplay/src/lua/lua_Node.cpp

+ 57 - 3
.gitignore

@@ -131,7 +131,8 @@ Thumbs.db
 /gameplay-samples/sample03-character/Device-Debug
 /gameplay-samples/sample03-character/Device-Debug
 /gameplay-samples/sample03-character/Device-Coverage
 /gameplay-samples/sample03-character/Device-Coverage
 /gameplay-samples/sample03-character/Device-Profile
 /gameplay-samples/sample03-character/Device-Profile
-/gameplay-samples/sample03-character/Device-Release
+/gameplay-samples/sample03-character/Device-Release
+/gameplay-samples/sample03-character/game.config
 /gameplay-samples/sample03-character/res/shaders
 /gameplay-samples/sample03-character/res/shaders
 /gameplay-samples/sample03-character/res/logo_powered_white.png
 /gameplay-samples/sample03-character/res/logo_powered_white.png
 /gameplay-samples/sample03-character/sample03-character.xcodeproj/xcuserdata
 /gameplay-samples/sample03-character/sample03-character.xcodeproj/xcuserdata
@@ -195,7 +196,60 @@ Thumbs.db
 /gameplay-samples/sample05-lua/android/NUL
 /gameplay-samples/sample05-lua/android/NUL
 /gameplay-samples/sample05-lua/android/local.properties
 /gameplay-samples/sample05-lua/android/local.properties
 /gameplay-samples/sample05-lua/android/proguard.cfg
 /gameplay-samples/sample05-lua/android/proguard.cfg
-/gameplay-samples/sample05-lua/android/project.properties
+/gameplay-samples/sample05-lua/android/project.properties
+
+/gameplay-samples/sample06-racer/Debug
+/gameplay-samples/sample06-racer/DebugMem
+/gameplay-samples/sample06-racer/Release
+/gameplay-samples/sample06-racer/Simulator
+/gameplay-samples/sample06-racer/Simulator-Coverage
+/gameplay-samples/sample06-racer/Simulator-Profile
+/gameplay-samples/sample06-racer/Device-Debug
+/gameplay-samples/sample06-racer/Device-Coverage
+/gameplay-samples/sample06-racer/Device-Profile
+/gameplay-samples/sample06-racer/Device-Release
+/gameplay-samples/sample06-racer/game.config
+/gameplay-samples/sample06-racer/res/shaders
+/gameplay-samples/sample06-racer/res/logo_powered_white.png
+/gameplay-samples/sample06-racer/sample06-racer.xcodeproj/xcuserdata
+/gameplay-samples/sample06-racer/android/project.properties
+/gameplay-samples/sample06-racer/android/proguard.cfg
+/gameplay-samples/sample06-racer/android/local.properties
+/gameplay-samples/sample06-racer/android/src
+/gameplay-samples/sample06-racer/android/assets
+/gameplay-samples/sample06-racer/android/bin
+/gameplay-samples/sample06-racer/android/gen
+/gameplay-samples/sample06-racer/android/libs
+/gameplay-samples/sample06-racer/android/obj
+/gameplay-samples/sample06-racer/android/NUL
+/gameplay-samples/sample06-racer/android/local.properties
+/gameplay-samples/sample06-racer/android/proguard.cfg
+/gameplay-samples/sample06-racer/android/project.properties
 
 
 /gameplay-internal
 /gameplay-internal
-/gameplay\android/proguard-project.txt
+/gameplay/android/proguard-project.txt
+
+/gameplay-tests/Debug
+/gameplay-tests/DebugMem
+/gameplay-tests/Release
+/gameplay-tests/Simulator
+/gameplay-tests/Simulator-Coverage
+/gameplay-tests/Simulator-Profile
+/gameplay-tests/Device-Debug
+/gameplay-tests/Device-Coverage
+/gameplay-tests/Device-Profile
+/gameplay-tests/Device-Release
+/gameplay-tests/res/shaders
+/gameplay-tests/res/logo_powered_white.png
+/gameplay-tests/gameplay-tests.xcodeproj/xcuserdata
+/gameplay-tests/android/src
+/gameplay-tests/android/assets
+/gameplay-tests/android/bin
+/gameplay-tests/android/gen
+/gameplay-tests/android/libs
+/gameplay-tests/android/obj
+/gameplay-tests/android/NUL
+/gameplay-tests/android/local.properties
+/gameplay-tests/android/proguard-project.txt
+/gameplay-tests/android/project.properties
+

+ 18 - 0
CHANGES.md

@@ -1,3 +1,21 @@
+## v1.5.0
+
+- Linux support.
+- CMake support for Linux makefile generation.
+- Gamepad controllers support for desktops.
+- Touch gesture support for tap, swipe and pinch.
+- Vehicle phyics support via new PhysicsVehicle adn PhysicsVehicleWheels classes.
+- Adds gameplay-tests project as a test app for various engine features with initial basic tests.
+- Adds support for Scene files for wildcard identifiers.
+- Web community forums at http://www.gameplay3d.org/forums
+- Fixes the texture coordinates of Mesh::createQuad(float x, float y, float width, float height).
+- Fixes line-wise distortion when loading RGB png's into texture that are non-power of two.
+- Fixes inconsitencies in createXXXX methods.  (breaks compat. in Scene)
+- Fixes Rectanngle::contains.
+- Fixes Lua print logging.
+- Fixes Lua errors to be treated as runtime warnings.
+- Fixes setVertexData to pointers instead of constant data.
+
 ## v1.4.0
 ## v1.4.0
 
 
 - Lua script bindings for all gameplay interfaces.
 - Lua script bindings for all gameplay interfaces.

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

@@ -130,7 +130,7 @@ void AnimationChannel::setInterpolations(const std::vector<unsigned int>& values
 
 
 void AnimationChannel::removeDuplicates()
 void AnimationChannel::removeDuplicates()
 {
 {
-    LOG(3, "      Removing duplicates for channel with target attribute: %d.\n", _targetAttrib);
+    LOG(3, "      Removing duplicates for channel with target attribute: %u.\n", _targetAttrib);
 
 
     int startCount = _keytimes.size();
     int startCount = _keytimes.size();
 
 

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

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

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

@@ -287,10 +287,9 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
 
 
     // Find the <visual_scene> element within the <scene>
     // Find the <visual_scene> element within the <scene>
     const domCOLLADA::domSceneRef& domScene = _dom->getScene();
     const domCOLLADA::domSceneRef& domScene = _dom->getScene();
-    daeElement* scene = NULL;
     if (domScene && domScene->getInstance_visual_scene())
     if (domScene && domScene->getInstance_visual_scene())
     {
     {
-        scene = getVisualScene(domScene);
+        daeElement* scene = getVisualScene(domScene);
         if (scene)
         if (scene)
         {
         {
             if (nodeId == NULL)
             if (nodeId == NULL)
@@ -1317,7 +1316,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
     // Resolve and set joints array for skin
     // Resolve and set joints array for skin
     std::vector<Node*> _joints;
     std::vector<Node*> _joints;
     const std::vector<std::string>& jointNames = skin->getJointNames();
     const std::vector<std::string>& jointNames = skin->getJointNames();
-    for (std::vector<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); i++)
+    for (std::vector<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); ++i)
     {
     {
         Object* obj = _gamePlayFile.getFromRefTable(*i);
         Object* obj = _gamePlayFile.getFromRefTable(*i);
         if (obj && obj->getTypeId() == Object::NODE_ID)
         if (obj && obj->getTypeId() == Object::NODE_ID)
@@ -1369,7 +1368,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
 
 
             // Go through the joint list and convert them from sid to id because the sid information is
             // Go through the joint list and convert them from sid to id because the sid information is
             // lost when converting to the gameplay binary format.
             // lost when converting to the gameplay binary format.
-            for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i)
             {
             {
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeElement* element = resolver.getElement();
                 daeElement* element = resolver.getElement();
@@ -1388,7 +1387,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
             jointCount = list.size();
             jointCount = list.size();
             _jointInverseBindPoseMatrices.reserve(jointCount);
             _jointInverseBindPoseMatrices.reserve(jointCount);
             unsigned int j = 0;
             unsigned int j = 0;
-            for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
             {
             {
                 _jointLookupTable[*i] = j++;
                 _jointLookupTable[*i] = j++;
             }
             }

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

@@ -538,7 +538,7 @@ void findChannelsTargetingJoints(const domSourceRef& source, std::list<domChanne
 {
 {
     std::vector<std::string> jointNames;
     std::vector<std::string> jointNames;
     getJointNames(source, jointNames);
     getJointNames(source, jointNames);
-    for (std::vector<std::string>::iterator i = jointNames.begin(); i != jointNames.end(); i++)
+    for (std::vector<std::string>::iterator i = jointNames.begin(); i != jointNames.end(); ++i)
     {
     {
         daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
         daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
         daeElement* element = resolver.getElement();
         daeElement* element = resolver.getElement();

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

@@ -137,7 +137,6 @@ bool EncoderArguments::containsGroupNodeId(const std::string& nodeId) const
 
 
 const std::string EncoderArguments::getAnimationId(const std::string& nodeId) const
 const std::string EncoderArguments::getAnimationId(const std::string& nodeId) const
 {
 {
-    std::vector<std::string>::const_iterator it = find(_groupAnimationNodeId.begin(), _groupAnimationNodeId.end(), nodeId);
     for (size_t i = 0, size = _groupAnimationNodeId.size(); i < size; ++i)
     for (size_t i = 0, size = _groupAnimationNodeId.size(); i < size; ++i)
     {
     {
         if (_groupAnimationNodeId[i].compare(nodeId) == 0)
         if (_groupAnimationNodeId[i].compare(nodeId) == 0)

+ 0 - 2
gameplay-encoder/src/FBXSceneEncoder.cpp

@@ -308,8 +308,6 @@ void FBXSceneEncoder::loadScene(FbxScene* fbxScene)
 
 
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 {
 {
-    const std::string* targetId = NULL;
-
     const char* name = fbxNode->GetName();
     const char* name = fbxNode->GetName();
     Node* node = _gamePlayFile.getNode(name);
     Node* node = _gamePlayFile.getNode(name);
     if (node)
     if (node)

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

@@ -496,7 +496,7 @@ void GPBFile::decomposeTransformAnimationChannel(Animation* animation, Animation
             ++oneCount;
             ++oneCount;
         else
         else
         {
         {
-            LOG(4, "Rotation not identity: %d\n", i);
+            LOG(4, "Rotation not identity: %u\n", i);
             Quaternion q(x, y, z, w);
             Quaternion q(x, y, z, w);
             Vector3 axis;
             Vector3 axis;
             float angle = q.toAxisAngle(&axis);
             float angle = q.toAxisAngle(&axis);

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

@@ -28,7 +28,7 @@ void Mesh::writeBinary(FILE* file)
     Object::writeBinary(file);
     Object::writeBinary(file);
     // vertex formats
     // vertex formats
     write(_vertexFormat.size(), file);
     write(_vertexFormat.size(), file);
-    for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
+    for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); ++i)
     {
     {
         i->writeBinary(file);
         i->writeBinary(file);
     }
     }
@@ -74,7 +74,7 @@ void Mesh::writeText(FILE* file)
     // for each VertexFormat
     // for each VertexFormat
     if (vertices.size() > 0 )
     if (vertices.size() > 0 )
     {
     {
-        for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
+        for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); ++i)
         {
         {
             i->writeText(file);
             i->writeText(file);
         }
         }

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

@@ -37,12 +37,12 @@ void MeshSkin::writeBinary(FILE* file)
     Object::writeBinary(file);
     Object::writeBinary(file);
     write(_bindShape, 16, file);
     write(_bindShape, 16, file);
     write(_joints.size(), file);
     write(_joints.size(), file);
-    for (std::vector<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); i++)
+    for (std::vector<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); ++i)
     {
     {
         (*i)->writeBinaryXref(file);
         (*i)->writeBinaryXref(file);
     }
     }
     write(_bindPoses.size() * 16, file);
     write(_bindPoses.size() * 16, file);
-    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); ++i)
     {
     {
         write(i->m, 16, file);
         write(i->m, 16, file);
     }
     }
@@ -68,13 +68,13 @@ void MeshSkin::writeText(FILE* file)
     fprintfMatrix4f(file, _bindShape);
     fprintfMatrix4f(file, _bindShape);
     fprintf(file, "</bindShape>");
     fprintf(file, "</bindShape>");
     fprintf(file, "<joints>");
     fprintf(file, "<joints>");
-    for (std::vector<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); ++i)
     {
     {
         fprintf(file, "%s ", i->c_str());
         fprintf(file, "%s ", i->c_str());
     }
     }
     fprintf(file, "</joints>\n");
     fprintf(file, "</joints>\n");
     fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size() * 16);
     fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size() * 16);
-    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); ++i)
     {
     {
         for (unsigned int j = 0; j < 16; ++j)
         for (unsigned int j = 0; j < 16; ++j)
         {
         {
@@ -129,7 +129,7 @@ void MeshSkin::setBindPoses(std::vector<Matrix>& list)
 
 
 bool MeshSkin::hasJoint(const char* id)
 bool MeshSkin::hasJoint(const char* id)
 {
 {
-    for (std::vector<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); ++i)
     {
     {
         if (equals(*i, id))
         if (equals(*i, id))
         {
         {
@@ -192,7 +192,7 @@ void MeshSkin::computeBounds()
     unsigned int jointCount = _joints.size();
     unsigned int jointCount = _joints.size();
     unsigned int vertexCount = _mesh->getVertexCount();
     unsigned int vertexCount = _mesh->getVertexCount();
 
 
-    LOG(3, "  %d joints found.\n", jointCount);
+    LOG(3, "  %u joints found.\n", jointCount);
 
 
     std::vector<AnimationChannel*> channels;
     std::vector<AnimationChannel*> channels;
     std::vector<Node*> channelTargets;
     std::vector<Node*> channelTargets;

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

@@ -52,7 +52,7 @@ bool Quaternion::isIdentity() const
 
 
 bool Quaternion::isZero() const
 bool Quaternion::isZero() const
 {
 {
-    return x == 0.0f && y == 0.0f && z == 0.0f && z == 0.0f;
+    return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
 }
 }
 
 
 void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternion* dst)
 void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternion* dst)

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

@@ -222,10 +222,10 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
             penY = row * rowSize;
             penY = row * rowSize;
             if (penY + rowSize > (int)imageHeight)
             if (penY + rowSize > (int)imageHeight)
             {
             {
-                LOG(1, "Image size exceeded!");
-               return -1;
+                free(imageBuffer);
+				LOG(1, "Image size exceeded!");
+				return -1;
             }
             }
-
         }
         }
         
         
         // penY should include the glyph offsets.
         // penY should include the glyph offsets.
@@ -306,7 +306,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         pgmFilePath.append(".pgm");
         pgmFilePath.append(".pgm");
         FILE *imageFp = fopen(pgmFilePath.c_str(), "wb");
         FILE *imageFp = fopen(pgmFilePath.c_str(), "wb");
-        fprintf(imageFp, "P5 %d %d 255\n", imageWidth, imageHeight);
+        fprintf(imageFp, "P5 %u %u 255\n", imageWidth, imageHeight);
         fwrite((const char *)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, imageFp);
         fwrite((const char *)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, imageFp);
         fclose(imageFp);
         fclose(imageFp);
     }
     }

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

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

+ 24 - 2
gameplay.sln

@@ -3,6 +3,16 @@ Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
 # Visual Studio 2010
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay", "gameplay\gameplay.vcxproj", "{1032BA4B-57EB-4348-9E03-29DD63E80E4A}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay", "gameplay\gameplay.vcxproj", "{1032BA4B-57EB-4348-9E03-29DD63E80E4A}"
 EndProject
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-tests", "gameplay-tests\gameplay-tests.vcxproj", "{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample00-mesh", "gameplay-samples\sample00-mesh\sample00-mesh.vcxproj", "{D672DC66-3CE0-4878-B0D2-813CA731012F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample01-longboard", "gameplay-samples\sample01-longboard\sample01-longboard.vcxproj", "{9A515C8B-3320-4C5C-9754-211E91206C9D}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample01-longboard", "gameplay-samples\sample01-longboard\sample01-longboard.vcxproj", "{9A515C8B-3320-4C5C-9754-211E91206C9D}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
@@ -23,12 +33,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample04-particles", "gamep
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample00-mesh", "gameplay-samples\sample00-mesh\sample00-mesh.vcxproj", "{D672DC66-3CE0-4878-B0D2-813CA731012F}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{C6121A62-AA46-BA6D-A1CE-8000544456AA}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{C6121A62-AA46-BA6D-A1CE-8000544456AA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample06-racer", "gameplay-samples\sample06-racer\sample06-racer.vcxproj", "{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
@@ -82,6 +92,18 @@ Global
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.Build.0 = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.ActiveCfg = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.Build.0 = Release|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.Build.0 = Debug|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.ActiveCfg = Release|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 6 - 0
gameplay.xcworkspace/contents.xcworkspacedata

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

+ 13 - 0
gameplay/CMakeLists.txt

@@ -77,6 +77,7 @@ set(GAMEPLAY_SRC
     src/gameplay-main-linux.cpp
     src/gameplay-main-linux.cpp
     src/gameplay-main-qnx.cpp
     src/gameplay-main-qnx.cpp
     src/gameplay-main-win32.cpp
     src/gameplay-main-win32.cpp
+	src/Gesture.h
     src/Image.cpp
     src/Image.cpp
     src/Image.h
     src/Image.h
     src/Image.inl
     src/Image.inl
@@ -142,6 +143,10 @@ set(GAMEPLAY_SRC
     src/PhysicsSocketConstraint.h
     src/PhysicsSocketConstraint.h
     src/PhysicsSpringConstraint.cpp
     src/PhysicsSpringConstraint.cpp
     src/PhysicsSpringConstraint.h
     src/PhysicsSpringConstraint.h
+	src/PhysicsVehicle.cpp
+	src/PhysicsVehicle.h
+	src/PhysicsVehicleWheel.cpp
+	src/PhysicsVehicle.h
     src/Plane.cpp
     src/Plane.cpp
     src/Plane.h
     src/Plane.h
     src/Plane.inl
     src/Plane.inl
@@ -325,6 +330,10 @@ set(GAMEPLAY_LUA
     src/lua/lua_GamepadGamepadEvent.h
     src/lua/lua_GamepadGamepadEvent.h
     src/lua/lua_GameState.cpp
     src/lua/lua_GameState.cpp
     src/lua/lua_GameState.h
     src/lua/lua_GameState.h
+	src/lua/lua_Gesture.cpp
+	src/lua/lua_Gesture.h
+	src/lua/lua_GestureGestureEvent.cpp
+	src/lua/lua_GestureGestureEvent.h
     src/lua/lua_Global.cpp
     src/lua/lua_Global.cpp
     src/lua/lua_Global.h
     src/lua/lua_Global.h
     src/lua/lua_Image.cpp
     src/lua/lua_Image.cpp
@@ -435,6 +444,10 @@ set(GAMEPLAY_LUA
     src/lua/lua_PhysicsSocketConstraint.h
     src/lua/lua_PhysicsSocketConstraint.h
     src/lua/lua_PhysicsSpringConstraint.cpp
     src/lua/lua_PhysicsSpringConstraint.cpp
     src/lua/lua_PhysicsSpringConstraint.h
     src/lua/lua_PhysicsSpringConstraint.h
+	src/lua/lua_PhysicsVehicle.cpp
+	src/lua/lua_PhysicsVehicle.h
+	src/lua/lua_PhysicsVehicleWheel.cpp
+	src/lua/lua_PhysicsVehicleWheel.h
     src/lua/lua_Plane.cpp
     src/lua/lua_Plane.cpp
     src/lua/lua_Plane.h
     src/lua/lua_Plane.h
     src/lua/lua_Platform.cpp
     src/lua/lua_Platform.cpp

+ 4 - 0
gameplay/android/jni/Android.mk

@@ -82,6 +82,8 @@ LOCAL_SRC_FILES := \
     PhysicsRigidBody.cpp \
     PhysicsRigidBody.cpp \
     PhysicsSocketConstraint.cpp \
     PhysicsSocketConstraint.cpp \
     PhysicsSpringConstraint.cpp \
     PhysicsSpringConstraint.cpp \
+	PhysicsVehicle.cpp \
+	PhysicsVehicleWheel.cpp \
     Plane.cpp \
     Plane.cpp \
     PlatformAndroid.cpp \
     PlatformAndroid.cpp \
     Properties.cpp \
     Properties.cpp \
@@ -224,6 +226,8 @@ LOCAL_SRC_FILES := \
     lua/lua_PhysicsRigidBodyParameters.cpp \
     lua/lua_PhysicsRigidBodyParameters.cpp \
     lua/lua_PhysicsSocketConstraint.cpp \
     lua/lua_PhysicsSocketConstraint.cpp \
     lua/lua_PhysicsSpringConstraint.cpp \
     lua/lua_PhysicsSpringConstraint.cpp \
+	lua/lua_PhysicsVehicle.cpp \
+	lua/lua_PhysicsVehicleWheel.cpp \
     lua/lua_Plane.cpp \
     lua/lua_Plane.cpp \
     lua/lua_Platform.cpp \
     lua/lua_Platform.cpp \
     lua/lua_Properties.cpp \
     lua/lua_Properties.cpp \

+ 8 - 0
gameplay/gameplay.vcxproj

@@ -171,6 +171,8 @@
     <ClCompile Include="src\lua\lua_PhysicsRigidBodyParameters.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsRigidBodyParameters.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSpringConstraint.cpp" />
     <ClCompile Include="src\lua\lua_PhysicsSpringConstraint.cpp" />
+    <ClCompile Include="src\lua\lua_PhysicsVehicle.cpp" />
+    <ClCompile Include="src\lua\lua_PhysicsVehicleWheel.cpp" />
     <ClCompile Include="src\lua\lua_Plane.cpp" />
     <ClCompile Include="src\lua\lua_Plane.cpp" />
     <ClCompile Include="src\lua\lua_Platform.cpp" />
     <ClCompile Include="src\lua\lua_Platform.cpp" />
     <ClCompile Include="src\lua\lua_Properties.cpp" />
     <ClCompile Include="src\lua\lua_Properties.cpp" />
@@ -241,6 +243,8 @@
     <ClCompile Include="src\PhysicsRigidBody.cpp" />
     <ClCompile Include="src\PhysicsRigidBody.cpp" />
     <ClCompile Include="src\PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\PhysicsSocketConstraint.cpp" />
     <ClCompile Include="src\PhysicsSpringConstraint.cpp" />
     <ClCompile Include="src\PhysicsSpringConstraint.cpp" />
+    <ClCompile Include="src\PhysicsVehicle.cpp" />
+    <ClCompile Include="src\PhysicsVehicleWheel.cpp" />
     <ClCompile Include="src\Plane.cpp" />
     <ClCompile Include="src\Plane.cpp" />
     <ClCompile Include="src\PlatformAndroid.cpp" />
     <ClCompile Include="src\PlatformAndroid.cpp" />
     <ClCompile Include="src\PlatformLinux.cpp" />
     <ClCompile Include="src\PlatformLinux.cpp" />
@@ -432,6 +436,8 @@
     <ClInclude Include="src\lua\lua_PhysicsRigidBodyParameters.h" />
     <ClInclude Include="src\lua\lua_PhysicsRigidBodyParameters.h" />
     <ClInclude Include="src\lua\lua_PhysicsSocketConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSocketConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSpringConstraint.h" />
     <ClInclude Include="src\lua\lua_PhysicsSpringConstraint.h" />
+    <ClInclude Include="src\lua\lua_PhysicsVehicle.h" />
+    <ClInclude Include="src\lua\lua_PhysicsVehicleWheel.h" />
     <ClInclude Include="src\lua\lua_Plane.h" />
     <ClInclude Include="src\lua\lua_Plane.h" />
     <ClInclude Include="src\lua\lua_Platform.h" />
     <ClInclude Include="src\lua\lua_Platform.h" />
     <ClInclude Include="src\lua\lua_Properties.h" />
     <ClInclude Include="src\lua\lua_Properties.h" />
@@ -504,6 +510,8 @@
     <ClInclude Include="src\PhysicsRigidBody.h" />
     <ClInclude Include="src\PhysicsRigidBody.h" />
     <ClInclude Include="src\PhysicsSocketConstraint.h" />
     <ClInclude Include="src\PhysicsSocketConstraint.h" />
     <ClInclude Include="src\PhysicsSpringConstraint.h" />
     <ClInclude Include="src\PhysicsSpringConstraint.h" />
+    <ClInclude Include="src\PhysicsVehicle.h" />
+    <ClInclude Include="src\PhysicsVehicleWheel.h" />
     <ClInclude Include="src\Plane.h" />
     <ClInclude Include="src\Plane.h" />
     <ClInclude Include="src\Platform.h" />
     <ClInclude Include="src\Platform.h" />
     <ClInclude Include="src\Properties.h" />
     <ClInclude Include="src\Properties.h" />

+ 24 - 0
gameplay/gameplay.vcxproj.filters

@@ -792,6 +792,18 @@
     <ClCompile Include="src\lua\lua_GestureGestureEvent.cpp">
     <ClCompile Include="src\lua\lua_GestureGestureEvent.cpp">
       <Filter>lua</Filter>
       <Filter>lua</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\PhysicsVehicle.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\PhysicsVehicleWheel.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_PhysicsVehicle.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_PhysicsVehicleWheel.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
     <ClInclude Include="src\Animation.h">
@@ -1574,6 +1586,18 @@
     <ClInclude Include="src\lua\lua_GestureGestureEvent.h">
     <ClInclude Include="src\lua\lua_GestureGestureEvent.h">
       <Filter>lua</Filter>
       <Filter>lua</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\PhysicsVehicleWheel.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\PhysicsVehicle.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_PhysicsVehicle.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_PhysicsVehicleWheel.h">
+      <Filter>lua</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="src\gameplay-main-macosx.mm">
     <None Include="src\gameplay-main-macosx.mm">

+ 72 - 26
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -21,6 +21,22 @@
 		421A233515B600E8004F97C3 /* ScriptTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421A233215B600E8004F97C3 /* ScriptTarget.cpp */; };
 		421A233515B600E8004F97C3 /* ScriptTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421A233215B600E8004F97C3 /* ScriptTarget.cpp */; };
 		421A233615B600E8004F97C3 /* ScriptTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 421A233315B600E8004F97C3 /* ScriptTarget.h */; };
 		421A233615B600E8004F97C3 /* ScriptTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 421A233315B600E8004F97C3 /* ScriptTarget.h */; };
 		421A233715B600E8004F97C3 /* ScriptTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 421A233315B600E8004F97C3 /* ScriptTarget.h */; };
 		421A233715B600E8004F97C3 /* ScriptTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 421A233315B600E8004F97C3 /* ScriptTarget.h */; };
+		421FBD4F1602818800A61BC0 /* PhysicsVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD4B1602818800A61BC0 /* PhysicsVehicle.cpp */; };
+		421FBD501602818800A61BC0 /* PhysicsVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD4B1602818800A61BC0 /* PhysicsVehicle.cpp */; };
+		421FBD511602818800A61BC0 /* PhysicsVehicle.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD4C1602818800A61BC0 /* PhysicsVehicle.h */; };
+		421FBD521602818800A61BC0 /* PhysicsVehicle.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD4C1602818800A61BC0 /* PhysicsVehicle.h */; };
+		421FBD531602818800A61BC0 /* PhysicsVehicleWheel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD4D1602818800A61BC0 /* PhysicsVehicleWheel.cpp */; };
+		421FBD541602818800A61BC0 /* PhysicsVehicleWheel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD4D1602818800A61BC0 /* PhysicsVehicleWheel.cpp */; };
+		421FBD551602818800A61BC0 /* PhysicsVehicleWheel.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD4E1602818800A61BC0 /* PhysicsVehicleWheel.h */; };
+		421FBD561602818800A61BC0 /* PhysicsVehicleWheel.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD4E1602818800A61BC0 /* PhysicsVehicleWheel.h */; };
+		421FBD5C1602827C00A61BC0 /* lua_PhysicsVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD581602827C00A61BC0 /* lua_PhysicsVehicle.cpp */; };
+		421FBD5D1602827C00A61BC0 /* lua_PhysicsVehicle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD581602827C00A61BC0 /* lua_PhysicsVehicle.cpp */; };
+		421FBD5E1602827C00A61BC0 /* lua_PhysicsVehicle.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD591602827C00A61BC0 /* lua_PhysicsVehicle.h */; };
+		421FBD5F1602827C00A61BC0 /* lua_PhysicsVehicle.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD591602827C00A61BC0 /* lua_PhysicsVehicle.h */; };
+		421FBD601602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD5A1602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp */; };
+		421FBD611602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 421FBD5A1602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp */; };
+		421FBD621602827C00A61BC0 /* lua_PhysicsVehicleWheel.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD5B1602827C00A61BC0 /* lua_PhysicsVehicleWheel.h */; };
+		421FBD631602827C00A61BC0 /* lua_PhysicsVehicleWheel.h in Headers */ = {isa = PBXBuildFile; fileRef = 421FBD5B1602827C00A61BC0 /* lua_PhysicsVehicleWheel.h */; };
 		422260D61537790F0011E3AB /* Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 422260D41537790F0011E3AB /* Bundle.cpp */; };
 		422260D61537790F0011E3AB /* Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 422260D41537790F0011E3AB /* Bundle.cpp */; };
 		422260D71537790F0011E3AB /* Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 422260D41537790F0011E3AB /* Bundle.cpp */; };
 		422260D71537790F0011E3AB /* Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 422260D41537790F0011E3AB /* Bundle.cpp */; };
 		422260D81537790F0011E3AB /* Bundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 422260D51537790F0011E3AB /* Bundle.h */; };
 		422260D81537790F0011E3AB /* Bundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 422260D51537790F0011E3AB /* Bundle.h */; };
@@ -32,14 +48,6 @@
 		4239DDEF157545A1005EA3F6 /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDEA157545A1005EA3F6 /* Joystick.h */; };
 		4239DDEF157545A1005EA3F6 /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDEA157545A1005EA3F6 /* Joystick.h */; };
 		4239DDF4157545C1005EA3F6 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDF1157545C1005EA3F6 /* MathUtil.h */; };
 		4239DDF4157545C1005EA3F6 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDF1157545C1005EA3F6 /* MathUtil.h */; };
 		4239DDF5157545C1005EA3F6 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDF1157545C1005EA3F6 /* MathUtil.h */; };
 		4239DDF5157545C1005EA3F6 /* MathUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4239DDF1157545C1005EA3F6 /* MathUtil.h */; };
-		424CD6EF15F6F349009CA1B8 /* lua_Gesture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 424CD6EB15F6F349009CA1B8 /* lua_Gesture.cpp */; };
-		424CD6F015F6F349009CA1B8 /* lua_Gesture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 424CD6EB15F6F349009CA1B8 /* lua_Gesture.cpp */; };
-		424CD6F115F6F349009CA1B8 /* lua_Gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 424CD6EC15F6F349009CA1B8 /* lua_Gesture.h */; };
-		424CD6F215F6F349009CA1B8 /* lua_Gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 424CD6EC15F6F349009CA1B8 /* lua_Gesture.h */; };
-		424CD6F315F6F349009CA1B8 /* lua_GestureGestureEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 424CD6ED15F6F349009CA1B8 /* lua_GestureGestureEvent.cpp */; };
-		424CD6F415F6F349009CA1B8 /* lua_GestureGestureEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 424CD6ED15F6F349009CA1B8 /* lua_GestureGestureEvent.cpp */; };
-		424CD6F515F6F349009CA1B8 /* lua_GestureGestureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 424CD6EE15F6F349009CA1B8 /* lua_GestureGestureEvent.h */; };
-		424CD6F615F6F349009CA1B8 /* lua_GestureGestureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 424CD6EE15F6F349009CA1B8 /* lua_GestureGestureEvent.h */; };
 		4251B131152D049B002F6199 /* ScreenDisplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4251B12E152D049B002F6199 /* ScreenDisplayer.h */; };
 		4251B131152D049B002F6199 /* ScreenDisplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4251B12E152D049B002F6199 /* ScreenDisplayer.h */; };
 		4251B132152D049B002F6199 /* ScreenDisplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4251B12E152D049B002F6199 /* ScreenDisplayer.h */; };
 		4251B132152D049B002F6199 /* ScreenDisplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4251B12E152D049B002F6199 /* ScreenDisplayer.h */; };
 		4251B133152D049B002F6199 /* ThemeStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4251B12F152D049B002F6199 /* ThemeStyle.cpp */; };
 		4251B133152D049B002F6199 /* ThemeStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4251B12F152D049B002F6199 /* ThemeStyle.cpp */; };
@@ -1618,7 +1626,6 @@
 		5B2BC7601512514500D176CD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC75E1512514500D176CD /* OpenGL.framework */; };
 		5B2BC7601512514500D176CD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC75E1512514500D176CD /* OpenGL.framework */; };
 		5B2BC7621512514D00D176CD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7611512514D00D176CD /* QuartzCore.framework */; };
 		5B2BC7621512514D00D176CD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7611512514D00D176CD /* QuartzCore.framework */; };
 		5B2BC7641512516B00D176CD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7631512516B00D176CD /* libz.dylib */; };
 		5B2BC7641512516B00D176CD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7631512516B00D176CD /* libz.dylib */; };
-		5BAF201F152F2A6D003E2AC3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF201E152F2A6D003E2AC3 /* libz.dylib */; };
 		5BAF2027152F2AF0003E2AC3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2020152F2AF0003E2AC3 /* CoreGraphics.framework */; };
 		5BAF2027152F2AF0003E2AC3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2020152F2AF0003E2AC3 /* CoreGraphics.framework */; };
 		5BAF2028152F2AF0003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2021152F2AF0003E2AC3 /* CoreMotion.framework */; };
 		5BAF2028152F2AF0003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2021152F2AF0003E2AC3 /* CoreMotion.framework */; };
 		5BAF2029152F2AF0003E2AC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2022152F2AF0003E2AC3 /* Foundation.framework */; };
 		5BAF2029152F2AF0003E2AC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2022152F2AF0003E2AC3 /* Foundation.framework */; };
@@ -1628,6 +1635,14 @@
 		5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2026152F2AF0003E2AC3 /* UIKit.framework */; };
 		5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2026152F2AF0003E2AC3 /* UIKit.framework */; };
 		5BB0823D14C6FEC40019975F /* Mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BB0823C14C6FEC40019975F /* Mouse.h */; };
 		5BB0823D14C6FEC40019975F /* Mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BB0823C14C6FEC40019975F /* Mouse.h */; };
 		5BB0823E14C6FEC40019975F /* 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 */; };
+		5BBAD0F415F5251E004C9639 /* lua_Gesture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */; };
+		5BBAD0F515F5251E004C9639 /* lua_Gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBAD0F015F5251D004C9639 /* lua_Gesture.h */; };
+		5BBAD0F615F5251E004C9639 /* lua_Gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBAD0F015F5251D004C9639 /* lua_Gesture.h */; };
+		5BBAD0F715F5251E004C9639 /* lua_GestureGestureEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBAD0F115F5251D004C9639 /* lua_GestureGestureEvent.cpp */; };
+		5BBAD0F815F5251E004C9639 /* lua_GestureGestureEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBAD0F115F5251D004C9639 /* lua_GestureGestureEvent.cpp */; };
+		5BBAD0F915F5251E004C9639 /* lua_GestureGestureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBAD0F215F5251D004C9639 /* lua_GestureGestureEvent.h */; };
+		5BBAD0FA15F5251E004C9639 /* lua_GestureGestureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBAD0F215F5251D004C9639 /* lua_GestureGestureEvent.h */; };
 		5BBE143E1513E400003FB362 /* PhysicsGhostObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */; };
 		5BBE143E1513E400003FB362 /* PhysicsGhostObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */; };
 		5BBE143F1513E400003FB362 /* PhysicsGhostObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */; };
 		5BBE143F1513E400003FB362 /* PhysicsGhostObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */; };
 		5BBE14401513E400003FB362 /* PhysicsGhostObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBE143D1513E400003FB362 /* PhysicsGhostObject.h */; };
 		5BBE14401513E400003FB362 /* PhysicsGhostObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BBE143D1513E400003FB362 /* PhysicsGhostObject.h */; };
@@ -1706,6 +1721,14 @@
 		421230D415B6121C00F0EC76 /* lua_ScriptTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_ScriptTarget.h; path = src/lua/lua_ScriptTarget.h; sourceTree = SOURCE_ROOT; };
 		421230D415B6121C00F0EC76 /* lua_ScriptTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_ScriptTarget.h; path = src/lua/lua_ScriptTarget.h; sourceTree = SOURCE_ROOT; };
 		421A233215B600E8004F97C3 /* ScriptTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptTarget.cpp; path = src/ScriptTarget.cpp; sourceTree = SOURCE_ROOT; };
 		421A233215B600E8004F97C3 /* ScriptTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptTarget.cpp; path = src/ScriptTarget.cpp; sourceTree = SOURCE_ROOT; };
 		421A233315B600E8004F97C3 /* ScriptTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptTarget.h; path = src/ScriptTarget.h; sourceTree = SOURCE_ROOT; };
 		421A233315B600E8004F97C3 /* ScriptTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptTarget.h; path = src/ScriptTarget.h; sourceTree = SOURCE_ROOT; };
+		421FBD4B1602818800A61BC0 /* PhysicsVehicle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsVehicle.cpp; path = src/PhysicsVehicle.cpp; sourceTree = SOURCE_ROOT; };
+		421FBD4C1602818800A61BC0 /* PhysicsVehicle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsVehicle.h; path = src/PhysicsVehicle.h; sourceTree = SOURCE_ROOT; };
+		421FBD4D1602818800A61BC0 /* PhysicsVehicleWheel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsVehicleWheel.cpp; path = src/PhysicsVehicleWheel.cpp; sourceTree = SOURCE_ROOT; };
+		421FBD4E1602818800A61BC0 /* PhysicsVehicleWheel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsVehicleWheel.h; path = src/PhysicsVehicleWheel.h; sourceTree = SOURCE_ROOT; };
+		421FBD581602827C00A61BC0 /* lua_PhysicsVehicle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_PhysicsVehicle.cpp; sourceTree = "<group>"; };
+		421FBD591602827C00A61BC0 /* lua_PhysicsVehicle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_PhysicsVehicle.h; sourceTree = "<group>"; };
+		421FBD5A1602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_PhysicsVehicleWheel.cpp; sourceTree = "<group>"; };
+		421FBD5B1602827C00A61BC0 /* lua_PhysicsVehicleWheel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_PhysicsVehicleWheel.h; sourceTree = "<group>"; };
 		422260D41537790F0011E3AB /* Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Bundle.cpp; path = src/Bundle.cpp; sourceTree = SOURCE_ROOT; };
 		422260D41537790F0011E3AB /* Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Bundle.cpp; path = src/Bundle.cpp; sourceTree = SOURCE_ROOT; };
 		422260D51537790F0011E3AB /* Bundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Bundle.h; path = src/Bundle.h; sourceTree = SOURCE_ROOT; };
 		422260D51537790F0011E3AB /* Bundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Bundle.h; path = src/Bundle.h; sourceTree = SOURCE_ROOT; };
 		4234D99A14686C52003031B3 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		4234D99A14686C52003031B3 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1716,10 +1739,6 @@
 		4239DDF1157545C1005EA3F6 /* MathUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathUtil.h; path = src/MathUtil.h; sourceTree = SOURCE_ROOT; };
 		4239DDF1157545C1005EA3F6 /* MathUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathUtil.h; path = src/MathUtil.h; sourceTree = SOURCE_ROOT; };
 		4239DDF2157545C1005EA3F6 /* MathUtil.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = MathUtil.inl; path = src/MathUtil.inl; sourceTree = SOURCE_ROOT; };
 		4239DDF2157545C1005EA3F6 /* MathUtil.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = MathUtil.inl; path = src/MathUtil.inl; sourceTree = SOURCE_ROOT; };
 		4239DDF3157545C1005EA3F6 /* MathUtilNeon.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = MathUtilNeon.inl; path = src/MathUtilNeon.inl; sourceTree = SOURCE_ROOT; };
 		4239DDF3157545C1005EA3F6 /* MathUtilNeon.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = MathUtilNeon.inl; path = src/MathUtilNeon.inl; sourceTree = SOURCE_ROOT; };
-		424CD6EB15F6F349009CA1B8 /* lua_Gesture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_Gesture.cpp; sourceTree = "<group>"; };
-		424CD6EC15F6F349009CA1B8 /* lua_Gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_Gesture.h; sourceTree = "<group>"; };
-		424CD6ED15F6F349009CA1B8 /* lua_GestureGestureEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_GestureGestureEvent.cpp; sourceTree = "<group>"; };
-		424CD6EE15F6F349009CA1B8 /* lua_GestureGestureEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_GestureGestureEvent.h; sourceTree = "<group>"; };
 		4251B12E152D049B002F6199 /* ScreenDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScreenDisplayer.h; path = src/ScreenDisplayer.h; sourceTree = SOURCE_ROOT; };
 		4251B12E152D049B002F6199 /* ScreenDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScreenDisplayer.h; path = src/ScreenDisplayer.h; sourceTree = SOURCE_ROOT; };
 		4251B12F152D049B002F6199 /* ThemeStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThemeStyle.cpp; path = src/ThemeStyle.cpp; sourceTree = SOURCE_ROOT; };
 		4251B12F152D049B002F6199 /* ThemeStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThemeStyle.cpp; path = src/ThemeStyle.cpp; sourceTree = SOURCE_ROOT; };
 		4251B130152D049B002F6199 /* ThemeStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThemeStyle.h; path = src/ThemeStyle.h; sourceTree = SOURCE_ROOT; };
 		4251B130152D049B002F6199 /* ThemeStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThemeStyle.h; path = src/ThemeStyle.h; sourceTree = SOURCE_ROOT; };
@@ -2550,6 +2569,10 @@
 		5BB0823814C6FEB10019975F /* gameplay-main-android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gameplay-main-android.cpp"; path = "src/gameplay-main-android.cpp"; sourceTree = SOURCE_ROOT; };
 		5BB0823814C6FEB10019975F /* gameplay-main-android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gameplay-main-android.cpp"; path = "src/gameplay-main-android.cpp"; sourceTree = SOURCE_ROOT; };
 		5BB0823914C6FEB10019975F /* PlatformAndroid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformAndroid.cpp; path = src/PlatformAndroid.cpp; sourceTree = SOURCE_ROOT; };
 		5BB0823914C6FEB10019975F /* PlatformAndroid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformAndroid.cpp; path = src/PlatformAndroid.cpp; sourceTree = SOURCE_ROOT; };
 		5BB0823C14C6FEC40019975F /* Mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mouse.h; path = src/Mouse.h; sourceTree = SOURCE_ROOT; };
 		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>"; };
+		5BBAD0F115F5251D004C9639 /* lua_GestureGestureEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_GestureGestureEvent.cpp; sourceTree = "<group>"; };
+		5BBAD0F215F5251D004C9639 /* lua_GestureGestureEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_GestureGestureEvent.h; sourceTree = "<group>"; };
 		5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsGhostObject.cpp; path = src/PhysicsGhostObject.cpp; sourceTree = SOURCE_ROOT; };
 		5BBE143C1513E400003FB362 /* PhysicsGhostObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsGhostObject.cpp; path = src/PhysicsGhostObject.cpp; sourceTree = SOURCE_ROOT; };
 		5BBE143D1513E400003FB362 /* PhysicsGhostObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsGhostObject.h; path = src/PhysicsGhostObject.h; sourceTree = SOURCE_ROOT; };
 		5BBE143D1513E400003FB362 /* PhysicsGhostObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsGhostObject.h; path = src/PhysicsGhostObject.h; sourceTree = SOURCE_ROOT; };
 		5BC4E7D4150F8C3C00CBE1C0 /* res */ = {isa = PBXFileReference; lastKnownFileType = folder; path = res; sourceTree = "<group>"; };
 		5BC4E7D4150F8C3C00CBE1C0 /* res */ = {isa = PBXFileReference; lastKnownFileType = folder; path = res; sourceTree = "<group>"; };
@@ -2617,7 +2640,6 @@
 				5BAF202B152F2AF0003E2AC3 /* OpenGLES.framework in Frameworks */,
 				5BAF202B152F2AF0003E2AC3 /* OpenGLES.framework in Frameworks */,
 				5BAF202C152F2AF0003E2AC3 /* QuartzCore.framework in Frameworks */,
 				5BAF202C152F2AF0003E2AC3 /* QuartzCore.framework in Frameworks */,
 				5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */,
 				5BAF202D152F2AF0003E2AC3 /* UIKit.framework in Frameworks */,
-				5BAF201F152F2A6D003E2AC3 /* libz.dylib in Frameworks */,
 				5B04C57514BFCFE100EB0071 /* libbullet.a in Frameworks */,
 				5B04C57514BFCFE100EB0071 /* libbullet.a in Frameworks */,
 				5B04C57614BFCFE100EB0071 /* libogg.a in Frameworks */,
 				5B04C57614BFCFE100EB0071 /* libogg.a in Frameworks */,
 				5B04C57714BFCFE100EB0071 /* libvorbis.a in Frameworks */,
 				5B04C57714BFCFE100EB0071 /* libvorbis.a in Frameworks */,
@@ -2814,6 +2836,10 @@
 				42CD0E13147D8FF50000361E /* PhysicsSpringConstraint.cpp */,
 				42CD0E13147D8FF50000361E /* PhysicsSpringConstraint.cpp */,
 				42CD0E14147D8FF50000361E /* PhysicsSpringConstraint.h */,
 				42CD0E14147D8FF50000361E /* PhysicsSpringConstraint.h */,
 				42CD0E15147D8FF50000361E /* PhysicsSpringConstraint.inl */,
 				42CD0E15147D8FF50000361E /* PhysicsSpringConstraint.inl */,
+				421FBD4B1602818800A61BC0 /* PhysicsVehicle.cpp */,
+				421FBD4C1602818800A61BC0 /* PhysicsVehicle.h */,
+				421FBD4D1602818800A61BC0 /* PhysicsVehicleWheel.cpp */,
+				421FBD4E1602818800A61BC0 /* PhysicsVehicleWheel.h */,
 				42CD0E19147D8FF50000361E /* Platform.h */,
 				42CD0E19147D8FF50000361E /* Platform.h */,
 				5BB0823914C6FEB10019975F /* PlatformAndroid.cpp */,
 				5BB0823914C6FEB10019975F /* PlatformAndroid.cpp */,
 				42CD0E1C147D8FF50000361E /* PlatformWin32.cpp */,
 				42CD0E1C147D8FF50000361E /* PlatformWin32.cpp */,
@@ -3334,10 +3360,10 @@
 				42BCD38C15EFD0F300C0E076 /* lua_GamepadGamepadEvent.h */,
 				42BCD38C15EFD0F300C0E076 /* lua_GamepadGamepadEvent.h */,
 				42BCD38D15EFD0F300C0E076 /* lua_GameState.cpp */,
 				42BCD38D15EFD0F300C0E076 /* lua_GameState.cpp */,
 				42BCD38E15EFD0F300C0E076 /* lua_GameState.h */,
 				42BCD38E15EFD0F300C0E076 /* lua_GameState.h */,
-				424CD6EB15F6F349009CA1B8 /* lua_Gesture.cpp */,
-				424CD6EC15F6F349009CA1B8 /* lua_Gesture.h */,
-				424CD6ED15F6F349009CA1B8 /* lua_GestureGestureEvent.cpp */,
-				424CD6EE15F6F349009CA1B8 /* lua_GestureGestureEvent.h */,
+				5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */,
+				5BBAD0F015F5251D004C9639 /* lua_Gesture.h */,
+				5BBAD0F115F5251D004C9639 /* lua_GestureGestureEvent.cpp */,
+				5BBAD0F215F5251D004C9639 /* lua_GestureGestureEvent.h */,
 				42BCD38F15EFD0F300C0E076 /* lua_Global.cpp */,
 				42BCD38F15EFD0F300C0E076 /* lua_Global.cpp */,
 				42BCD39015EFD0F300C0E076 /* lua_Global.h */,
 				42BCD39015EFD0F300C0E076 /* lua_Global.h */,
 				42BCD39115EFD0F300C0E076 /* lua_Image.cpp */,
 				42BCD39115EFD0F300C0E076 /* lua_Image.cpp */,
@@ -3448,6 +3474,10 @@
 				42BCD3FA15EFD0F300C0E076 /* lua_PhysicsSocketConstraint.h */,
 				42BCD3FA15EFD0F300C0E076 /* lua_PhysicsSocketConstraint.h */,
 				42BCD3FB15EFD0F300C0E076 /* lua_PhysicsSpringConstraint.cpp */,
 				42BCD3FB15EFD0F300C0E076 /* lua_PhysicsSpringConstraint.cpp */,
 				42BCD3FC15EFD0F300C0E076 /* lua_PhysicsSpringConstraint.h */,
 				42BCD3FC15EFD0F300C0E076 /* lua_PhysicsSpringConstraint.h */,
+				421FBD581602827C00A61BC0 /* lua_PhysicsVehicle.cpp */,
+				421FBD591602827C00A61BC0 /* lua_PhysicsVehicle.h */,
+				421FBD5A1602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp */,
+				421FBD5B1602827C00A61BC0 /* lua_PhysicsVehicleWheel.h */,
 				42BCD3FD15EFD0F300C0E076 /* lua_Plane.cpp */,
 				42BCD3FD15EFD0F300C0E076 /* lua_Plane.cpp */,
 				42BCD3FE15EFD0F300C0E076 /* lua_Plane.h */,
 				42BCD3FE15EFD0F300C0E076 /* lua_Plane.h */,
 				42BCD3FF15EFD0F300C0E076 /* lua_Platform.cpp */,
 				42BCD3FF15EFD0F300C0E076 /* lua_Platform.cpp */,
@@ -4032,8 +4062,12 @@
 				42BCD6C615EFD0F300C0E076 /* lua_VertexFormatElement.h in Headers */,
 				42BCD6C615EFD0F300C0E076 /* lua_VertexFormatElement.h in Headers */,
 				42BCD6CA15EFD0F300C0E076 /* lua_VertexFormatUsage.h in Headers */,
 				42BCD6CA15EFD0F300C0E076 /* lua_VertexFormatUsage.h in Headers */,
 				42BCD6CE15EFD0F300C0E076 /* lua_VerticalLayout.h in Headers */,
 				42BCD6CE15EFD0F300C0E076 /* lua_VerticalLayout.h in Headers */,
-				424CD6F115F6F349009CA1B8 /* lua_Gesture.h in Headers */,
-				424CD6F515F6F349009CA1B8 /* lua_GestureGestureEvent.h in Headers */,
+				5BBAD0F515F5251E004C9639 /* lua_Gesture.h in Headers */,
+				5BBAD0F915F5251E004C9639 /* lua_GestureGestureEvent.h in Headers */,
+				421FBD511602818800A61BC0 /* PhysicsVehicle.h in Headers */,
+				421FBD551602818800A61BC0 /* PhysicsVehicleWheel.h in Headers */,
+				421FBD5E1602827C00A61BC0 /* lua_PhysicsVehicle.h in Headers */,
+				421FBD621602827C00A61BC0 /* lua_PhysicsVehicleWheel.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -4455,8 +4489,12 @@
 				42BCD6C715EFD0F300C0E076 /* lua_VertexFormatElement.h in Headers */,
 				42BCD6C715EFD0F300C0E076 /* lua_VertexFormatElement.h in Headers */,
 				42BCD6CB15EFD0F300C0E076 /* lua_VertexFormatUsage.h in Headers */,
 				42BCD6CB15EFD0F300C0E076 /* lua_VertexFormatUsage.h in Headers */,
 				42BCD6CF15EFD0F300C0E076 /* lua_VerticalLayout.h in Headers */,
 				42BCD6CF15EFD0F300C0E076 /* lua_VerticalLayout.h in Headers */,
-				424CD6F215F6F349009CA1B8 /* lua_Gesture.h in Headers */,
-				424CD6F615F6F349009CA1B8 /* lua_GestureGestureEvent.h in Headers */,
+				5BBAD0F615F5251E004C9639 /* lua_Gesture.h in Headers */,
+				5BBAD0FA15F5251E004C9639 /* lua_GestureGestureEvent.h in Headers */,
+				421FBD521602818800A61BC0 /* PhysicsVehicle.h in Headers */,
+				421FBD561602818800A61BC0 /* PhysicsVehicleWheel.h in Headers */,
+				421FBD5F1602827C00A61BC0 /* lua_PhysicsVehicle.h in Headers */,
+				421FBD631602827C00A61BC0 /* lua_PhysicsVehicleWheel.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -4938,8 +4976,12 @@
 				42BCD6CC15EFD0F300C0E076 /* lua_VerticalLayout.cpp in Sources */,
 				42BCD6CC15EFD0F300C0E076 /* lua_VerticalLayout.cpp in Sources */,
 				42BCD6D015EFD0F300C0E076 /* PlatformLinux.cpp in Sources */,
 				42BCD6D015EFD0F300C0E076 /* PlatformLinux.cpp in Sources */,
 				42BCD6D415EFD14800C0E076 /* gameplay-main-linux.cpp in Sources */,
 				42BCD6D415EFD14800C0E076 /* gameplay-main-linux.cpp in Sources */,
-				424CD6EF15F6F349009CA1B8 /* lua_Gesture.cpp in Sources */,
-				424CD6F315F6F349009CA1B8 /* lua_GestureGestureEvent.cpp in Sources */,
+				5BBAD0F315F5251E004C9639 /* lua_Gesture.cpp in Sources */,
+				5BBAD0F715F5251E004C9639 /* lua_GestureGestureEvent.cpp in Sources */,
+				421FBD4F1602818800A61BC0 /* PhysicsVehicle.cpp in Sources */,
+				421FBD531602818800A61BC0 /* PhysicsVehicleWheel.cpp in Sources */,
+				421FBD5C1602827C00A61BC0 /* lua_PhysicsVehicle.cpp in Sources */,
+				421FBD601602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -5357,8 +5399,12 @@
 				42BCD6CD15EFD0F300C0E076 /* lua_VerticalLayout.cpp in Sources */,
 				42BCD6CD15EFD0F300C0E076 /* lua_VerticalLayout.cpp in Sources */,
 				42BCD6D115EFD0F300C0E076 /* PlatformLinux.cpp in Sources */,
 				42BCD6D115EFD0F300C0E076 /* PlatformLinux.cpp in Sources */,
 				42BCD6D515EFD14800C0E076 /* gameplay-main-linux.cpp in Sources */,
 				42BCD6D515EFD14800C0E076 /* gameplay-main-linux.cpp in Sources */,
-				424CD6F015F6F349009CA1B8 /* lua_Gesture.cpp in Sources */,
-				424CD6F415F6F349009CA1B8 /* lua_GestureGestureEvent.cpp in Sources */,
+				5BBAD0F415F5251E004C9639 /* lua_Gesture.cpp in Sources */,
+				5BBAD0F815F5251E004C9639 /* lua_GestureGestureEvent.cpp in Sources */,
+				421FBD501602818800A61BC0 /* PhysicsVehicle.cpp in Sources */,
+				421FBD541602818800A61BC0 /* PhysicsVehicleWheel.cpp in Sources */,
+				421FBD5D1602827C00A61BC0 /* lua_PhysicsVehicle.cpp in Sources */,
+				421FBD611602827C00A61BC0 /* lua_PhysicsVehicleWheel.cpp in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};

+ 2 - 2
gameplay/src/Animation.cpp

@@ -344,7 +344,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     normalizedKeyTimes[i] = 1.0f;
     normalizedKeyTimes[i] = 1.0f;
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);
 
 
-    SAFE_DELETE(normalizedKeyTimes);
+    SAFE_DELETE_ARRAY(normalizedKeyTimes);
 
 
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     curve->release();
     curve->release();
@@ -386,7 +386,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
     normalizedKeyTimes[i] = 1.0f;
     normalizedKeyTimes[i] = 1.0f;
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);
     curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);
 
 
-    SAFE_DELETE(normalizedKeyTimes);
+    SAFE_DELETE_ARRAY(normalizedKeyTimes);
 
 
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     Channel* channel = new Channel(this, target, propertyId, curve, duration);
     curve->release();
     curve->release();

+ 4 - 4
gameplay/src/AnimationTarget.cpp

@@ -261,10 +261,10 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
         animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
         animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve);
     }
     }
 
 
-    SAFE_DELETE(keyOut);
-    SAFE_DELETE(keyIn);
-    SAFE_DELETE(keyValues);
-    SAFE_DELETE(keyTimes);
+    SAFE_DELETE_ARRAY(keyOut);
+    SAFE_DELETE_ARRAY(keyIn);
+    SAFE_DELETE_ARRAY(keyValues);
+    SAFE_DELETE_ARRAY(keyTimes);
 
 
     Properties* pClip = animationProperties->getNextNamespace();
     Properties* pClip = animationProperties->getNextNamespace();
     if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
     if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)

+ 1 - 1
gameplay/src/AudioBuffer.cpp

@@ -101,7 +101,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
         goto cleanup;
         goto cleanup;
     }
     }
 
 
-	//NOTE: loadOgg actually sets this null, so it is expected
+    //NOTE: loadOgg actually sets this null, so it is expected
     if (file)    
     if (file)    
         fclose(file);
         fclose(file);
 
 

+ 1 - 1
gameplay/src/Base.h

@@ -201,7 +201,7 @@ using std::va_list;
         #define USE_NEON
         #define USE_NEON
     #endif
     #endif
 #elif __ANDROID__
 #elif __ANDROID__
-	#include <EGL/egl.h>
+    #include <EGL/egl.h>
     #include <GLES2/gl2.h>
     #include <GLES2/gl2.h>
     #include <GLES2/gl2ext.h>
     #include <GLES2/gl2ext.h>
     extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
     extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;

+ 10 - 10
gameplay/src/BoundingBox.h

@@ -39,11 +39,11 @@ public:
     /**
     /**
      * Constructs a new bounding box from the specified values.
      * Constructs a new bounding box from the specified values.
      * 
      * 
-     * @param minX The x coordinate of the minimum point of the bounding box.
-     * @param minY The y coordinate of the minimum point of the bounding box.
-     * @param minZ The z coordinate of the minimum point of the bounding box.
-     * @param maxX The x coordinate of the maximum point of the bounding box.
-     * @param maxY The y coordinate of the maximum point of the bounding box.
+     * @param minX The x coordinate of the minimum point of the bounding box.
+     * @param minY The y coordinate of the minimum point of the bounding box.
+     * @param minZ The z coordinate of the minimum point of the bounding box.
+     * @param maxX The x coordinate of the maximum point of the bounding box.
+     * @param maxY The y coordinate of the maximum point of the bounding box.
      * @param maxZ The z coordinate of the maximum point of the bounding box.
      * @param maxZ The z coordinate of the maximum point of the bounding box.
      */
      */
     BoundingBox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
     BoundingBox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
@@ -178,11 +178,11 @@ public:
     /**
     /**
      * Sets this bounding box to the specified values.
      * Sets this bounding box to the specified values.
      * 
      * 
-     * @param minX The x coordinate of the minimum point of the bounding box.
-     * @param minY The y coordinate of the minimum point of the bounding box.
-     * @param minZ The z coordinate of the minimum point of the bounding box.
-     * @param maxX The x coordinate of the maximum point of the bounding box.
-     * @param maxY The y coordinate of the maximum point of the bounding box.
+     * @param minX The x coordinate of the minimum point of the bounding box.
+     * @param minY The y coordinate of the minimum point of the bounding box.
+     * @param minZ The z coordinate of the minimum point of the bounding box.
+     * @param maxX The x coordinate of the maximum point of the bounding box.
+     * @param maxY The y coordinate of the maximum point of the bounding box.
      * @param maxZ The z coordinate of the maximum point of the bounding box.
      * @param maxZ The z coordinate of the maximum point of the bounding box.
      */
      */
     void set(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
     void set(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);

+ 26 - 26
gameplay/src/Button.cpp

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

+ 9 - 9
gameplay/src/CheckBox.cpp

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

+ 69 - 69
gameplay/src/Container.cpp

@@ -730,26 +730,26 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
     switch(evt)
     switch(evt)
     {
     {
     case Touch::TOUCH_PRESS:
     case Touch::TOUCH_PRESS:
-    	if (_contactIndex == INVALID_CONTACT_INDEX)
-    	{
-    		_contactIndex = (int) contactIndex;
-    		_contactIndices++;
-			_scrollingLastX = _scrollingFirstX = x;
-			_scrollingLastY = _scrollingFirstY = y;
-			_scrollingVelocity.set(0, 0);
-			_scrolling = true;
-			_scrollingStartTimeX = _scrollingStartTimeY = 0;
-
-			if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
-			{
-				_scrollBarOpacityClip->stop();
-				_scrollBarOpacityClip = NULL;
-			}
-			_scrollBarOpacity = 1.0f;
+        if (_contactIndex == INVALID_CONTACT_INDEX)
+        {
+            _contactIndex = (int) contactIndex;
+            _contactIndices++;
+            _scrollingLastX = _scrollingFirstX = x;
+            _scrollingLastY = _scrollingFirstY = y;
+            _scrollingVelocity.set(0, 0);
+            _scrolling = true;
+            _scrollingStartTimeX = _scrollingStartTimeY = 0;
+
+            if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
+            {
+                _scrollBarOpacityClip->stop();
+                _scrollBarOpacityClip = NULL;
+            }
+            _scrollBarOpacity = 1.0f;
             _dirty = true;
             _dirty = true;
-			return _consumeInputEvents;
-    	}
-		break;
+            return _consumeInputEvents;
+        }
+        break;
     case Touch::TOUCH_MOVE:
     case Touch::TOUCH_MOVE:
         if (_scrolling && _contactIndex == (int) contactIndex)
         if (_scrolling && _contactIndex == (int) contactIndex)
         {
         {
@@ -814,58 +814,58 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         break;
         break;
 
 
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
-    	if (_contactIndex == (int) contactIndex)
-    	{
-    		_contactIndex = INVALID_CONTACT_INDEX;
-    		_contactIndices--;
-			_scrolling = false;
-			double gameTime = Game::getAbsoluteTime();
-			float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
-			if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
-			{
-				_scrollingVelocity.set(0, 0);
-				_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+        if (_contactIndex == (int) contactIndex)
+        {
+            _contactIndex = INVALID_CONTACT_INDEX;
+            _contactIndices--;
+            _scrolling = false;
+            double gameTime = Game::getAbsoluteTime();
+            float timeSinceLastMove = (float)(gameTime - _scrollingLastTime);
+            if (timeSinceLastMove > SCROLL_INERTIA_DELAY)
+            {
+                _scrollingVelocity.set(0, 0);
+                _scrollingMouseVertically = _scrollingMouseHorizontally = false;
                 _dirty = true;
                 _dirty = true;
-				return _consumeInputEvents;
-			}
-
-			int dx = _scrollingLastX - _scrollingFirstX;
-			int dy = _scrollingLastY - _scrollingFirstY;
-
-			float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
-			float elapsedSecsX = timeTakenX * 0.001f;
-			float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
-			float elapsedSecsY = timeTakenY * 0.001f;
-
-			float vx = dx;
-			float vy = dy;
-			if (elapsedSecsX > 0)
-				vx = (float)dx / elapsedSecsX;
-			if (elapsedSecsY > 0)
-				vy = (float)dy / elapsedSecsY;
-
-			if (_scrollingMouseVertically)
-			{
-				float yRatio = _totalHeight / _absoluteBounds.height;
-				vy *= yRatio;
-				_scrollingVelocity.set(0, -vy);
-			}
-			else if (_scrollingMouseHorizontally)
-			{
-				float xRatio = _totalWidth / _absoluteBounds.width;
-				vx *= xRatio;
-				_scrollingVelocity.set(-vx, 0);
-			}
-			else
-			{
-				_scrollingVelocity.set(vx, vy);
-			}
-
-			_scrollingMouseVertically = _scrollingMouseHorizontally = false;
+                return _consumeInputEvents;
+            }
+
+            int dx = _scrollingLastX - _scrollingFirstX;
+            int dy = _scrollingLastY - _scrollingFirstY;
+
+            float timeTakenX = (float)(gameTime - _scrollingStartTimeX);
+            float elapsedSecsX = timeTakenX * 0.001f;
+            float timeTakenY = (float)(gameTime - _scrollingStartTimeY);
+            float elapsedSecsY = timeTakenY * 0.001f;
+
+            float vx = dx;
+            float vy = dy;
+            if (elapsedSecsX > 0)
+                vx = (float)dx / elapsedSecsX;
+            if (elapsedSecsY > 0)
+                vy = (float)dy / elapsedSecsY;
+
+            if (_scrollingMouseVertically)
+            {
+                float yRatio = _totalHeight / _absoluteBounds.height;
+                vy *= yRatio;
+                _scrollingVelocity.set(0, -vy);
+            }
+            else if (_scrollingMouseHorizontally)
+            {
+                float xRatio = _totalWidth / _absoluteBounds.width;
+                vx *= xRatio;
+                _scrollingVelocity.set(-vx, 0);
+            }
+            else
+            {
+                _scrollingVelocity.set(vx, vy);
+            }
+
+            _scrollingMouseVertically = _scrollingMouseHorizontally = false;
             _dirty = true;
             _dirty = true;
-			return _consumeInputEvents;
-    	}
-    	break;
+            return _consumeInputEvents;
+        }
+        break;
     }
     }
 
 
     return false;
     return false;

+ 11 - 11
gameplay/src/Control.cpp

@@ -744,20 +744,20 @@ bool Control::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int conta
     case Touch::TOUCH_RELEASE:
     case Touch::TOUCH_RELEASE:
         if (_contactIndex == (int)contactIndex)
         if (_contactIndex == (int)contactIndex)
         {
         {
-			_contactIndex = INVALID_CONTACT_INDEX;
+            _contactIndex = INVALID_CONTACT_INDEX;
 
 
-			// Always trigger Listener::RELEASE
-			notifyListeners(Listener::RELEASE);
+            // Always trigger Listener::RELEASE
+            notifyListeners(Listener::RELEASE);
 
 
-			// Only trigger Listener::CLICK if both PRESS and RELEASE took place within the control's bounds.
-			if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-				y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-			{
-				// Leave this control in the FOCUS state.
-				notifyListeners(Listener::CLICK);
-			}
+            // Only trigger Listener::CLICK if both PRESS and RELEASE took place within the control's bounds.
+            if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+            {
+                // Leave this control in the FOCUS state.
+                notifyListeners(Listener::CLICK);
+            }
 
 
-			return _consumeInputEvents;
+            return _consumeInputEvents;
         }
         }
         break;
         break;
     }
     }

+ 16 - 2
gameplay/src/FileSystem.cpp

@@ -219,7 +219,14 @@ bool FileSystem::fileExists(const char* filePath)
         fullPath += "../../gameplay/";
         fullPath += "../../gameplay/";
         fullPath += filePath;
         fullPath += filePath;
         
         
-        return stat(fullPath.c_str(), &s) == 0;
+        int result = stat(fullPath.c_str(), &s);
+        if (result != 0)
+        {
+            fullPath = __resourcePath;
+            fullPath += "../gameplay/";
+            fullPath += filePath;
+            return stat(fullPath.c_str(), &s) == 0;
+        }
     }
     }
     return true;
     return true;
 #else
 #else
@@ -248,6 +255,13 @@ FILE* FileSystem::openFile(const char* path, const char* mode)
         fullPath += path;
         fullPath += path;
         
         
         fp = fopen(fullPath.c_str(), mode);
         fp = fopen(fullPath.c_str(), mode);
+        if (!fp)
+        {
+            fullPath = __resourcePath;
+            fullPath += "../gameplay/";
+            fullPath += path;
+            fp = fopen(fullPath.c_str(), mode);
+        }
     }
     }
 #endif
 #endif
 
 
@@ -335,7 +349,7 @@ void createFileFromAsset(const char* path)
     std::string directoryPath = fullPath.substr(0, fullPath.rfind('/'));
     std::string directoryPath = fullPath.substr(0, fullPath.rfind('/'));
     struct stat s;
     struct stat s;
     if (stat(directoryPath.c_str(), &s) != 0)
     if (stat(directoryPath.c_str(), &s) != 0)
-        makepath(directoryPath.c_str(), 0777);
+        makepath(directoryPath, 0777);
 
 
     // To ensure that the files on the file system corresponding to the assets in the APK bundle
     // To ensure that the files on the file system corresponding to the assets in the APK bundle
     // are always up to date (and in sync), we copy them from the APK to the file system once
     // are always up to date (and in sync), we copy them from the APK to the file system once

+ 5 - 8
gameplay/src/Font.cpp

@@ -139,11 +139,7 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
 
 
     // Create batch for the font.
     // Create batch for the font.
     SpriteBatch* batch = SpriteBatch::create(texture, __fontEffect, 128);
     SpriteBatch* batch = SpriteBatch::create(texture, __fontEffect, 128);
-
-    // Add linear filtering for better font quality.
-    Texture::Sampler* sampler = batch->getSampler();
-    sampler->setFilterMode(Texture::LINEAR, Texture::LINEAR);
-
+    
     // Release __fontEffect since the SpriteBatch keeps a reference to it
     // Release __fontEffect since the SpriteBatch keeps a reference to it
     SAFE_RELEASE(__fontEffect);
     SAFE_RELEASE(__fontEffect);
 
 
@@ -153,6 +149,10 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
         return NULL;
         return NULL;
     }
     }
 
 
+    // Add linear filtering for better font quality.
+    Texture::Sampler* sampler = batch->getSampler();
+    sampler->setFilterMode(Texture::LINEAR, Texture::LINEAR);
+
     // Increase the ref count of the texture to retain it.
     // Increase the ref count of the texture to retain it.
     texture->addRef();
     texture->addRef();
 
 
@@ -193,7 +193,6 @@ Font::Text* Font::createText(const char* text, const Rectangle& area, const Vect
         size = _size;
         size = _size;
     GP_ASSERT(_size);
     GP_ASSERT(_size);
     float scale = (float)size / _size;
     float scale = (float)size / _size;
-    const int length = strlen(text);
     int yPos = area.y;
     int yPos = area.y;
     const float areaHeight = area.height - size;
     const float areaHeight = area.height - size;
     std::vector<int> xPositions;
     std::vector<int> xPositions;
@@ -554,7 +553,6 @@ void Font::drawText(const char* text, const Rectangle& area, const Vector4& colo
         size = _size;
         size = _size;
     GP_ASSERT(_size);
     GP_ASSERT(_size);
     float scale = (float)size / _size;
     float scale = (float)size / _size;
-    const int length = strlen(text);
     int yPos = area.y;
     int yPos = area.y;
     const float areaHeight = area.height - size;
     const float areaHeight = area.height - size;
     std::vector<int> xPositions;
     std::vector<int> xPositions;
@@ -1327,7 +1325,6 @@ int Font::getIndexOrLocation(const char* text, const Rectangle& area, unsigned i
 
 
     // Essentially need to measure text until we reach inLocation.
     // Essentially need to measure text until we reach inLocation.
     float scale = (float)size / _size;
     float scale = (float)size / _size;
-    const int length = strlen(text);
     int yPos = area.y;
     int yPos = area.y;
     const float areaHeight = area.height - size;
     const float areaHeight = area.height - size;
     std::vector<int> xPositions;
     std::vector<int> xPositions;

+ 1 - 1
gameplay/src/Form.cpp

@@ -40,7 +40,7 @@ static std::vector<Form*> __forms;
 
 
 Form::Form() : _theme(NULL), _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL), _nodeQuad(NULL), _nodeMaterial(NULL) , _u2(0), _v1(0)
 Form::Form() : _theme(NULL), _frameBuffer(NULL), _spriteBatch(NULL), _node(NULL), _nodeQuad(NULL), _nodeMaterial(NULL) , _u2(0), _v1(0)
 {
 {
-	_consumeInputEvents = false;
+    _consumeInputEvents = false;
 }
 }
 
 
 Form::~Form()
 Form::~Form()

+ 5 - 0
gameplay/src/Game.cpp

@@ -456,6 +456,11 @@ void Game::unregisterGesture(Gesture::GestureEvent evt)
     Platform::unregisterGesture(evt);
     Platform::unregisterGesture(evt);
 }
 }
 
 
+bool Game::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return Platform::isGestureRegistered(evt);
+}
+
 void Game::gestureSwipeEvent(int x, int y, int direction)
 void Game::gestureSwipeEvent(int x, int y, int direction)
 {
 {
 }
 }

+ 16 - 2
gameplay/src/Game.h

@@ -174,6 +174,13 @@ public:
      * @return The game window height.
      * @return The game window height.
      */
      */
     inline unsigned int getHeight() const;
     inline unsigned int getHeight() const;
+    
+    /**
+     * Gets the aspect ratio of the window. (width / height)
+     * 
+     * @return The aspect ratio of the window.
+     */
+    inline float getAspectRatio() const;
 
 
     /**
     /**
      * Gets the game current viewport.
      * Gets the game current viewport.
@@ -183,7 +190,7 @@ public:
     inline const Rectangle& getViewport() const;
     inline const Rectangle& getViewport() const;
 
 
     /**
     /**
-     * Set the game current viewport.
+     * Sets the game current viewport.
      *
      *
      * The x, y, width and height of the viewport must all be positive.
      * The x, y, width and height of the viewport must all be positive.
      *
      *
@@ -354,7 +361,7 @@ public:
     inline bool isCursorVisible();
     inline bool isCursorVisible();
 
 
     /**
     /**
-     * Determines whether a specific gesture event is supported.
+     * Determines whether a specified gesture event is supported.
      *
      *
      * Use Gesture::GESTURE_ANY_SUPPORTED to test if one or more gesture events are supported.
      * Use Gesture::GESTURE_ANY_SUPPORTED to test if one or more gesture events are supported.
      *
      *
@@ -389,6 +396,13 @@ public:
      */
      */
     void unregisterGesture(Gesture::GestureEvent evt);
     void unregisterGesture(Gesture::GestureEvent evt);
 
 
+    /**
+     * Determines whether a specified gesture event is registered to receive event callbacks.
+     *
+     * @return true if the specified gesture event is registered; false of not registered.
+     */
+    bool isGestureRegistered(Gesture::GestureEvent evt);
+
     /**
     /**
      * Gesture callback on Gesture::SWIPE events.
      * Gesture callback on Gesture::SWIPE events.
      *
      *

+ 5 - 0
gameplay/src/Game.inl

@@ -29,6 +29,11 @@ inline unsigned int Game::getHeight() const
     return _height;
     return _height;
 }
 }
 
 
+inline float Game::getAspectRatio() const
+{
+    return (float)_width / (float)_height;
+}
+
 inline const Rectangle& Game::getViewport() const
 inline const Rectangle& Game::getViewport() const
 {
 {
     return _viewport;
     return _viewport;

+ 2 - 2
gameplay/src/Gesture.h

@@ -16,9 +16,9 @@ public:
      */
      */
     enum GestureEvent
     enum GestureEvent
     {
     {
-        GESTURE_SWIPE = 0,
+        GESTURE_TAP = 0,
+        GESTURE_SWIPE,
         GESTURE_PINCH,
         GESTURE_PINCH,
-        GESTURE_TAP,
         GESTURE_ANY_SUPPORTED = -1,
         GESTURE_ANY_SUPPORTED = -1,
     };
     };
 
 

+ 4 - 4
gameplay/src/Joystick.cpp

@@ -4,7 +4,7 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-Joystick::Joystick() : _relative(true), _innerSize(NULL), _outerSize(NULL)
+Joystick::Joystick() : _radius(1.0f), _relative(true), _innerSize(NULL), _outerSize(NULL)
 {
 {
 }
 }
 
 
@@ -47,6 +47,7 @@ void Joystick::initialize(Theme::Style* style, Properties* properties)
         return;
         return;
     }
     }
     _radius = properties->getFloat("radius");
     _radius = properties->getFloat("radius");
+    GP_ASSERT(_radius != 0.0f);
 
 
     if (properties->exists("relative"))
     if (properties->exists("relative"))
     {
     {
@@ -95,7 +96,6 @@ void Joystick::initialize(Theme::Style* style, Properties* properties)
         if (inner)
         if (inner)
         {
         {
             const Rectangle& rect = inner->getRegion();
             const Rectangle& rect = inner->getRegion();
-            float radiusx2 = _radius * 2;;
             _screenRegion.width = rect.width;
             _screenRegion.width = rect.width;
             _screenRegion.height = rect.height;
             _screenRegion.height = rect.height;
         }
         }
@@ -147,7 +147,7 @@ bool Joystick::touchEvent(Touch::TouchEvent touchEvent, int x, int y, unsigned i
 
 
                 // If the displacement is greater than the radius, then cap the displacement to the
                 // If the displacement is greater than the radius, then cap the displacement to the
                 // radius.
                 // radius.
-                
+                
                 Vector2 value;
                 Vector2 value;
                 if ((fabs(_displacement.x) > _radius) || (fabs(_displacement.y) > _radius))
                 if ((fabs(_displacement.x) > _radius) || (fabs(_displacement.y) > _radius))
                 {
                 {
@@ -183,7 +183,7 @@ bool Joystick::touchEvent(Touch::TouchEvent touchEvent, int x, int y, unsigned i
                 float dy = -(y - ((_relative) ? _screenRegion.y - _bounds.y : 0.0f) - _screenRegion.height * 0.5f);
                 float dy = -(y - ((_relative) ? _screenRegion.y - _bounds.y : 0.0f) - _screenRegion.height * 0.5f);
             
             
                 _displacement.set(dx, dy);
                 _displacement.set(dx, dy);
-            
+            
                 Vector2 value;
                 Vector2 value;
                 if ((fabs(_displacement.x) > _radius) || (fabs(_displacement.y) > _radius))
                 if ((fabs(_displacement.x) > _radius) || (fabs(_displacement.y) > _radius))
                 {
                 {

+ 1 - 4
gameplay/src/Material.cpp

@@ -21,10 +21,7 @@ Material::~Material()
     for (unsigned int i = 0, count = _techniques.size(); i < count; ++i)
     for (unsigned int i = 0, count = _techniques.size(); i < count; ++i)
     {
     {
         Technique* technique = _techniques[i];
         Technique* technique = _techniques[i];
-        if (technique)
-        {
-            SAFE_RELEASE(technique);
-        }
+        SAFE_RELEASE(technique);
     }
     }
 }
 }
 
 

+ 7 - 0
gameplay/src/MaterialParameter.cpp

@@ -68,6 +68,13 @@ const char* MaterialParameter::getName() const
     return _name.c_str();
     return _name.c_str();
 }
 }
 
 
+Texture::Sampler* MaterialParameter::getSampler() const
+{
+    if (_type == MaterialParameter::SAMPLER)
+        return const_cast<Texture::Sampler*>(_value.samplerValue);
+    return NULL;
+}
+
 void MaterialParameter::setValue(float value)
 void MaterialParameter::setValue(float value)
 {
 {
     clearValue();
     clearValue();

+ 7 - 0
gameplay/src/MaterialParameter.h

@@ -44,6 +44,13 @@ public:
      */
      */
     const char* getName() const;
     const char* getName() const;
 
 
+    /**
+     * Returns the texture sampler or NULL if this MaterialParameter is not a sampler type.
+     * 
+     * @return The texture sampler or NULL if this MaterialParameter is not a sampler type.
+     */
+    Texture::Sampler* getSampler() const;
+
     /**
     /**
      * Sets the value of this parameter to a float value.
      * Sets the value of this parameter to a float value.
      */
      */

+ 13 - 13
gameplay/src/MathUtil.h

@@ -8,32 +8,32 @@ namespace gameplay
  */
  */
 class MathUtil
 class MathUtil
 {
 {
-	friend class Matrix;
-	friend class Vector3;
+    friend class Matrix;
+    friend class Vector3;
 
 
 private:
 private:
 
 
-	inline static void addMatrix(const float* m, float scalar, float* dst);
+    inline static void addMatrix(const float* m, float scalar, float* dst);
 
 
-	inline static void addMatrix(const float* m1, const float* m2, float* dst);
+    inline static void addMatrix(const float* m1, const float* m2, float* dst);
 
 
-	inline static void subtractMatrix(const float* m1, const float* m2, float* dst);
+    inline static void subtractMatrix(const float* m1, const float* m2, float* dst);
 
 
-	inline static void multiplyMatrix(const float* m, float scalar, float* dst);
+    inline static void multiplyMatrix(const float* m, float scalar, float* dst);
 
 
-	inline static void multiplyMatrix(const float* m1, const float* m2, float* dst);
+    inline static void multiplyMatrix(const float* m1, const float* m2, float* dst);
 
 
-	inline static void negateMatrix(const float* m, float* dst);
+    inline static void negateMatrix(const float* m, float* dst);
 
 
-	inline static void transposeMatrix(const float* m, float* dst);
+    inline static void transposeMatrix(const float* m, float* dst);
 
 
-	inline static void transformVector4(const float* m, float x, float y, float z, float w, float* dst);
+    inline static void transformVector4(const float* m, float x, float y, float z, float w, float* dst);
 
 
-	inline static void transformVector4(const float* m, const float* v, float* dst);
+    inline static void transformVector4(const float* m, const float* v, float* dst);
 
 
-	inline static void crossVector3(const float* v1, const float* v2, float* dst);
+    inline static void crossVector3(const float* v1, const float* v2, float* dst);
 
 
-	MathUtil();
+    MathUtil();
 };
 };
 
 
 }
 }

+ 123 - 123
gameplay/src/MathUtil.inl

@@ -3,173 +3,173 @@ namespace gameplay
 
 
 inline void MathUtil::addMatrix(const float* m, float scalar, float* dst)
 inline void MathUtil::addMatrix(const float* m, float scalar, float* dst)
 {
 {
-	dst[0]  = m[0]  + scalar;
-	dst[1]  = m[1]  + scalar;
-	dst[2]  = m[2]  + scalar;
-	dst[3]  = m[3]  + scalar;
-	dst[4]  = m[4]  + scalar;
-	dst[5]  = m[5]  + scalar;
-	dst[6]  = m[6]  + scalar;
-	dst[7]  = m[7]  + scalar;
-	dst[8]  = m[8]  + scalar;
-	dst[9]  = m[9]  + scalar;
-	dst[10] = m[10] + scalar;
-	dst[11] = m[11] + scalar;
-	dst[12] = m[12] + scalar;
-	dst[13] = m[13] + scalar;
-	dst[14] = m[14] + scalar;
-	dst[15] = m[15] + scalar;
+    dst[0]  = m[0]  + scalar;
+    dst[1]  = m[1]  + scalar;
+    dst[2]  = m[2]  + scalar;
+    dst[3]  = m[3]  + scalar;
+    dst[4]  = m[4]  + scalar;
+    dst[5]  = m[5]  + scalar;
+    dst[6]  = m[6]  + scalar;
+    dst[7]  = m[7]  + scalar;
+    dst[8]  = m[8]  + scalar;
+    dst[9]  = m[9]  + scalar;
+    dst[10] = m[10] + scalar;
+    dst[11] = m[11] + scalar;
+    dst[12] = m[12] + scalar;
+    dst[13] = m[13] + scalar;
+    dst[14] = m[14] + scalar;
+    dst[15] = m[15] + scalar;
 }
 }
 
 
 inline void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	dst[0]  = m1[0]  + m2[0];
-	dst[1]  = m1[1]  + m2[1];
-	dst[2]  = m1[2]  + m2[2];
-	dst[3]  = m1[3]  + m2[3];
-	dst[4]  = m1[4]  + m2[4];
-	dst[5]  = m1[5]  + m2[5];
-	dst[6]  = m1[6]  + m2[6];
-	dst[7]  = m1[7]  + m2[7];
-	dst[8]  = m1[8]  + m2[8];
-	dst[9]  = m1[9]  + m2[9];
-	dst[10] = m1[10] + m2[10];
-	dst[11] = m1[11] + m2[11];
-	dst[12] = m1[12] + m2[12];
-	dst[13] = m1[13] + m2[13];
-	dst[14] = m1[14] + m2[14];
-	dst[15] = m1[15] + m2[15];
+    dst[0]  = m1[0]  + m2[0];
+    dst[1]  = m1[1]  + m2[1];
+    dst[2]  = m1[2]  + m2[2];
+    dst[3]  = m1[3]  + m2[3];
+    dst[4]  = m1[4]  + m2[4];
+    dst[5]  = m1[5]  + m2[5];
+    dst[6]  = m1[6]  + m2[6];
+    dst[7]  = m1[7]  + m2[7];
+    dst[8]  = m1[8]  + m2[8];
+    dst[9]  = m1[9]  + m2[9];
+    dst[10] = m1[10] + m2[10];
+    dst[11] = m1[11] + m2[11];
+    dst[12] = m1[12] + m2[12];
+    dst[13] = m1[13] + m2[13];
+    dst[14] = m1[14] + m2[14];
+    dst[15] = m1[15] + m2[15];
 }
 }
 
 
 inline void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	dst[0]  = m1[0]  - m2[0];
-	dst[1]  = m1[1]  - m2[1];
-	dst[2]  = m1[2]  - m2[2];
-	dst[3]  = m1[3]  - m2[3];
-	dst[4]  = m1[4]  - m2[4];
-	dst[5]  = m1[5]  - m2[5];
-	dst[6]  = m1[6]  - m2[6];
-	dst[7]  = m1[7]  - m2[7];
-	dst[8]  = m1[8]  - m2[8];
-	dst[9]  = m1[9]  - m2[9];
-	dst[10] = m1[10] - m2[10];
-	dst[11] = m1[11] - m2[11];
-	dst[12] = m1[12] - m2[12];
-	dst[13] = m1[13] - m2[13];
-	dst[14] = m1[14] - m2[14];
-	dst[15] = m1[15] - m2[15];
+    dst[0]  = m1[0]  - m2[0];
+    dst[1]  = m1[1]  - m2[1];
+    dst[2]  = m1[2]  - m2[2];
+    dst[3]  = m1[3]  - m2[3];
+    dst[4]  = m1[4]  - m2[4];
+    dst[5]  = m1[5]  - m2[5];
+    dst[6]  = m1[6]  - m2[6];
+    dst[7]  = m1[7]  - m2[7];
+    dst[8]  = m1[8]  - m2[8];
+    dst[9]  = m1[9]  - m2[9];
+    dst[10] = m1[10] - m2[10];
+    dst[11] = m1[11] - m2[11];
+    dst[12] = m1[12] - m2[12];
+    dst[13] = m1[13] - m2[13];
+    dst[14] = m1[14] - m2[14];
+    dst[15] = m1[15] - m2[15];
 }
 }
 
 
 inline void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
 inline void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
 {
 {
-	dst[0]  = m[0]  * scalar;
-	dst[1]  = m[1]  * scalar;
-	dst[2]  = m[2]  * scalar;
-	dst[3]  = m[3]  * scalar;
-	dst[4]  = m[4]  * scalar;
-	dst[5]  = m[5]  * scalar;
-	dst[6]  = m[6]  * scalar;
-	dst[7]  = m[7]  * scalar;
-	dst[8]  = m[8]  * scalar;
-	dst[9]  = m[9]  * scalar;
-	dst[10] = m[10] * scalar;
-	dst[11] = m[11] * scalar;
-	dst[12] = m[12] * scalar;
-	dst[13] = m[13] * scalar;
-	dst[14] = m[14] * scalar;
-	dst[15] = m[15] * scalar;
+    dst[0]  = m[0]  * scalar;
+    dst[1]  = m[1]  * scalar;
+    dst[2]  = m[2]  * scalar;
+    dst[3]  = m[3]  * scalar;
+    dst[4]  = m[4]  * scalar;
+    dst[5]  = m[5]  * scalar;
+    dst[6]  = m[6]  * scalar;
+    dst[7]  = m[7]  * scalar;
+    dst[8]  = m[8]  * scalar;
+    dst[9]  = m[9]  * scalar;
+    dst[10] = m[10] * scalar;
+    dst[11] = m[11] * scalar;
+    dst[12] = m[12] * scalar;
+    dst[13] = m[13] * scalar;
+    dst[14] = m[14] * scalar;
+    dst[15] = m[15] * scalar;
 }
 }
 
 
 inline void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	// Support the case where m1 or m2 is the same array as dst.
-	float product[16];
-
-	product[0]  = m1[0] * m2[0]  + m1[4] * m2[1] + m1[8]   * m2[2]  + m1[12] * m2[3];
-	product[1]  = m1[1] * m2[0]  + m1[5] * m2[1] + m1[9]   * m2[2]  + m1[13] * m2[3];
-	product[2]  = m1[2] * m2[0]  + m1[6] * m2[1] + m1[10]  * m2[2]  + m1[14] * m2[3];
-	product[3]  = m1[3] * m2[0]  + m1[7] * m2[1] + m1[11]  * m2[2]  + m1[15] * m2[3];
-
-	product[4]  = m1[0] * m2[4]  + m1[4] * m2[5] + m1[8]   * m2[6]  + m1[12] * m2[7];
-	product[5]  = m1[1] * m2[4]  + m1[5] * m2[5] + m1[9]   * m2[6]  + m1[13] * m2[7];
-	product[6]  = m1[2] * m2[4]  + m1[6] * m2[5] + m1[10]  * m2[6]  + m1[14] * m2[7];
-	product[7]  = m1[3] * m2[4]  + m1[7] * m2[5] + m1[11]  * m2[6]  + m1[15] * m2[7];
-
-	product[8]  = m1[0] * m2[8]  + m1[4] * m2[9] + m1[8]   * m2[10] + m1[12] * m2[11];
-	product[9]  = m1[1] * m2[8]  + m1[5] * m2[9] + m1[9]   * m2[10] + m1[13] * m2[11];
-	product[10] = m1[2] * m2[8]  + m1[6] * m2[9] + m1[10]  * m2[10] + m1[14] * m2[11];
-	product[11] = m1[3] * m2[8]  + m1[7] * m2[9] + m1[11]  * m2[10] + m1[15] * m2[11];
-
-	product[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8]  * m2[14] + m1[12] * m2[15];
-	product[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9]  * m2[14] + m1[13] * m2[15];
-	product[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
-	product[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
-
-	memcpy(dst, product, MATRIX_SIZE);
+    // Support the case where m1 or m2 is the same array as dst.
+    float product[16];
+
+    product[0]  = m1[0] * m2[0]  + m1[4] * m2[1] + m1[8]   * m2[2]  + m1[12] * m2[3];
+    product[1]  = m1[1] * m2[0]  + m1[5] * m2[1] + m1[9]   * m2[2]  + m1[13] * m2[3];
+    product[2]  = m1[2] * m2[0]  + m1[6] * m2[1] + m1[10]  * m2[2]  + m1[14] * m2[3];
+    product[3]  = m1[3] * m2[0]  + m1[7] * m2[1] + m1[11]  * m2[2]  + m1[15] * m2[3];
+
+    product[4]  = m1[0] * m2[4]  + m1[4] * m2[5] + m1[8]   * m2[6]  + m1[12] * m2[7];
+    product[5]  = m1[1] * m2[4]  + m1[5] * m2[5] + m1[9]   * m2[6]  + m1[13] * m2[7];
+    product[6]  = m1[2] * m2[4]  + m1[6] * m2[5] + m1[10]  * m2[6]  + m1[14] * m2[7];
+    product[7]  = m1[3] * m2[4]  + m1[7] * m2[5] + m1[11]  * m2[6]  + m1[15] * m2[7];
+
+    product[8]  = m1[0] * m2[8]  + m1[4] * m2[9] + m1[8]   * m2[10] + m1[12] * m2[11];
+    product[9]  = m1[1] * m2[8]  + m1[5] * m2[9] + m1[9]   * m2[10] + m1[13] * m2[11];
+    product[10] = m1[2] * m2[8]  + m1[6] * m2[9] + m1[10]  * m2[10] + m1[14] * m2[11];
+    product[11] = m1[3] * m2[8]  + m1[7] * m2[9] + m1[11]  * m2[10] + m1[15] * m2[11];
+
+    product[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8]  * m2[14] + m1[12] * m2[15];
+    product[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9]  * m2[14] + m1[13] * m2[15];
+    product[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
+    product[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
+
+    memcpy(dst, product, MATRIX_SIZE);
 }
 }
 
 
 inline void MathUtil::negateMatrix(const float* m, float* dst)
 inline void MathUtil::negateMatrix(const float* m, float* dst)
 {
 {
-	dst[0]  = -m[0];
-	dst[1]  = -m[1];
-	dst[2]  = -m[2];
-	dst[3]  = -m[3];
-	dst[4]  = -m[4];
-	dst[5]  = -m[5];
-	dst[6]  = -m[6];
-	dst[7]  = -m[7];
-	dst[8]  = -m[8];
-	dst[9]  = -m[9];
-	dst[10] = -m[10];
-	dst[11] = -m[11];
-	dst[12] = -m[12];
-	dst[13] = -m[13];
-	dst[14] = -m[14];
-	dst[15] = -m[15];
+    dst[0]  = -m[0];
+    dst[1]  = -m[1];
+    dst[2]  = -m[2];
+    dst[3]  = -m[3];
+    dst[4]  = -m[4];
+    dst[5]  = -m[5];
+    dst[6]  = -m[6];
+    dst[7]  = -m[7];
+    dst[8]  = -m[8];
+    dst[9]  = -m[9];
+    dst[10] = -m[10];
+    dst[11] = -m[11];
+    dst[12] = -m[12];
+    dst[13] = -m[13];
+    dst[14] = -m[14];
+    dst[15] = -m[15];
 }
 }
 
 
 inline void MathUtil::transposeMatrix(const float* m, float* dst)
 inline void MathUtil::transposeMatrix(const float* m, float* dst)
 {
 {
-	float t[16] = {
-		m[0], m[4], m[8], m[12],
-		m[1], m[5], m[9], m[13],
-		m[2], m[6], m[10], m[14],
-		m[3], m[7], m[11], m[15]
-	};
-	memcpy(dst, t, MATRIX_SIZE);
+    float t[16] = {
+        m[0], m[4], m[8], m[12],
+        m[1], m[5], m[9], m[13],
+        m[2], m[6], m[10], m[14],
+        m[3], m[7], m[11], m[15]
+    };
+    memcpy(dst, t, MATRIX_SIZE);
 }
 }
 
 
 inline void MathUtil::transformVector4(const float* m, float x, float y, float z, float w, float* dst)
 inline void MathUtil::transformVector4(const float* m, float x, float y, float z, float w, float* dst)
 {
 {
-	dst[0] = x * m[0] + y * m[4] + z * m[8] + w * m[12];
-	dst[1] = x * m[1] + y * m[5] + z * m[9] + w * m[13];
-	dst[2] = x * m[2] + y * m[6] + z * m[10] + w * m[14];
+    dst[0] = x * m[0] + y * m[4] + z * m[8] + w * m[12];
+    dst[1] = x * m[1] + y * m[5] + z * m[9] + w * m[13];
+    dst[2] = x * m[2] + y * m[6] + z * m[10] + w * m[14];
 }
 }
 
 
 inline void MathUtil::transformVector4(const float* m, const float* v, float* dst)
 inline void MathUtil::transformVector4(const float* m, const float* v, float* dst)
 {
 {
     // Handle case where v == dst.
     // Handle case where v == dst.
     float x = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
     float x = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
-	float y = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
+    float y = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
     float z = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
     float z = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
     float w = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
     float w = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
 
 
     dst[0] = x;
     dst[0] = x;
     dst[1] = y;
     dst[1] = y;
-	dst[2] = z;
-	dst[3] = w;
+    dst[2] = z;
+    dst[3] = w;
 }
 }
 
 
 inline void MathUtil::crossVector3(const float* v1, const float* v2, float* dst)
 inline void MathUtil::crossVector3(const float* v1, const float* v2, float* dst)
 {
 {
-	float x = (v1[1] * v2[2]) - (v1[2] * v2[1]);
-	float y = (v1[2] * v2[0]) - (v1[0] * v2[2]);
-	float z = (v1[0] * v2[1]) - (v1[1] * v2[0]);
+    float x = (v1[1] * v2[2]) - (v1[2] * v2[1]);
+    float y = (v1[2] * v2[0]) - (v1[0] * v2[2]);
+    float z = (v1[0] * v2[1]) - (v1[1] * v2[0]);
 
 
-	dst[0] = x;
-	dst[1] = y;
-	dst[2] = z;
+    dst[0] = x;
+    dst[1] = y;
+    dst[2] = z;
 }
 }
 
 
 }
 }

+ 185 - 185
gameplay/src/MathUtilNeon.inl

@@ -3,227 +3,227 @@ namespace gameplay
 
 
 inline void MathUtil::addMatrix(const float* m, float scalar, float* dst)
 inline void MathUtil::addMatrix(const float* m, float scalar, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 {q0, q1}, [%1]! 	\n\t" // M[m0-m7]
-		"vld1.32 {q2, q3}, [%1] 	\n\t" // M[m8-m15]
-		"vld1.32 {d8[0]},  [%2] 	\n\t" // s
-		"vmov.f32 s17, s16          \n\t" // s
-		"vmov.f32 s18, s16          \n\t" // s
-		"vmov.f32 s19, s16          \n\t" // s
-
-		"vadd.f32 q8, q0, q4  		\n\t" // DST->M[m0-m3] = M[m0-m3] + s
-		"vadd.f32 q9, q1, q4 		\n\t" // DST->M[m4-m7] = M[m4-m7] + s
-		"vadd.f32 q10, q2, q4 		\n\t" // DST->M[m8-m11] = M[m8-m11] + s
-		"vadd.f32 q11, q3, q4 		\n\t" // DST->M[m12-m15] = M[m12-m15] + s
-
-		"vst1.32 {q8, q9}, [%0]!  	\n\t" // DST->M[m0-m7]
-		"vst1.32 {q10, q11}, [%0]   \n\t" // DST->M[m8-m15]
-		:
-		: "r"(dst), "r"(m), "r"(&scalar)
-		: "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", "memory"
-	);
+    asm volatile(
+        "vld1.32 {q0, q1}, [%1]!    \n\t" // M[m0-m7]
+        "vld1.32 {q2, q3}, [%1]     \n\t" // M[m8-m15]
+        "vld1.32 {d8[0]},  [%2]     \n\t" // s
+        "vmov.f32 s17, s16          \n\t" // s
+        "vmov.f32 s18, s16          \n\t" // s
+        "vmov.f32 s19, s16          \n\t" // s
+
+        "vadd.f32 q8, q0, q4        \n\t" // DST->M[m0-m3] = M[m0-m3] + s
+        "vadd.f32 q9, q1, q4        \n\t" // DST->M[m4-m7] = M[m4-m7] + s
+        "vadd.f32 q10, q2, q4       \n\t" // DST->M[m8-m11] = M[m8-m11] + s
+        "vadd.f32 q11, q3, q4       \n\t" // DST->M[m12-m15] = M[m12-m15] + s
+
+        "vst1.32 {q8, q9}, [%0]!    \n\t" // DST->M[m0-m7]
+        "vst1.32 {q10, q11}, [%0]   \n\t" // DST->M[m8-m15]
+        :
+        : "r"(dst), "r"(m), "r"(&scalar)
+        : "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 	{q0, q1}, 	[%1]! 	\n\t" // M1[m0-m7]
-		"vld1.32 	{q2, q3}, 	[%1] 	\n\t" // M1[m8-m15]
-		"vld1.32 	{q8, q9}, 	[%2]! 	\n\t" // M2[m0-m7]
-		"vld1.32 	{q10, q11}, [%2]  	\n\t" // M2[m8-m15]
-
-		"vadd.f32   q12, q0, q8 		\n\t" // DST->M[m0-m3] = M1[m0-m3] + M2[m0-m3]
-		"vadd.f32   q13, q1, q9			\n\t" // DST->M[m4-m7] = M1[m4-m7] + M2[m4-m7]
-		"vadd.f32   q14, q2, q10		\n\t" // DST->M[m8-m11] = M1[m8-m11] + M2[m8-m11]
-		"vadd.f32   q15, q3, q11		\n\t" // DST->M[m12-m15] = M1[m12-m15] + M2[m12-m15]
-
-		"vst1.32    {q12, q13}, [%0]!   \n\t" // DST->M[m0-m7]
-		"vst1.32    {q14, q15}, [%0]    \n\t" // DST->M[m8-m15]
-		:
-		: "r"(dst), "r"(m1), "r"(m2)
-		: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
-	);
+    asm volatile(
+        "vld1.32     {q0, q1},     [%1]! \n\t" // M1[m0-m7]
+        "vld1.32     {q2, q3},     [%1]  \n\t" // M1[m8-m15]
+        "vld1.32     {q8, q9},     [%2]! \n\t" // M2[m0-m7]
+        "vld1.32     {q10, q11}, [%2]    \n\t" // M2[m8-m15]
+
+        "vadd.f32   q12, q0, q8          \n\t" // DST->M[m0-m3] = M1[m0-m3] + M2[m0-m3]
+        "vadd.f32   q13, q1, q9          \n\t" // DST->M[m4-m7] = M1[m4-m7] + M2[m4-m7]
+        "vadd.f32   q14, q2, q10         \n\t" // DST->M[m8-m11] = M1[m8-m11] + M2[m8-m11]
+        "vadd.f32   q15, q3, q11         \n\t" // DST->M[m12-m15] = M1[m12-m15] + M2[m12-m15]
+
+        "vst1.32    {q12, q13}, [%0]!    \n\t" // DST->M[m0-m7]
+        "vst1.32    {q14, q15}, [%0]     \n\t" // DST->M[m8-m15]
+        :
+        : "r"(dst), "r"(m1), "r"(m2)
+        : "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 	{q0, q1}, 	[%1]! 	\n\t" // M1[m0-m7]
-		"vld1.32 	{q2, q3}, 	[%1] 	\n\t" // M1[m8-m15]
-		"vld1.32 	{q8, q9}, 	[%2]! 	\n\t" // M2[m0-m7]
-		"vld1.32 	{q10, q11}, [%2] 	\n\t" // M2[m8-m15]
-
-		"vsub.f32   q12, q0, q8 		\n\t" // DST->M[m0-m3] = M1[m0-m3] - M2[m0-m3]
-		"vsub.f32   q13, q1, q9			\n\t" // DST->M[m4-m7] = M1[m4-m7] - M2[m4-m7]
-		"vsub.f32   q14, q2, q10		\n\t" // DST->M[m8-m11] = M1[m8-m11] - M2[m8-m11]
-		"vsub.f32   q15, q3, q11		\n\t" // DST->M[m12-m15] = M1[m12-m15] - M2[m12-m15]
-
-		"vst1.32    {q12, q13}, [%0]!   \n\t" // DST->M[m0-m7]
-		"vst1.32    {q14, q15}, [%0]    \n\t" // DST->M[m8-m15]
-		:
-		: "r"(dst), "r"(m1), "r"(m2)
-		: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
-	);
+    asm volatile(
+        "vld1.32     {q0, q1},     [%1]!  \n\t" // M1[m0-m7]
+        "vld1.32     {q2, q3},     [%1]   \n\t" // M1[m8-m15]
+        "vld1.32     {q8, q9},     [%2]!  \n\t" // M2[m0-m7]
+        "vld1.32     {q10, q11}, [%2]     \n\t" // M2[m8-m15]
+
+        "vsub.f32   q12, q0, q8         \n\t" // DST->M[m0-m3] = M1[m0-m3] - M2[m0-m3]
+        "vsub.f32   q13, q1, q9         \n\t" // DST->M[m4-m7] = M1[m4-m7] - M2[m4-m7]
+        "vsub.f32   q14, q2, q10        \n\t" // DST->M[m8-m11] = M1[m8-m11] - M2[m8-m11]
+        "vsub.f32   q15, q3, q11        \n\t" // DST->M[m12-m15] = M1[m12-m15] - M2[m12-m15]
+
+        "vst1.32    {q12, q13}, [%0]!   \n\t" // DST->M[m0-m7]
+        "vst1.32    {q14, q15}, [%0]    \n\t" // DST->M[m8-m15]
+        :
+        : "r"(dst), "r"(m1), "r"(m2)
+        : "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
 inline void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 	{d0[0]},	 	[%2]     	\n\t" // M[m0-m7]
-		"vld1.32	{q4-q5},  		[%1]!    	\n\t" // M[m8-m15]
-		"vld1.32	{q6-q7},  		[%1]		\n\t" // s
-
-		"vmul.f32 	q8, q4, d0[0]    			\n\t" // DST->M[m0-m3] = M[m0-m3] * s
-		"vmul.f32 	q9, q5, d0[0]    			\n\t" // DST->M[m4-m7] = M[m4-m7] * s
-		"vmul.f32 	q10, q6, d0[0]    			\n\t" // DST->M[m8-m11] = M[m8-m11] * s
-		"vmul.f32 	q11, q7, d0[0]   		 	\n\t" // DST->M[m12-m15] = M[m12-m15] * s
-
-		"vst1.32 	{q8-q9},   		[%0]! 		\n\t" // DST->M[m0-m7]
-		"vst1.32 	{q10-q11}, 		[%0]		\n\t" // DST->M[m8-m15]
-		:
-		: "r"(dst), "r"(m), "r"(&scalar)
-		: "q0", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "memory"
-	);
+    asm volatile(
+        "vld1.32     {d0[0]},         [%2]        \n\t" // M[m0-m7]
+        "vld1.32    {q4-q5},          [%1]!       \n\t" // M[m8-m15]
+        "vld1.32    {q6-q7},          [%1]        \n\t" // s
+
+        "vmul.f32     q8, q4, d0[0]               \n\t" // DST->M[m0-m3] = M[m0-m3] * s
+        "vmul.f32     q9, q5, d0[0]               \n\t" // DST->M[m4-m7] = M[m4-m7] * s
+        "vmul.f32     q10, q6, d0[0]              \n\t" // DST->M[m8-m11] = M[m8-m11] * s
+        "vmul.f32     q11, q7, d0[0]              \n\t" // DST->M[m12-m15] = M[m12-m15] * s
+
+        "vst1.32     {q8-q9},           [%0]!     \n\t" // DST->M[m0-m7]
+        "vst1.32     {q10-q11},         [%0]      \n\t" // DST->M[m8-m15]
+        :
+        : "r"(dst), "r"(m), "r"(&scalar)
+        : "q0", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
 inline void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32	 {d16 - d19}, [%1]!	  \n\t"       // M1[m0-m7]
-		"vld1.32     {d20 - d23}, [%1]    \n\t"       // M1[m8-m15]
-		"vld1.32     {d0 - d3}, [%2]!     \n\t"       // M2[m0-m7]
-		"vld1.32     {d4 - d7}, [%2]      \n\t"       // M2[m8-m15]
-
-		"vmul.f32    q12, q8, d0[0]     \n\t"         // DST->M[m0-m3] = M1[m0-m3] * M2[m0]
-		"vmul.f32    q13, q8, d2[0]     \n\t"         // DST->M[m4-m7] = M1[m4-m7] * M2[m4]
-		"vmul.f32    q14, q8, d4[0]     \n\t"         // DST->M[m8-m11] = M1[m8-m11] * M2[m8]
-		"vmul.f32    q15, q8, d6[0]     \n\t"         // DST->M[m12-m15] = M1[m12-m15] * M2[m12]
-
-		"vmla.f32    q12, q9, d0[1]     \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m1]
-		"vmla.f32    q13, q9, d2[1]     \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m5]
-		"vmla.f32    q14, q9, d4[1]     \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m9]
-		"vmla.f32    q15, q9, d6[1]     \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m13]
-
-		"vmla.f32    q12, q10, d1[0]    \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m2]
-		"vmla.f32    q13, q10, d3[0]    \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m6]
-		"vmla.f32    q14, q10, d5[0]    \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m10]
-		"vmla.f32    q15, q10, d7[0]    \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m14]
-
-		"vmla.f32    q12, q11, d1[1]    \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m3]
-		"vmla.f32    q13, q11, d3[1]    \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m7]
-		"vmla.f32    q14, q11, d5[1]    \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m11]
-		"vmla.f32    q15, q11, d7[1]    \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m15]
-
-		"vst1.32    {d24 - d27}, [%0]!    \n\t"       // DST->M[m0-m7]
-		"vst1.32    {d28 - d31}, [%0]     \n\t"       // DST->M[m8-m15]
-
-		: // output
-		: "r"(dst), "r"(m1), "r"(m2) // input - note *value* of pointer doesn't change.
-		: "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
-	);
+    asm volatile(
+        "vld1.32     {d16 - d19}, [%1]! \n\t"       // M1[m0-m7]
+        "vld1.32     {d20 - d23}, [%1]  \n\t"       // M1[m8-m15]
+        "vld1.32     {d0 - d3}, [%2]!   \n\t"       // M2[m0-m7]
+        "vld1.32     {d4 - d7}, [%2]    \n\t"       // M2[m8-m15]
+
+        "vmul.f32    q12, q8, d0[0]     \n\t"         // DST->M[m0-m3] = M1[m0-m3] * M2[m0]
+        "vmul.f32    q13, q8, d2[0]     \n\t"         // DST->M[m4-m7] = M1[m4-m7] * M2[m4]
+        "vmul.f32    q14, q8, d4[0]     \n\t"         // DST->M[m8-m11] = M1[m8-m11] * M2[m8]
+        "vmul.f32    q15, q8, d6[0]     \n\t"         // DST->M[m12-m15] = M1[m12-m15] * M2[m12]
+
+        "vmla.f32    q12, q9, d0[1]     \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m1]
+        "vmla.f32    q13, q9, d2[1]     \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m5]
+        "vmla.f32    q14, q9, d4[1]     \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m9]
+        "vmla.f32    q15, q9, d6[1]     \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m13]
+
+        "vmla.f32    q12, q10, d1[0]    \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m2]
+        "vmla.f32    q13, q10, d3[0]    \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m6]
+        "vmla.f32    q14, q10, d5[0]    \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m10]
+        "vmla.f32    q15, q10, d7[0]    \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m14]
+
+        "vmla.f32    q12, q11, d1[1]    \n\t"         // DST->M[m0-m3] += M1[m0-m3] * M2[m3]
+        "vmla.f32    q13, q11, d3[1]    \n\t"         // DST->M[m4-m7] += M1[m4-m7] * M2[m7]
+        "vmla.f32    q14, q11, d5[1]    \n\t"         // DST->M[m8-m11] += M1[m8-m11] * M2[m11]
+        "vmla.f32    q15, q11, d7[1]    \n\t"         // DST->M[m12-m15] += M1[m12-m15] * M2[m15]
+
+        "vst1.32    {d24 - d27}, [%0]!  \n\t"       // DST->M[m0-m7]
+        "vst1.32    {d28 - d31}, [%0]   \n\t"       // DST->M[m8-m15]
+
+        : // output
+        : "r"(dst), "r"(m1), "r"(m2) // input - note *value* of pointer doesn't change.
+        : "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
+    );
 }
 }
 
 
 inline void MathUtil::negateMatrix(const float* m, float* dst)
 inline void MathUtil::negateMatrix(const float* m, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 	{q0-q1},  [%1]! 	\n\t" // load m0-m7
-		"vld1.32 	{q2-q3},  [%1]   	\n\t" // load m8-m15
-
-		"vneg.f32 	q4, q0 				\n\t" // negate m0-m3
-		"vneg.f32 	q5, q1 				\n\t" // negate m4-m7
-		"vneg.f32 	q6, q2 				\n\t" // negate m8-m15
-		"vneg.f32 	q7, q3 				\n\t" // negate m8-m15
-
-		"vst1.32 	{q4-q5},  [%0]!		\n\t" // store m0-m7
-		"vst1.32 	{q6-q7},  [%0]		\n\t" // store m8-m15
-		:
-		: "r"(dst), "r"(m)
-		: "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "memory"
-	);
+    asm volatile(
+        "vld1.32     {q0-q1},  [%1]!     \n\t" // load m0-m7
+        "vld1.32     {q2-q3},  [%1]      \n\t" // load m8-m15
+
+        "vneg.f32     q4, q0             \n\t" // negate m0-m3
+        "vneg.f32     q5, q1             \n\t" // negate m4-m7
+        "vneg.f32     q6, q2             \n\t" // negate m8-m15
+        "vneg.f32     q7, q3             \n\t" // negate m8-m15
+
+        "vst1.32     {q4-q5},  [%0]!     \n\t" // store m0-m7
+        "vst1.32     {q6-q7},  [%0]      \n\t" // store m8-m15
+        :
+        : "r"(dst), "r"(m)
+        : "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::transposeMatrix(const float* m, float* dst)
 inline void MathUtil::transposeMatrix(const float* m, float* dst)
 {
 {
-	asm volatile(
-		"vld4.32 {d0[0], d2[0], d4[0], d6[0]}, [%1]! 	\n\t" // DST->M[m0, m4, m8, m12] = M[m0-m3]
-		"vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [%1]!	\n\t" // DST->M[m1, m5, m9, m12] = M[m4-m7]
-		"vld4.32 {d1[0], d3[0], d5[0], d7[0]}, [%1]!	\n\t" // DST->M[m2, m6, m10, m12] = M[m8-m11]
-		"vld4.32 {d1[1], d3[1], d5[1], d7[1]}, [%1] 	\n\t" // DST->M[m3, m7, m11, m12] = M[m12-m15]
-
-		"vst1.32 {q0-q1}, [%0]! 						\n\t" // DST->M[m0-m7]
-		"vst1.32 {q2-q3}, [%0] 							\n\t" // DST->M[m8-m15]
-		:
-		: "r"(dst), "r"(m)
-		: "q0", "q1", "q2", "q3", "memory"
-	);
+    asm volatile(
+        "vld4.32 {d0[0], d2[0], d4[0], d6[0]}, [%1]!    \n\t" // DST->M[m0, m4, m8, m12] = M[m0-m3]
+        "vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [%1]!    \n\t" // DST->M[m1, m5, m9, m12] = M[m4-m7]
+        "vld4.32 {d1[0], d3[0], d5[0], d7[0]}, [%1]!    \n\t" // DST->M[m2, m6, m10, m12] = M[m8-m11]
+        "vld4.32 {d1[1], d3[1], d5[1], d7[1]}, [%1]     \n\t" // DST->M[m3, m7, m11, m12] = M[m12-m15]
+
+        "vst1.32 {q0-q1}, [%0]!                         \n\t" // DST->M[m0-m7]
+        "vst1.32 {q2-q3}, [%0]                          \n\t" // DST->M[m8-m15]
+        :
+        : "r"(dst), "r"(m)
+        : "q0", "q1", "q2", "q3", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::transformVector4(const float* m, float x, float y, float z, float w, float* dst)
 inline void MathUtil::transformVector4(const float* m, float x, float y, float z, float w, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32	{d0[0]},		[%1]	\n\t"	// V[x]
-		"vld1.32	{d0[1]},    	[%2]	\n\t"	// V[y]
-		"vld1.32	{d1[0]},		[%3]	\n\t"	// V[z]
-		"vld1.32	{d1[1]},		[%4]	\n\t"	// V[w]
-		"vld1.32	{d18 - d21},	[%5]!	\n\t"	// M[m0-m7]
-		"vld1.32	{d22 - d25},	[%5]	\n\t"	// M[m8-m15]
-
-		"vmul.f32 q13,  q9, d0[0]			\n\t"	// DST->V = M[m0-m3] * V[x]
-		"vmla.f32 q13, q10, d0[1]      		\n\t"	// DST->V += M[m4-m7] * V[y]
-		"vmla.f32 q13, q11, d1[0]      		\n\t"	// DST->V += M[m8-m11] * V[z]
-		"vmla.f32 q13, q12, d1[1]      		\n\t"	// DST->V += M[m12-m15] * V[w]
-
-		"vst1.32 {d26}, [%0]!        		\n\t"	// DST->V[x, y]
-		"vst1.32 {d27[0]}, [%0]        		\n\t"	// DST->V[z]
-		:
-		: "r"(dst), "r"(&x), "r"(&y), "r"(&z), "r"(&w), "r"(m)
-		: "q0", "q9", "q10","q11", "q12", "q13", "memory"
-	);
+    asm volatile(
+        "vld1.32    {d0[0]},        [%1]    \n\t"    // V[x]
+        "vld1.32    {d0[1]},        [%2]    \n\t"    // V[y]
+        "vld1.32    {d1[0]},        [%3]    \n\t"    // V[z]
+        "vld1.32    {d1[1]},        [%4]    \n\t"    // V[w]
+        "vld1.32    {d18 - d21},    [%5]!   \n\t"    // M[m0-m7]
+        "vld1.32    {d22 - d25},    [%5]    \n\t"    // M[m8-m15]
+
+        "vmul.f32 q13,  q9, d0[0]           \n\t"    // DST->V = M[m0-m3] * V[x]
+        "vmla.f32 q13, q10, d0[1]           \n\t"    // DST->V += M[m4-m7] * V[y]
+        "vmla.f32 q13, q11, d1[0]           \n\t"    // DST->V += M[m8-m11] * V[z]
+        "vmla.f32 q13, q12, d1[1]           \n\t"    // DST->V += M[m12-m15] * V[w]
+
+        "vst1.32 {d26}, [%0]!               \n\t"    // DST->V[x, y]
+        "vst1.32 {d27[0]}, [%0]             \n\t"    // DST->V[z]
+        :
+        : "r"(dst), "r"(&x), "r"(&y), "r"(&z), "r"(&w), "r"(m)
+        : "q0", "q9", "q10","q11", "q12", "q13", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::transformVector4(const float* m, const float* v, float* dst)
 inline void MathUtil::transformVector4(const float* m, const float* v, float* dst)
 {
 {
-	asm volatile
-	(
-		"vld1.32	{d0, d1}, [%1]		\n\t"   // V[x, y, z, w]
-		"vld1.32    {d18 - d21}, [%2]!  \n\t"   // M[m0-m7]
-		"vld1.32    {d22 - d25}, [%2]  \n\t"    // M[m8-m15]
-
-		"vmul.f32   q13, q9, d0[0]      \n\t"   // DST->V = M[m0-m3] * V[x]
-		"vmla.f32   q13, q10, d0[1]     \n\t"   // DST->V = M[m4-m7] * V[y]
-		"vmla.f32   q13, q11, d1[0]     \n\t"   // DST->V = M[m8-m11] * V[z]
-		"vmla.f32   q13, q12, d1[1]     \n\t"   // DST->V = M[m12-m15] * V[w]
-
-		"vst1.32    {d26, d27}, [%0]    \n\t"   // DST->V
-		:
-		: "r"(dst), "r"(v), "r"(m)
-		: "q0", "q9", "q10","q11", "q12", "q13", "memory"
-	);
+    asm volatile
+    (
+        "vld1.32    {d0, d1}, [%1]     \n\t"   // V[x, y, z, w]
+        "vld1.32    {d18 - d21}, [%2]! \n\t"   // M[m0-m7]
+        "vld1.32    {d22 - d25}, [%2]  \n\t"    // M[m8-m15]
+
+        "vmul.f32   q13, q9, d0[0]     \n\t"   // DST->V = M[m0-m3] * V[x]
+        "vmla.f32   q13, q10, d0[1]    \n\t"   // DST->V = M[m4-m7] * V[y]
+        "vmla.f32   q13, q11, d1[0]    \n\t"   // DST->V = M[m8-m11] * V[z]
+        "vmla.f32   q13, q12, d1[1]    \n\t"   // DST->V = M[m12-m15] * V[w]
+
+        "vst1.32    {d26, d27}, [%0]   \n\t"   // DST->V
+        :
+        : "r"(dst), "r"(v), "r"(m)
+        : "q0", "q9", "q10","q11", "q12", "q13", "memory"
+    );
 }
 }
 
 
 inline void MathUtil::crossVector3(const float* v1, const float* v2, float* dst)
 inline void MathUtil::crossVector3(const float* v1, const float* v2, float* dst)
 {
 {
-	asm volatile(
-		"vld1.32 {d1[1]},  [%1] 		\n\t" //
-		"vld1.32 {d0},     [%2]         \n\t" //
-		"vmov.f32 s2, s1                \n\t" // q0 = (v1y, v1z, v1z, v1x)
-
-		"vld1.32 {d2[1]},  [%3]	    	\n\t" //
-		"vld1.32 {d3},     [%4]         \n\t" //
-		"vmov.f32 s4, s7          		\n\t" // q1 = (v2z, v2x, v2y, v2z)
-
-		"vmul.f32 d4, d0, d2  			\n\t" // x = v1y * v2z, y = v1z * v2x
-		"vmls.f32 d4, d1, d3  			\n\t" // x -= v1z * v2y, y-= v1x - v2z
-
-		"vmul.f32 d5, d3, d1[1]			\n\t" // z = v1x * v2y
-		"vmls.f32 d5, d0, d2[1]         \n\t" // z-= v1y * vx
-
-		"vst1.32 {d4}, 	  [%0]!    		\n\t" // V[x, y]
-		"vst1.32 {d5[0]}, [%0]     		\n\t" // V[z]
-		:
-		: "r"(dst), "r"(v1), "r"((v1+1)), "r"(v2), "r"((v2+1))
-		: "q0", "q1", "q2", "memory"
-	);
+    asm volatile(
+        "vld1.32 {d1[1]},  [%1]         \n\t" //
+        "vld1.32 {d0},     [%2]         \n\t" //
+        "vmov.f32 s2, s1                \n\t" // q0 = (v1y, v1z, v1z, v1x)
+
+        "vld1.32 {d2[1]},  [%3]         \n\t" //
+        "vld1.32 {d3},     [%4]         \n\t" //
+        "vmov.f32 s4, s7                  \n\t" // q1 = (v2z, v2x, v2y, v2z)
+
+        "vmul.f32 d4, d0, d2            \n\t" // x = v1y * v2z, y = v1z * v2x
+        "vmls.f32 d4, d1, d3            \n\t" // x -= v1z * v2y, y-= v1x - v2z
+
+        "vmul.f32 d5, d3, d1[1]         \n\t" // z = v1x * v2y
+        "vmls.f32 d5, d0, d2[1]         \n\t" // z-= v1y * vx
+
+        "vst1.32 {d4},       [%0]!      \n\t" // V[x, y]
+        "vst1.32 {d5[0]}, [%0]          \n\t" // V[z]
+        :
+        : "r"(dst), "r"(v1), "r"((v1+1)), "r"(v2), "r"((v2+1))
+        : "q0", "q1", "q2", "memory"
+    );
 }
 }
 
 
 }
 }

+ 2 - 2
gameplay/src/Matrix.cpp

@@ -654,9 +654,9 @@ void Matrix::multiply(const Matrix& m)
 
 
 void Matrix::multiply(const Matrix& m1, const Matrix& m2, Matrix* dst)
 void Matrix::multiply(const Matrix& m1, const Matrix& m2, Matrix* dst)
 {
 {
-	GP_ASSERT(dst);
+    GP_ASSERT(dst);
 
 
-	MathUtil::multiplyMatrix(m1.m, m2.m, dst->m);
+    MathUtil::multiplyMatrix(m1.m, m2.m, dst->m);
 }
 }
 
 
 void Matrix::negate()
 void Matrix::negate()

+ 5 - 5
gameplay/src/Mesh.cpp

@@ -68,17 +68,17 @@ Mesh* Mesh::createMesh(const VertexFormat& vertexFormat, unsigned int vertexCoun
 }
 }
 
 
 
 
-Mesh* Mesh::createQuad(float x, float y, float width, float height)
+Mesh* Mesh::createQuad(float x, float y, float width, float height, float s1, float t1, float s2, float t2)
 {
 {
     float x2 = x + width;
     float x2 = x + width;
     float y2 = y + height;
     float y2 = y + height;
 
 
     float vertices[] =
     float vertices[] =
     {
     {
-        x, y2, 0,   0, 0, 1,    0, 0,
-        x, y, 0,    0, 0, 1,    0, 1,
-        x2, y2, 0,  0, 0, 1,    1, 0,
-        x2, y, 0,   0, 0, 1,    1, 1
+        x, y2, 0,   0, 0, 1,    s1, t2,
+        x, y, 0,    0, 0, 1,    s1, t1,
+        x2, y2, 0,  0, 0, 1,    s2, t2,
+        x2, y, 0,   0, 0, 1,    s2, t1,
     };
     };
 
 
     VertexFormat::Element elements[] =
     VertexFormat::Element elements[] =

+ 5 - 1
gameplay/src/Mesh.h

@@ -83,11 +83,15 @@ public:
      * @param y The y coordinate.
      * @param y The y coordinate.
      * @param width The width of the quad.
      * @param width The width of the quad.
      * @param height The height of the quad.
      * @param height The height of the quad.
+     * @param s1 The S texture coordinate of the bottom left point.
+     * @param t1 The T texture coordinate of the bottom left point.
+     * @param s2 The S texture coordinate of the top right point.
+     * @param t2 The T texture coordinate of the top right point.
      * 
      * 
      * @return The newly created mesh.
      * @return The newly created mesh.
      * @script{create}
      * @script{create}
      */
      */
-    static Mesh* createQuad(float x, float y, float width, float height);
+    static Mesh* createQuad(float x, float y, float width, float height, float s1 = 0.0f, float t1 = 0.0f, float s2 = 1.0f, float t2 = 1.0f);
 
 
     /**
     /**
      * Creates a new full-screen 2D quad.
      * Creates a new full-screen 2D quad.

+ 55 - 0
gameplay/src/Node.cpp

@@ -4,6 +4,8 @@
 #include "Scene.h"
 #include "Scene.h"
 #include "Joint.h"
 #include "Joint.h"
 #include "PhysicsRigidBody.h"
 #include "PhysicsRigidBody.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsCharacter.h"
 #include "PhysicsCharacter.h"
 #include "Game.h"
 #include "Game.h"
@@ -1034,6 +1036,27 @@ PhysicsCollisionObject* Node::setCollisionObject(PhysicsCollisionObject::Type ty
         }
         }
         break;
         break;
 
 
+    case PhysicsCollisionObject::VEHICLE:
+        {
+            _collisionObject = new PhysicsVehicle(this, shape, rigidBodyParameters ? *rigidBodyParameters : PhysicsRigidBody::Parameters());
+        }
+        break;
+
+    case PhysicsCollisionObject::VEHICLE_WHEEL:
+        {
+            //
+            // PhysicsVehicleWheel is special because this call will traverse up the scene graph for the
+            // first ancestor node that is shared with another node of collision type VEHICLE, and then
+            // proceed to add itself as a wheel onto that vehicle. This is by design, and allows the
+            // visual scene hierarchy to be the sole representation of the relationship between physics
+            // objects rather than forcing that upon the otherwise-flat ".physics" (properties) file.
+            //
+            // IMPORTANT: The VEHICLE must come before the VEHICLE_WHEEL in the ".scene" (properties) file!
+            //
+            _collisionObject = new PhysicsVehicleWheel(this, shape, rigidBodyParameters ? *rigidBodyParameters : PhysicsRigidBody::Parameters());
+        }
+        break;
+
     case PhysicsCollisionObject::NONE:
     case PhysicsCollisionObject::NONE:
         break;  // Already deleted, Just don't add a new collision object back.
         break;  // Already deleted, Just don't add a new collision object back.
     }
     }
@@ -1082,6 +1105,23 @@ PhysicsCollisionObject* Node::setCollisionObject(Properties* properties)
         {
         {
             _collisionObject = PhysicsRigidBody::create(this, properties);
             _collisionObject = PhysicsRigidBody::create(this, properties);
         }
         }
+        else if (strcmp(type, "VEHICLE") == 0)
+        {
+            _collisionObject = PhysicsVehicle::create(this, properties);
+        }
+        else if (strcmp(type, "VEHICLE_WHEEL") == 0)
+        {
+            //
+            // PhysicsVehicleWheel is special because this call will traverse up the scene graph for the
+            // first ancestor node that is shared with another node of collision type VEHICLE, and then
+            // proceed to add itself as a wheel onto that vehicle. This is by design, and allows the
+            // visual scene hierarchy to be the sole representation of the relationship between physics
+            // objects rather than forcing that upon the otherwise-flat ".physics" (properties) file.
+            //
+            // IMPORTANT: The VEHICLE must come before the VEHICLE_WHEEL in the ".scene" (properties) file!
+            //
+            _collisionObject = PhysicsVehicleWheel::create(this, properties);
+        }
         else
         else
         {
         {
             GP_ERROR("Unsupported collision object type '%s'.", type);
             GP_ERROR("Unsupported collision object type '%s'.", type);
@@ -1097,6 +1137,21 @@ PhysicsCollisionObject* Node::setCollisionObject(Properties* properties)
     return _collisionObject;
     return _collisionObject;
 }
 }
 
 
+unsigned int Node::getNumAdvertisedDescendants() const
+{
+    return _advertisedDescendants.size();
+}
+
+Node* Node::getAdvertisedDescendant(unsigned int i) const
+{
+    return _advertisedDescendants.at(i);
+}
+
+void Node::addAdvertisedDescendant(Node* node)
+{
+    _advertisedDescendants.push_back(node);
+}
+
 AIAgent* Node::getAgent() const
 AIAgent* Node::getAgent() const
 {
 {
     return _agent;
     return _agent;

+ 52 - 5
gameplay/src/Node.h

@@ -486,8 +486,8 @@ public:
     /**
     /**
      * Sets (or disables) the physics collision object for this node.
      * Sets (or disables) the physics collision object for this node.
      *
      *
-     * The supported collision object types include rigid bodies, ghost objects and 
-     * characters.
+     * The supported collision object types include rigid bodies, ghost objects, 
+     * characters, vehicles, and vehicle wheels.
      *
      *
      * Rigid bodies are used to represent most physical objects in a game. The important
      * Rigid bodies are used to represent most physical objects in a game. The important
      * feature of rigid bodies is that they can be simulated by the physics system as other
      * feature of rigid bodies is that they can be simulated by the physics system as other
@@ -496,6 +496,9 @@ public:
      * define their physical features. These parameters can be passed into the
      * define their physical features. These parameters can be passed into the
      * 'rigidBodyParameters' parameter.
      * 'rigidBodyParameters' parameter.
      *
      *
+     * Vehicles consist of a rigid body with wheels. The rigid body parameters can be passed-in
+     * via the 'rigidBodyParameters' parameter, and wheels can be added to the vehicle.
+     *
      * Ghost objects are a simple type of collision object that are not simulated. By default
      * Ghost objects are a simple type of collision object that are not simulated. By default
      * they pass through other objects in the scene without affecting them. Ghost objects do
      * they pass through other objects in the scene without affecting them. Ghost objects do
      * receive collision events however, which makes them useful for representing non-simulated
      * receive collision events however, which makes them useful for representing non-simulated
@@ -516,9 +519,10 @@ public:
      * @param shape Definition of a physics collision shape to be used for this collision object.
      * @param shape Definition of a physics collision shape to be used for this collision object.
      *        Use the static shape methods on the PhysicsCollisionShape class to specificy a shape
      *        Use the static shape methods on the PhysicsCollisionShape class to specificy a shape
      *        definition, such as PhysicsCollisionShape::box().
      *        definition, such as PhysicsCollisionShape::box().
-     * @param rigidBodyParameters If type is PhysicsCollisionObject::RIGID_BODY, this
-     *        must point to a valid rigid body parameters object containing information
-     *        about the rigid body; otherwise, this parmater may be NULL.
+     * @param rigidBodyParameters If type is PhysicsCollisionObject::RIGID_BODY or
+     *        PhysicsCollisionObject::VEHICLE, this must point to a valid rigid body
+     *        parameters object containing information about the rigid body;
+     *        otherwise, this parmater may be NULL.
      */
      */
     PhysicsCollisionObject* setCollisionObject(PhysicsCollisionObject::Type type, const PhysicsCollisionShape::Definition& shape = PhysicsCollisionShape::box(), 
     PhysicsCollisionObject* setCollisionObject(PhysicsCollisionObject::Type type, const PhysicsCollisionShape::Definition& shape = PhysicsCollisionShape::box(), 
                                                PhysicsRigidBody::Parameters* rigidBodyParameters = NULL);
                                                PhysicsRigidBody::Parameters* rigidBodyParameters = NULL);
@@ -539,6 +543,41 @@ public:
      */
      */
     PhysicsCollisionObject* setCollisionObject(Properties* properties);
     PhysicsCollisionObject* setCollisionObject(Properties* properties);
 
 
+    /**
+     * Returns the number of advertised descendants held in this node.
+     *
+     * Descendant nodes can advertise themselves to others using this
+     * mechanism, such as how the wheels are bound to a physics vehicle
+     * via their common ancestor.
+     *
+     * @return the number of advertised descendants held in this node.
+     */
+    unsigned int getNumAdvertisedDescendants() const;
+
+    /**
+     * Returns the advertised descendant at the specified index.
+     *
+     * Descendant nodes can advertise themselves to others using this
+     * mechanism, such as how the wheels are bound to a physics vehicle
+     * via their common ancestor.
+     *
+     * @param i the index to look-up.
+     *
+     * @return the advertised descendant at the specified index.
+     */
+    Node* getAdvertisedDescendant(unsigned int i) const;
+
+    /**
+     * Adds the specified node to the list of advertised descendants.
+     *
+     * Descendant nodes can advertise themselves to others using this
+     * mechanism, such as how the wheels are bound to a physics vehicle
+     * via their common ancestor.
+     *
+     * @param node the node reference to add.
+     */
+    void addAdvertisedDescendant(Node* node);
+
     /**
     /**
      * Returns the AI agent assigned to this node.
      * Returns the AI agent assigned to this node.
      *
      *
@@ -779,6 +818,14 @@ protected:
      * Pointer to custom UserData and cleanup call back that can be stored in a Node.
      * Pointer to custom UserData and cleanup call back that can be stored in a Node.
      */
      */
     UserData* _userData;
     UserData* _userData;
+
+    /**
+     * A linear collection of descendants who wish to advertise themselves, typically
+     * to other descendants. This allows nodes of common ancestry to bond. One example
+     * of this is a physics vehicle and its wheels, which are associated via their
+     * lowest common ancestor.
+     */
+    std::vector<Node*> _advertisedDescendants;
 };
 };
 
 
 /**
 /**

+ 65 - 70
gameplay/src/PhysicsCharacter.cpp

@@ -39,24 +39,6 @@ public:
         if (object == _me || object->getType() == PhysicsCollisionObject::GHOST_OBJECT)
         if (object == _me || object->getType() == PhysicsCollisionObject::GHOST_OBJECT)
             return 1.0f;
             return 1.0f;
 
 
-        /*
-        btVector3 hitNormalWorld;
-        if (normalInWorldSpace)
-        {
-            hitNormalWorld = convexResult.m_hitNormalLocal;
-        } else
-        {
-            // transform normal into worldspace
-            hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
-        }
-
-        btScalar dotUp = _up.dot(hitNormalWorld);
-        if (dotUp < _minSlopeDot)
-        {
-            return btScalar(1.0);
-        }
-        */
-
         return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
         return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
     }
     }
 
 
@@ -71,7 +53,7 @@ PhysicsCharacter::PhysicsCharacter(Node* node, const PhysicsCollisionShape::Defi
     : PhysicsGhostObject(node, shape), _moveVelocity(0,0,0), _forwardVelocity(0.0f), _rightVelocity(0.0f),
     : PhysicsGhostObject(node, shape), _moveVelocity(0,0,0), _forwardVelocity(0.0f), _rightVelocity(0.0f),
     _verticalVelocity(0, 0, 0), _currentVelocity(0,0,0), _normalizedVelocity(0,0,0),
     _verticalVelocity(0, 0, 0), _currentVelocity(0,0,0), _normalizedVelocity(0,0,0),
     _colliding(false), _collisionNormal(0,0,0), _currentPosition(0,0,0), _stepHeight(0.1f),
     _colliding(false), _collisionNormal(0,0,0), _currentPosition(0,0,0), _stepHeight(0.1f),
-    _slopeAngle(0.0f), _cosSlopeAngle(0.0f), _physicsEnabled(true), _mass(mass)
+    _slopeAngle(0.0f), _cosSlopeAngle(0.0f), _physicsEnabled(true), _mass(mass), _actionInterface(NULL)
 {
 {
     setMaxSlopeAngle(45.0f);
     setMaxSlopeAngle(45.0f);
 
 
@@ -81,14 +63,17 @@ PhysicsCharacter::PhysicsCharacter(Node* node, const PhysicsCollisionShape::Defi
 
 
     // Register ourselves as an action on the physics world so we are called back during physics ticks.
     // Register ourselves as an action on the physics world so we are called back during physics ticks.
     GP_ASSERT(Game::getInstance()->getPhysicsController() && Game::getInstance()->getPhysicsController()->_world);
     GP_ASSERT(Game::getInstance()->getPhysicsController() && Game::getInstance()->getPhysicsController()->_world);
-    Game::getInstance()->getPhysicsController()->_world->addAction(this);
+    _actionInterface = new ActionInterface(this);
+    Game::getInstance()->getPhysicsController()->_world->addAction(_actionInterface);
 }
 }
 
 
 PhysicsCharacter::~PhysicsCharacter()
 PhysicsCharacter::~PhysicsCharacter()
 {
 {
     // Unregister ourselves as action from world.
     // Unregister ourselves as action from world.
     GP_ASSERT(Game::getInstance()->getPhysicsController() && Game::getInstance()->getPhysicsController()->_world);
     GP_ASSERT(Game::getInstance()->getPhysicsController() && Game::getInstance()->getPhysicsController()->_world);
-    Game::getInstance()->getPhysicsController()->_world->removeAction(this);
+    Game::getInstance()->getPhysicsController()->_world->removeAction(_actionInterface);
+    SAFE_DELETE(_actionInterface);
+
 }
 }
 
 
 PhysicsCharacter* PhysicsCharacter::create(Node* node, Properties* properties)
 PhysicsCharacter* PhysicsCharacter::create(Node* node, Properties* properties)
@@ -318,53 +303,6 @@ void PhysicsCharacter::updateCurrentVelocity()
     }
     }
 }
 }
 
 
-void PhysicsCharacter::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep)
-{
-    GP_ASSERT(_ghostObject);
-    GP_ASSERT(_node);
-
-    // First check for existing collisions and attempt to respond/fix them.
-    // Basically we are trying to move the character so that it does not penetrate
-    // any other collision objects in the scene. We need to do this to ensure that
-    // the following steps (movement) start from a clean slate, where the character
-    // is not colliding with anything. Also, this step handles collision between
-    // dynamic objects (i.e. objects that moved and now intersect the character).
-    if (_physicsEnabled)
-    {
-        _colliding = false;
-        int stepCount = 0;
-        while (fixCollision(collisionWorld))
-        {
-            _colliding = true;
-
-            if (++stepCount > 4)
-            {
-                // Most likely we are wedged between a number of different collision objects.
-                break;
-            }
-        }
-    }
-
-    // Update current and target world positions.
-    btVector3 startPosition = _ghostObject->getWorldTransform().getOrigin();
-    _currentPosition = startPosition;
-
-    // Process movement in the up direction.
-    if (_physicsEnabled)
-        stepUp(collisionWorld, deltaTimeStep);
-    
-    // Process horizontal movement.
-    stepForwardAndStrafe(collisionWorld, deltaTimeStep);
-
-    // Process movement in the down direction.
-    if (_physicsEnabled)
-        stepDown(collisionWorld, deltaTimeStep);
-
-    // Set new position.
-    btVector3 translation = _currentPosition - startPosition;
-    _node->translate(translation.x(), translation.y(), translation.z());
-}
-
 void PhysicsCharacter::stepUp(btCollisionWorld* collisionWorld, btScalar time)
 void PhysicsCharacter::stepUp(btCollisionWorld* collisionWorld, btScalar time)
 {
 {
     btVector3 targetPosition(_currentPosition);
     btVector3 targetPosition(_currentPosition);
@@ -692,9 +630,66 @@ bool PhysicsCharacter::fixCollision(btCollisionWorld* world)
     return collision;
     return collision;
 }
 }
 
 
-void PhysicsCharacter::debugDraw(btIDebugDraw* debugDrawer)
+PhysicsCharacter::ActionInterface::ActionInterface(PhysicsCharacter* character) : character(character)
 {
 {
-    // debug drawing handled by PhysicsController
 }
 }
 
 
+void PhysicsCharacter::ActionInterface::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep)
+{
+    character->updateAction(collisionWorld, deltaTimeStep);
+}
+
+void PhysicsCharacter::ActionInterface::debugDraw(btIDebugDraw* debugDrawer)
+{
+    // Not used yet.
+}
+
+void PhysicsCharacter::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep)
+{
+    GP_ASSERT(_ghostObject);
+    GP_ASSERT(_node);
+
+    // First check for existing collisions and attempt to respond/fix them.
+    // Basically we are trying to move the character so that it does not penetrate
+    // any other collision objects in the scene. We need to do this to ensure that
+    // the following steps (movement) start from a clean slate, where the character
+    // is not colliding with anything. Also, this step handles collision between
+    // dynamic objects (i.e. objects that moved and now intersect the character).
+    if (_physicsEnabled)
+    {
+        _colliding = false;
+        int stepCount = 0;
+        while (fixCollision(collisionWorld))
+        {
+            _colliding = true;
+
+            if (++stepCount > 4)
+            {
+                // Most likely we are wedged between a number of different collision objects.
+                break;
+            }
+        }
+    }
+
+    // Update current and target world positions.
+    btVector3 startPosition = _ghostObject->getWorldTransform().getOrigin();
+    _currentPosition = startPosition;
+
+    // Process movement in the up direction.
+    if (_physicsEnabled)
+        stepUp(collisionWorld, deltaTimeStep);
+    
+    // Process horizontal movement.
+    stepForwardAndStrafe(collisionWorld, deltaTimeStep);
+
+    // Process movement in the down direction.
+    if (_physicsEnabled)
+        stepDown(collisionWorld, deltaTimeStep);
+
+    // Set new position.
+    btVector3 translation = _currentPosition - startPosition;
+    _node->translate(translation.x(), translation.y(), translation.z());
+}
+
+
 }
 }

+ 21 - 13
gameplay/src/PhysicsCharacter.h

@@ -19,7 +19,7 @@ namespace gameplay
  * character than would be possible if trying to move a character by applying
  * character than would be possible if trying to move a character by applying
  * physical simulation with forces.
  * physical simulation with forces.
  */
  */
-class PhysicsCharacter : public PhysicsGhostObject, public btActionInterface
+class PhysicsCharacter : public PhysicsGhostObject
 {
 {
     friend class Node;
     friend class Node;
 
 
@@ -179,18 +179,6 @@ public:
      */
      */
     void jump(float height);
     void jump(float height);
 
 
-    /**
-     * @see btActionInterface::updateAction
-     * @script{ignore}
-     */
-    void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
-
-    /**
-     * @see btActionInterface::debugDraw
-     * @script{ignore}
-     */
-    void debugDraw(btIDebugDraw* debugDrawer);
-
 protected:
 protected:
 
 
     /**
     /**
@@ -240,6 +228,25 @@ private:
 
 
     bool fixCollision(btCollisionWorld* world);
     bool fixCollision(btCollisionWorld* world);
 
 
+    /**
+     * Hides the callback interfaces within the PhysicsCharacter.
+     * @script{ignore}
+     */
+    class ActionInterface : public btActionInterface
+    {
+    public:
+
+        ActionInterface(PhysicsCharacter* character);
+
+        void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
+
+        void debugDraw(btIDebugDraw* debugDrawer);
+        
+        PhysicsCharacter* character;
+    };
+
+    void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
+
     btVector3 _moveVelocity;
     btVector3 _moveVelocity;
     float _forwardVelocity;
     float _forwardVelocity;
     float _rightVelocity;
     float _rightVelocity;
@@ -255,6 +262,7 @@ private:
     float _cosSlopeAngle;
     float _cosSlopeAngle;
     bool _physicsEnabled;
     bool _physicsEnabled;
     float _mass;
     float _mass;
+    ActionInterface* _actionInterface;
 };
 };
 
 
 }
 }

+ 10 - 0
gameplay/src/PhysicsCollisionObject.h

@@ -39,6 +39,16 @@ public:
          */
          */
         GHOST_OBJECT,
         GHOST_OBJECT,
 
 
+        /** 
+         * PhysicsVehicle type.
+         */
+        VEHICLE,
+
+        /** 
+         * PhysicsVehicleWheel type.
+         */
+        VEHICLE_WHEEL,
+
         /**
         /**
          * No collision object.
          * No collision object.
          */
          */

+ 4 - 4
gameplay/src/PhysicsController.cpp

@@ -173,8 +173,8 @@ bool PhysicsController::rayTest(const Ray& ray, float distance, PhysicsControlle
         {
         {
         }
         }
 
 
-		virtual bool needsCollision(btBroadphaseProxy* proxy0) const
-		{
+        virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+        {
             if (!btCollisionWorld::ClosestRayResultCallback::needsCollision(proxy0))
             if (!btCollisionWorld::ClosestRayResultCallback::needsCollision(proxy0))
                 return false;
                 return false;
 
 
@@ -248,8 +248,8 @@ bool PhysicsController::sweepTest(PhysicsCollisionObject* object, const Vector3&
         {
         {
         }
         }
 
 
-		virtual bool needsCollision(btBroadphaseProxy* proxy0) const
-		{
+        virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+        {
             if (!btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))
             if (!btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))
                 return false;
                 return false;
 
 

+ 1 - 0
gameplay/src/PhysicsController.h

@@ -25,6 +25,7 @@ class PhysicsController : public ScriptTarget
     friend class PhysicsConstraint;
     friend class PhysicsConstraint;
     friend class PhysicsRigidBody;
     friend class PhysicsRigidBody;
     friend class PhysicsCharacter;
     friend class PhysicsCharacter;
+    friend class PhysicsVehicle;
     friend class PhysicsCollisionObject;
     friend class PhysicsCollisionObject;
     friend class PhysicsGhostObject;
     friend class PhysicsGhostObject;
 
 

+ 3 - 3
gameplay/src/PhysicsRigidBody.cpp

@@ -151,7 +151,7 @@ void PhysicsRigidBody::applyTorqueImpulse(const Vector3& torque)
     }
     }
 }
 }
 
 
-PhysicsRigidBody* PhysicsRigidBody::create(Node* node, Properties* properties)
+PhysicsRigidBody* PhysicsRigidBody::create(Node* node, Properties* properties, const char* nspace)
 {
 {
     // Check if the properties is valid and has a valid namespace.
     // Check if the properties is valid and has a valid namespace.
     if (!properties || !(strcmp(properties->getNamespace(), "collisionObject") == 0))
     if (!properties || !(strcmp(properties->getNamespace(), "collisionObject") == 0))
@@ -167,9 +167,9 @@ PhysicsRigidBody* PhysicsRigidBody::create(Node* node, Properties* properties)
         GP_ERROR("Failed to load physics rigid body from properties object; required attribute 'type' is missing.");
         GP_ERROR("Failed to load physics rigid body from properties object; required attribute 'type' is missing.");
         return NULL;
         return NULL;
     }
     }
-    if (strcmp(type, "RIGID_BODY") != 0)
+    if (strcmp(type, nspace) != 0)
     {
     {
-        GP_ERROR("Failed to load physics rigid body from properties object; attribute 'type' must be equal to 'RIGID_BODY'.");
+        GP_ERROR("Failed to load physics rigid body from properties object; attribute 'type' must be equal to '%s'.", nspace);
         return NULL;
         return NULL;
     }
     }
 
 

+ 8 - 4
gameplay/src/PhysicsRigidBody.h

@@ -20,6 +20,8 @@ class PhysicsRigidBody : public PhysicsCollisionObject, public Transform::Listen
 {
 {
     friend class Node;
     friend class Node;
     friend class PhysicsCharacter;
     friend class PhysicsCharacter;
+    friend class PhysicsVehicle;
+    friend class PhysicsVehicleWheel;
     friend class PhysicsConstraint;
     friend class PhysicsConstraint;
     friend class PhysicsController;
     friend class PhysicsController;
     friend class PhysicsFixedConstraint;
     friend class PhysicsFixedConstraint;
@@ -280,6 +282,8 @@ public:
 
 
     /**
     /**
      * Applies the given force to the rigid body (optionally, from the given relative position).
      * Applies the given force to the rigid body (optionally, from the given relative position).
+     * Note that the total force applied depends on the duration of the next frame.
+     * If you want to apply an "impulse" irrespective of the frame duration, consider using applyImpulse.
      * 
      * 
      * @param force The force to be applied.
      * @param force The force to be applied.
      * @param relativePosition The relative position from which to apply the force.
      * @param relativePosition The relative position from which to apply the force.
@@ -340,12 +344,12 @@ private:
     /**
     /**
      * Creates a rigid body from the specified properties object.
      * Creates a rigid body from the specified properties object.
      * 
      * 
-     * @param node The node to create a rigid body for; note that the node must have
-     *      a model attached to it prior to creating a rigid body for it.
-     * @param properties The properties object defining the rigid body (must have namespace equal to 'rigidBody').
+     * @param node The node to create a rigid body for; note that the node must have a model attached to it prior to creating a rigid body for it.
+     * @param properties The properties object defining the rigid body.
+     * @param nspace The namespace expected (default is "RIGID_BODY").
      * @return The newly created rigid body, or <code>NULL</code> if the rigid body failed to load.
      * @return The newly created rigid body, or <code>NULL</code> if the rigid body failed to load.
      */
      */
-    static PhysicsRigidBody* create(Node* node, Properties* properties);
+    static PhysicsRigidBody* create(Node* node, Properties* properties, const char* nspace = "RIGID_BODY");
 
 
     // Adds a constraint to this rigid body.
     // Adds a constraint to this rigid body.
     void addConstraint(PhysicsConstraint* constraint);
     void addConstraint(PhysicsConstraint* constraint);

+ 258 - 0
gameplay/src/PhysicsVehicle.cpp

@@ -0,0 +1,258 @@
+#include "Base.h"
+#include "Game.h"
+#include "Node.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
+
+namespace gameplay
+{
+
+/**
+  * The default vehicle raycaster in Bullet currently does not filter out the vehicle's own
+  * rigid body from the ray test which can result in unexpected behavior. These implementations
+  * are intended to fix that.
+  *
+  * @script{ignore}
+  */
+class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
+{
+public:
+
+    ClosestNotMeRayResultCallback(const btVector3& from, const btVector3& to, btCollisionObject* me)
+        : btCollisionWorld::ClosestRayResultCallback(from, to), _me(me)
+    {
+    }
+
+    btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
+    {
+        if (rayResult.m_collisionObject == _me)
+            return 1.0f;
+
+        return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
+    }
+
+private:
+
+    btCollisionObject* _me;
+};
+
+/**
+  * @script{ignore}
+  */
+class VehicleNotMeRaycaster : public btVehicleRaycaster
+{
+
+public:
+
+    VehicleNotMeRaycaster(btDynamicsWorld* world, btCollisionObject* me)
+        : _dynamicsWorld(world), _me(me)
+    {
+    }
+
+    void* castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result)
+    {
+        ClosestNotMeRayResultCallback rayCallback(from, to, _me);
+        _dynamicsWorld->rayTest(from, to, rayCallback);
+
+        if (rayCallback.hasHit())
+        {
+            const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
+            if (body && body->hasContactResponse())
+            {
+                result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
+                result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
+                result.m_hitNormalInWorld.normalize();
+                result.m_distFraction = rayCallback.m_closestHitFraction;
+                return (void*)body;
+            }
+        }
+        return 0;
+    }
+
+private:
+
+    btDynamicsWorld* _dynamicsWorld;
+    btCollisionObject* _me;
+};
+
+PhysicsVehicle::PhysicsVehicle(Node* node, const PhysicsCollisionShape::Definition& shape, const PhysicsRigidBody::Parameters& parameters)
+    : PhysicsCollisionObject(node)
+{
+    // Note that the constructor for PhysicsRigidBody calls addCollisionObject and so
+    // that is where the rigid body gets added to the dynamics world.
+    _rigidBody = new PhysicsRigidBody(node, shape, parameters);
+
+    initialize();
+}
+
+PhysicsVehicle::PhysicsVehicle(Node* node, PhysicsRigidBody* rigidBody)
+    : PhysicsCollisionObject(node)
+{
+    _rigidBody = rigidBody;
+
+    initialize();
+}
+
+PhysicsVehicle* PhysicsVehicle::create(Node* node, Properties* properties)
+{
+    // Note that the constructor for PhysicsRigidBody calls addCollisionObject and so
+    // that is where the rigid body gets added to the dynamics world.
+    PhysicsRigidBody* rigidBody = PhysicsRigidBody::create(node, properties, "VEHICLE");
+    PhysicsVehicle* vehicle = new PhysicsVehicle(node, rigidBody);
+
+    // Load the defined vehicle parameters.
+    properties->rewind();
+    const char* name;
+    while ((name = properties->getNextProperty()) != NULL)
+    {
+        if (strcmp(name, "steeringGain") == 0)
+        {
+            vehicle->setSteeringGain(properties->getFloat());
+        }
+        else if (strcmp(name, "brakingForce") == 0)
+        {
+            vehicle->setBrakingForce(properties->getFloat());
+        }
+        else if (strcmp(name, "drivingForce") == 0)
+        {
+            vehicle->setDrivingForce(properties->getFloat());
+        }
+        else
+        {
+            // Ignore this case (we've already parsed the rigid body parameters).
+        }
+    }
+
+    return vehicle;
+}
+
+void PhysicsVehicle::initialize()
+{
+    GP_ASSERT(getNode());
+
+    // Safe default values
+    setSteeringGain(0.5f);
+    setBrakingForce(350.0f);
+    setDrivingForce(2000.0f);
+
+    // Create the vehicle and add it to world
+    btRigidBody* body = static_cast<btRigidBody*>(_rigidBody->getCollisionObject());
+    btDynamicsWorld* dynamicsWorld = Game::getInstance()->getPhysicsController()->_world;
+    _vehicleRaycaster = new VehicleNotMeRaycaster(dynamicsWorld, body);
+    _vehicle = new btRaycastVehicle(_vehicleTuning, body, _vehicleRaycaster);
+    body->setActivationState(DISABLE_DEACTIVATION);
+    dynamicsWorld->addVehicle(_vehicle);
+    _vehicle->setCoordinateSystem(0, 1, 2);
+
+    // Advertise self among ancestor nodes so that wheels can bind to self.
+    // See PhysicsVehicleWheel and Node for more details.
+    for (Node* n = getNode()->getParent(); n; n = n->getParent())
+    {
+        n->addAdvertisedDescendant(getNode());
+    }
+}
+
+PhysicsVehicle::~PhysicsVehicle()
+{
+    // Note that the destructor for PhysicsRigidBody calls removeCollisionObject and so
+    // that is where the rigid body gets removed from the dynamics world. The vehicle
+    // itself is just an action interface in the dynamics world.
+    SAFE_DELETE(_vehicle);
+    SAFE_DELETE(_vehicleRaycaster);
+    SAFE_DELETE(_rigidBody);
+}
+
+btCollisionObject* PhysicsVehicle::getCollisionObject() const
+{
+    GP_ASSERT(_rigidBody);
+
+    return _rigidBody->getCollisionObject();
+}
+
+PhysicsCollisionObject::Type PhysicsVehicle::getType() const
+{
+    return PhysicsCollisionObject::VEHICLE;
+}
+
+PhysicsRigidBody* PhysicsVehicle::getRigidBody() const
+{
+    GP_ASSERT(_rigidBody);
+
+    return _rigidBody;
+}
+
+unsigned int PhysicsVehicle::getNumWheels() const
+{
+    return _wheels.size();
+}
+
+PhysicsVehicleWheel* PhysicsVehicle::getWheel(unsigned int i)
+{
+    return _wheels.at(i);
+}
+
+void PhysicsVehicle::addWheel(PhysicsVehicleWheel* wheel)
+{
+    unsigned int i = _wheels.size();
+    _wheels.push_back(wheel);
+    wheel->setHost(this, i);
+    wheel->addToVehicle(_vehicle);
+}
+
+float PhysicsVehicle::getSpeedKph() const
+{
+    return _vehicle->getCurrentSpeedKmHour();
+}
+
+void PhysicsVehicle::update(float steering, float braking, float driving)
+{
+    PhysicsVehicleWheel* wheel;
+    for (int i = 0; i < _vehicle->getNumWheels(); i++)
+    {
+        wheel = getWheel(i);
+
+        if (wheel->isFront())
+        {
+            _vehicle->setSteeringValue(steering * _steeringGain, i);
+        }
+        else
+        {
+            _vehicle->applyEngineForce(driving * _drivingForce, i);
+            _vehicle->setBrake(braking * _brakingForce, i);
+        }
+
+        wheel->transform(wheel->getNode());
+    }
+}
+
+float PhysicsVehicle::getSteeringGain() const
+{
+    return _steeringGain;
+}
+
+void PhysicsVehicle::setSteeringGain(float steeringGain)
+{
+    _steeringGain = steeringGain;
+}
+
+float PhysicsVehicle::getBrakingForce() const
+{
+    return _brakingForce;
+}
+
+void PhysicsVehicle::setBrakingForce(float brakingForce)
+{
+    _brakingForce = brakingForce;
+}
+
+float PhysicsVehicle::getDrivingForce() const
+{
+    return _drivingForce;
+}
+
+void PhysicsVehicle::setDrivingForce(float drivingForce)
+{
+    _drivingForce = drivingForce;
+}
+
+}

+ 205 - 0
gameplay/src/PhysicsVehicle.h

@@ -0,0 +1,205 @@
+#ifndef PHYSICSVEHICLE_H_
+#define PHYSICSVEHICLE_H_
+
+#include "PhysicsCollisionObject.h"
+#include "PhysicsRigidBody.h"
+
+namespace gameplay
+{
+
+class Node;
+class PhysicsVehicleWheel;
+
+/**
+ * Defines a class for vehicle physics.
+ *
+ * In addition to its own properties defined below, a vehicle has available
+ * to it all of the properties of a rigid body such as shape, mass, friction,
+ * etc which correspond to the vehicle body:
+
+ @verbatim
+    collisionObject <vehicleID>
+    {
+        type           = VEHICLE
+
+        shape          = BOX        // collision shape for vehicle body
+        mass           = <float>    // mass of vehicle body
+        friction       = <float>    // friction of vehicle body
+        restitution    = <float>    // restitution of vehicle body
+        linearDamping  = <float>    // linear damping of vehicle body
+        angularDamping = <float>    // angular damping of vehicle body
+
+        // Vehicle steering, braking, and powertrain
+        steeringGain   = <float>    // steering at full deflection
+        brakingForce   = <float>    // braking force at full braking
+        drivingForce   = <float>    // driving force at full throttle
+    }
+ @endverbatim
+ */
+class PhysicsVehicle : public PhysicsCollisionObject
+{
+    friend class Node;
+    friend class PhysicsVehicleWheel;
+
+public:
+
+    /**
+     * @see PhysicsCollisionObject#getType
+     */
+    PhysicsCollisionObject::Type getType() const;
+
+    /**
+     * Returns the rigid body associated with this vehicle.
+     */
+    PhysicsRigidBody* getRigidBody() const;
+
+    /**
+     * Returns the number of wheels on this vehicle.
+     *
+     * @return the number of wheels on this vehicle.
+     */
+    unsigned int getNumWheels() const;
+
+    /**
+     * Gets the wheel at the specified index.
+     * 
+     * @param i index of wheel.
+     * @return the wheel at the specified index.
+     */
+    PhysicsVehicleWheel* getWheel(unsigned int i);
+
+    /**
+     * Permanently adds a wheel to this vehicle.
+     *
+     * @param wheel the wheel to add.
+     */
+    void addWheel(PhysicsVehicleWheel* wheel);
+
+    /**
+     * Returns an indication of vehicle speed in kilometers per hour.
+     */
+    float getSpeedKph() const;
+
+    /**
+     * Updates the vehicle state using the specified normalized command
+     * inputs, and updates the transform on the visual node for each wheel.
+     *
+     * @param steering steering command (-1 to 1).
+     * @param braking braking command (0 to 1).
+     * @param driving net drivetrain command (0 to 1).
+     */
+    void update(float steering, float braking, float driving);
+
+    /**
+     * Gets steering gain at full deflection.
+     *
+     * @return steering gain at full deflection.
+     */
+    float getSteeringGain() const;
+
+    /**
+     * Sets steering gain at full deflection.
+     *
+     * @param steeringGain steering gain at full deflection.
+     */
+    void setSteeringGain(float steeringGain);
+
+    /**
+     * Gets braking force at full braking.
+     *
+     * @return braking force at full braking.
+     */
+    float getBrakingForce() const;
+
+    /**
+     * Sets braking force at full braking.
+     *
+     * @param brakingForce braking force at full braking.
+     */
+    void setBrakingForce(float brakingForce);
+
+    /**
+     * Gets driving force at full throttle.
+     *
+     * @return driving force at full throttle.
+     */
+    float getDrivingForce() const;
+
+    /**
+     * Sets driving force at full throttle.
+     *
+     * @param drivingForce driving force at full throttle.
+     */
+    void setDrivingForce(float drivingForce);
+
+protected:
+
+    /**
+     * @see PhysicsCollisionObject::getCollisionObject
+     */
+    btCollisionObject* getCollisionObject() const;
+
+private:
+
+    /**
+     * Creates a vehicle based on the specified rigid body parameters and some 'safe' defaults.
+     * 
+     * @param node The node to create a rigid body for; note that the node must have
+     *      a model attached to it prior to creating a rigid body for it.
+     * @param shape The rigid body shape construction information.
+     * @param parameters The rigid body construction parameters.
+     */
+    PhysicsVehicle(Node* node, const PhysicsCollisionShape::Definition& shape, const PhysicsRigidBody::Parameters& parameters);
+
+    /**
+     * Creates a vehicle based on the given rigid body and some 'safe' defaults.
+     * 
+     * @param node The node to create a rigid body for; note that the node must have
+     *      a model attached to it prior to creating a rigid body for it.
+     * @param rigidBody The rigid body.
+     */
+    PhysicsVehicle(Node* node, PhysicsRigidBody* rigidBody);
+
+    /**
+     * Private copy constructor to prevent copying.
+     */
+    PhysicsVehicle(const PhysicsVehicle& src);
+
+    /**
+     * Private copy assignment operator.
+     */
+    PhysicsVehicle& operator=(const PhysicsVehicle&);
+
+    /**
+     * Creates a vehicle physics object from the specified properties object.
+     * 
+     * @param node The node to create a vehicle for; note that the node must have
+     *      a model attached to it prior to creating a vehicle for it.
+     * @param properties The properties object defining the vehicle (must have type equal to 'VEHICLE').
+     * @return The newly created vehicle, or <code>NULL</code> if the vehicle failed to load.
+     */
+    static PhysicsVehicle* create(Node* node, Properties* properties);
+
+    /**
+     * Initializes this vehicle and advertises itself among its ancestor nodes.
+     */
+    void initialize();
+
+    /**
+     * Destructor.
+     */
+    ~PhysicsVehicle();
+
+    float _steeringGain;
+    float _brakingForce;
+    float _drivingForce;
+    PhysicsRigidBody* _rigidBody;
+    btRaycastVehicle::btVehicleTuning _vehicleTuning;
+    btVehicleRaycaster* _vehicleRaycaster;
+    btRaycastVehicle* _vehicle;
+    std::vector<PhysicsVehicleWheel*> _wheels;
+};
+
+}
+
+#endif

+ 401 - 0
gameplay/src/PhysicsVehicleWheel.cpp

@@ -0,0 +1,401 @@
+#include "Base.h"
+#include "Node.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
+
+namespace gameplay
+{
+
+PhysicsVehicleWheel::PhysicsVehicleWheel(Node* node, const PhysicsCollisionShape::Definition& shape, const PhysicsRigidBody::Parameters& parameters)
+    : PhysicsCollisionObject(node)
+{
+    // Note that the constructor for PhysicsRigidBody calls addCollisionObject and so
+    // that is where the rigid body gets added to the dynamics world.
+    _rigidBody = new PhysicsRigidBody(node, shape, parameters);
+
+    findAncestorAndBind();
+}
+
+PhysicsVehicleWheel::PhysicsVehicleWheel(Node* node, PhysicsRigidBody* rigidBody)
+    : PhysicsCollisionObject(node)
+{
+    _rigidBody = rigidBody;
+
+    findAncestorAndBind();
+}
+
+PhysicsVehicleWheel* PhysicsVehicleWheel::create(Node* node, Properties* properties)
+{
+    // Note that the constructor for PhysicsRigidBody calls addCollisionObject and so
+    // that is where the rigid body gets added to the dynamics world.
+    PhysicsRigidBody* rigidBody = PhysicsRigidBody::create(node, properties, "VEHICLE_WHEEL");
+    PhysicsVehicleWheel* wheel = new PhysicsVehicleWheel(node, rigidBody);
+
+    // Load the defined wheel parameters.
+    properties->rewind();
+    Vector3 v;
+    const char* name;
+    while ((name = properties->getNextProperty()) != NULL)
+    {
+        if (strcmp(name, "isFront") == 0)
+        {
+            wheel->setFront(properties->getBool(name));
+        }
+        else if (strcmp(name, "wheelDirection") == 0 && properties->getVector3(name, &v))
+        {
+            wheel->setWheelDirection(v);
+        }
+        else if (strcmp(name, "wheelAxle") == 0 && properties->getVector3(name, &v))
+        {
+            wheel->setWheelAxle(v);
+        }
+        else if (strcmp(name, "strutConnectionPoint") == 0 && properties->getVector3(name, &v))
+        {
+            wheel->setStrutConnectionPoint(v);
+        }
+        else if (strcmp(name, "strutRestLength") == 0)
+        {
+            wheel->setStrutRestLength(properties->getFloat(name));
+        }
+        else if (strcmp(name, "strutTravelMax") == 0)
+        {
+            wheel->setStrutTravelMax(properties->getFloat(name));
+        }
+        else if (strcmp(name, "strutStiffness") == 0)
+        {
+            wheel->setStrutStiffness(properties->getFloat(name));
+        }
+        else if (strcmp(name, "strutDampingCompression") == 0)
+        {
+            wheel->setStrutDampingCompression(properties->getFloat(name));
+        }
+        else if (strcmp(name, "strutDampingRelaxation") == 0)
+        {
+            wheel->setStrutDampingRelaxation(properties->getFloat(name));
+        }
+        else if (strcmp(name, "strutForceMax") == 0)
+        {
+            wheel->setStrutForceMax(properties->getFloat(name));
+        }
+        else if (strcmp(name, "frictionBreakout") == 0)
+        {
+            wheel->setFrictionBreakout(properties->getFloat(name));
+        }
+        else if (strcmp(name, "wheelRadius") == 0)
+        {
+            wheel->setWheelRadius(properties->getFloat(name));
+        }
+        else if (strcmp(name, "rollInfluence") == 0)
+        {
+            wheel->setRollInfluence(properties->getFloat(name));
+        }
+        else
+        {
+            // Ignore this case (we've already parsed the rigid body parameters).
+        }
+    }
+
+    return wheel;
+}
+
+PhysicsVehicleWheel::~PhysicsVehicleWheel()
+{
+    SAFE_DELETE(_rigidBody);
+}
+
+btCollisionObject* PhysicsVehicleWheel::getCollisionObject() const
+{
+    GP_ASSERT(_rigidBody);
+
+    return _rigidBody->getCollisionObject();
+}
+
+PhysicsCollisionObject::Type PhysicsVehicleWheel::getType() const
+{
+    return PhysicsCollisionObject::VEHICLE_WHEEL;
+}
+
+void PhysicsVehicleWheel::findAncestorAndBind()
+{
+    GP_ASSERT(getNode());
+
+    // This is not an efficient algorithm if the number of advertised
+    // descendants gets large. In fact, this search is O(n*m) in the
+    // worst case with n nodes and m advertised descendants per node.
+    // But (1) we are only visiting ancestor nodes, and (2) the number
+    // of advertised descendants is expected to be small since this
+    // mechanism is currently only used for binding wheels onto a vehicle.
+    //
+    // TODO: revisit if the advertised descendants mechanism becomes popular.
+    PhysicsVehicle* host = NULL;
+    PhysicsCollisionObject* collisionObject;
+    Node* m;
+    for (Node* n = getNode()->getParent(); n && !host; n = n->getParent())
+    {
+        for (unsigned int i = 0; i < n->getNumAdvertisedDescendants() && !host; i++)
+        {
+            m = n->getAdvertisedDescendant(i);
+
+            collisionObject = m->getCollisionObject();
+            if (collisionObject && collisionObject->getType() == PhysicsCollisionObject::VEHICLE)
+            {
+                host = static_cast<PhysicsVehicle*>(collisionObject);
+            }
+        }
+    }
+
+    // Note: Currently this method is silent on failure to find a host.
+    if (host)
+    {
+        host->addWheel(this);
+    }
+}
+
+void PhysicsVehicleWheel::setHost(PhysicsVehicle* host, unsigned int indexInHost)
+{
+    _host = host;
+    _indexInHost = indexInHost;
+}
+
+void PhysicsVehicleWheel::addToVehicle(btRaycastVehicle* vehicle)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->getNumWheels() == vehicle->getNumWheels() + 1);
+
+    // Use safe defaults for now. Properties are assigned elsewhere.
+    btRaycastVehicle::btVehicleTuning tuning;
+    vehicle->addWheel(
+        btVector3(0, 0, 0),
+        btVector3(0, -1, 0),
+        btVector3(-1, 0, 0),
+        0.6f,
+        0.5f,
+        tuning,
+        false);
+}
+
+void PhysicsVehicleWheel::transform(Node* node) const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    const btTransform& trans = _host->_vehicle->getWheelInfo(_indexInHost).m_worldTransform;
+    const btQuaternion& rot = trans.getRotation();
+    const btVector3& pos = trans.getOrigin();
+    node->setRotation(rot.x(), rot.y(), rot.z(), rot.w());
+    node->setTranslation(pos.x(), pos.y(), pos.z());
+}
+
+bool PhysicsVehicleWheel::isFront() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_bIsFrontWheel;
+}
+
+void PhysicsVehicleWheel::setFront(bool front)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_bIsFrontWheel = front;
+}
+
+void PhysicsVehicleWheel::getWheelDirection(Vector3* wheelDirection) const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    const btVector3& v = _host->_vehicle->getWheelInfo(_indexInHost).m_wheelDirectionCS;
+    wheelDirection->set(v.x(), v.y(), v.z());
+}
+
+void PhysicsVehicleWheel::setWheelDirection(const Vector3& wheelDirection)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_wheelDirectionCS.setValue(wheelDirection.x, wheelDirection.y, wheelDirection.z);
+}
+
+void PhysicsVehicleWheel::getWheelAxle(Vector3* wheelAxle) const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    const btVector3& v = _host->_vehicle->getWheelInfo(_indexInHost).m_wheelAxleCS;
+    wheelAxle->set(v.x(), v.y(), v.z());
+}
+
+void PhysicsVehicleWheel::setWheelAxle(const Vector3& wheelAxle)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_wheelAxleCS.setValue( wheelAxle.x, wheelAxle.y, wheelAxle.z);
+}
+
+void PhysicsVehicleWheel::getStrutConnectionPoint(Vector3* strutConnectionPoint) const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    const btVector3& v = _host->_vehicle->getWheelInfo(_indexInHost).m_chassisConnectionPointCS;
+    strutConnectionPoint->set(v.x(), v.y(), v.z());
+}
+
+void PhysicsVehicleWheel::setStrutConnectionPoint(const Vector3& strutConnectionPoint)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+    _host->_vehicle->getWheelInfo(_indexInHost).m_chassisConnectionPointCS.setValue(strutConnectionPoint.x,
+                                                                                    strutConnectionPoint.y,
+                                                                                    strutConnectionPoint.z);
+}
+
+float PhysicsVehicleWheel::getStrutRestLength() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_suspensionRestLength1;
+}
+
+void PhysicsVehicleWheel::setStrutRestLength(float strutRestLength)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_suspensionRestLength1 = strutRestLength;
+}
+
+float PhysicsVehicleWheel::getStrutTravelMax() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_maxSuspensionTravelCm / 100.0f;
+}
+
+void PhysicsVehicleWheel::setStrutTravelMax(float strutTravelMax)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_maxSuspensionTravelCm = strutTravelMax * 100.0f;
+}
+
+float PhysicsVehicleWheel::getStrutStiffness() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_suspensionStiffness;
+}
+
+void PhysicsVehicleWheel::setStrutStiffness(float strutStiffness)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_suspensionStiffness = strutStiffness;
+}
+
+float PhysicsVehicleWheel::getStrutDampingCompression() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsDampingCompression;
+}
+
+void PhysicsVehicleWheel::setStrutDampingCompression(float strutDampingCompression)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsDampingCompression = strutDampingCompression;
+}
+
+float PhysicsVehicleWheel::getStrutDampingRelaxation() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsDampingRelaxation;
+}
+
+void PhysicsVehicleWheel::setStrutDampingRelaxation(float strutDampingRelaxation)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsDampingRelaxation = strutDampingRelaxation;
+}
+
+float PhysicsVehicleWheel::getStrutForceMax() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_maxSuspensionForce;
+}
+
+void PhysicsVehicleWheel::setStrutForceMax(float strutForceMax)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_maxSuspensionForce = strutForceMax;
+}
+
+float PhysicsVehicleWheel::getFrictionBreakout() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_frictionSlip;
+}
+
+void PhysicsVehicleWheel::setFrictionBreakout(float frictionBreakout)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_frictionSlip = frictionBreakout;
+}
+
+float PhysicsVehicleWheel::getWheelRadius() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsRadius;
+}
+
+void PhysicsVehicleWheel::setWheelRadius(float wheelRadius)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_wheelsRadius = wheelRadius;
+}
+
+float PhysicsVehicleWheel::getRollInfluence() const
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    return _host->_vehicle->getWheelInfo(_indexInHost).m_rollInfluence;
+}
+
+void PhysicsVehicleWheel::setRollInfluence(float rollInfluence)
+{
+    GP_ASSERT(_host);
+    GP_ASSERT(_host->_vehicle);
+
+    _host->_vehicle->getWheelInfo(_indexInHost).m_rollInfluence = rollInfluence;
+}
+
+}

+ 336 - 0
gameplay/src/PhysicsVehicleWheel.h

@@ -0,0 +1,336 @@
+#ifndef PHYSICSVEHICLEWHEEL_H_
+#define PHYSICSVEHICLEWHEEL_H_
+
+#include "PhysicsCollisionObject.h"
+#include "PhysicsRigidBody.h"
+
+namespace gameplay
+{
+
+class Node;
+class PhysicsVehicle;
+
+/**
+ * Defines a class for vehicle wheel physics which represents the individual wheel
+ * itself as well as the tire and suspension.
+ *
+ * The following properties are available for wheels:
+
+ @verbatim
+    collisionObject <wheelID>
+    {
+        type                     = VEHICLE_WHEEL
+
+        isFront                  = <bool>                // indicates whether this is a front wheel
+        wheelDirection           = <float, float, float> // direction strut extension, in chassis space
+        wheelAxle                = <float, float, float> // direction of axle (spin axis), in chassis space
+        strutConnectionPoint     = <float, float, float> // strut connection point, in chassis space
+        strutRestLength          = <float>               // strut rest length
+        strutTravelMax           = <float>               // maximum strut travel
+        strutStiffness           = <float>               // strut stiffness, normalized to chassis mass
+        strutDampingCompression  = <float>               // strut damping under compression, normalized to chassis mass
+        strutDampingRelaxation   = <float>               // strut damping under relaxation, normalized to chassis mass
+        strutForceMax            = <float>               // maximum strut force
+        frictionBreakout         = <float>               // breakout friction
+        wheelRadius              = <float>               // wheel radius
+        rollInfluence            = <float>               // how side friction affects chassis roll, normalized
+    }
+ @endverbatim
+ */
+
+class PhysicsVehicleWheel : public PhysicsCollisionObject
+{
+    friend class Node;
+    friend class PhysicsVehicle;
+
+public:
+
+    /**
+     * @see PhysicsCollisionObject#getType
+     */
+    PhysicsCollisionObject::Type getType() const;
+
+    /**
+     * Apply this wheel's world transform to the specified node.
+     * Useful for updating the specified visual node with the current
+     * transform.
+     *
+     * @param node the node to be transformed; (typically a visual
+     * representation of this wheel).
+     */
+    void transform(Node* node) const;
+
+    /**
+     * Returns true if this is a front wheel, false otherwise.
+     *
+     * @return true if this is a front wheel, false otherwise.
+     */
+    bool isFront() const;
+
+    /**
+     * Sets whether this is a front wheel.
+     *
+     * @param front true if this is a front wheel, false otherwise.
+     */
+    void setFront(bool front);
+
+    /**
+     * Gets direction of strut extension, in chassis space.
+     *
+     * @param wheelDirection address of where to store the result.
+     */
+    void getWheelDirection(Vector3* wheelDirection) const;
+
+    /**
+     * Sets direction of strut extension, in chassis space.
+     *
+     * @param wheelDirection direction of strut extension.
+     */
+    void setWheelDirection(const Vector3& wheelDirection);
+
+    /**
+     * Gets direction of axle (the spin axis), in chassis space.
+     *
+     * @param wheelAxle address of where to store the result.
+     */
+    void getWheelAxle(Vector3* wheelAxle) const;
+
+    /**
+     * Sets direction of axle (the spin axis), in chassis space.
+     *
+     * @param wheelAxle direction of axle (the spin axis).
+     */
+    void setWheelAxle(const Vector3& wheelAxle);
+
+    /**
+     * Gets strut connection point, in chassis space.
+     *
+     * @param strutConnectionPoint address of where to store the result.
+     */
+    void getStrutConnectionPoint(Vector3* strutConnectionPoint) const;
+
+    /**
+     * Sets strut connection point, in chassis space.
+     *
+     * @param strutConnectionPoint strut connection point.
+     */
+    void setStrutConnectionPoint(const Vector3& strutConnectionPoint);
+
+    /**
+     * Gets the strut rest length.
+     *
+     * @return the strut rest length.
+     */
+    float getStrutRestLength() const;
+
+    /**
+     * Sets the strut rest length.
+     *
+     * @param strutRestLength the strut rest length.
+     */
+    void setStrutRestLength(float strutRestLength);
+
+    /**
+     * Gets the maximum strut travel.
+     *
+     * @return the maximum strut travel.
+     */
+    float getStrutTravelMax() const;
+
+    /**
+     * Sets the maximum strut travel.
+     *
+     * @param strutTravelMax the maximum strut travel.
+     */
+    void setStrutTravelMax(float strutTravelMax);
+
+    /**
+     * Gets the strut stiffness, normalized to chassis mass.
+     *
+     * @return the strut stiffness, normalized to chassis mass.
+     */
+    float getStrutStiffness() const;
+
+    /**
+     * Sets the strut stiffness, normalized to chassis mass.
+     *
+     * @param strutStiffness the strut stiffness, normalized to chassis mass.
+     */
+    void setStrutStiffness(float strutStiffness);
+
+    /**
+     * Gets strut damping under compression, normalized to chassis mass.
+     *
+     * @return strut damping under compression, normalized to chassis mass.
+     */
+    float getStrutDampingCompression() const;
+
+    /**
+     * Sets strut damping under compression, normalized to chassis mass.
+     *
+     * @param strutDampingCompression strut damping under compression, normalized to chassis mass.
+     */
+    void setStrutDampingCompression(float strutDampingCompression);
+
+    /**
+     * Gets strut damping under relaxation, normalized to chassis mass.
+     *
+     * @return strut damping under relaxation, normalized to chassis mass.
+     */
+    float getStrutDampingRelaxation() const;
+
+    /**
+     * Sets strut damping under relaxation, normalized to chassis mass.
+     *
+     * @param strutDampingRelaxation strut damping under relaxation, normalized to chassis mass.
+     */
+    void setStrutDampingRelaxation(float strutDampingRelaxation);
+
+    /**
+     * Gets the maximum strut force.
+     *
+     * @return the maximum strut force.
+     */
+    float getStrutForceMax() const;
+
+    /**
+     * Sets the maximum strut force.
+     *
+     * @param strutForceMax the maximum strut force.
+     */
+    void setStrutForceMax(float strutForceMax);
+
+    /**
+     * Gets the breakout friction.
+     *
+     * @return the breakout friction.
+     */
+    float getFrictionBreakout() const;
+
+    /**
+     * Sets the breakout friction.
+     *
+     * @param frictionBreakout the breakout friction.
+     */
+    void setFrictionBreakout(float frictionBreakout);
+
+    /**
+     * Gets the wheel radius.
+     *
+     * @return the wheel radius.
+     */
+    float getWheelRadius() const;
+
+    /**
+     * Sets the wheel radius.
+     *
+     * @param wheelRadius the wheel radius.
+     */
+    void setWheelRadius(float wheelRadius);
+
+    /**
+     * Gets roll influence which determines how side friction affects chassis roll.
+     *
+     * @return roll influence, normalized factor.
+     */
+    float getRollInfluence() const;
+
+    /**
+     * Sets roll influence which determines how side friction affects chassis roll.
+     *
+     * @param rollInfluence roll influence, normalized factor.
+     */
+    void setRollInfluence(float rollInfluence);
+
+protected:
+
+    /**
+     * @see PhysicsCollisionObject::getCollisionObject
+     */
+    btCollisionObject* getCollisionObject() const;
+
+private:
+
+    /**
+     * Creates a vehicle wheel based on the specified rigid body parameters and some 'safe' defaults.
+     * Also, traverse up the scene graph until we find the first common ancestor with another node
+     * of collision type VEHICLE and add ourself as a wheel onto that vehicle. This assumes that the
+     * VEHICLE comes before the VEHICLE_WHEEL in the ".scene" (properties) file.
+     * 
+     * @param node The node to create a rigid body for; note that the node must have
+     *      a model attached to it prior to creating a rigid body for it.
+     * @param shape The rigid body shape construction information.
+     * @param parameters The rigid body construction parameters.
+     */
+    PhysicsVehicleWheel(Node* node, const PhysicsCollisionShape::Definition& shape, const PhysicsRigidBody::Parameters& parameters);
+
+    /**
+     * Creates a vehicle wheel based on the given rigid body and some 'safe' defaults.
+     * Also, traverse up the scene graph until we find the first common ancestor with another node
+     * of collision type VEHICLE and add ourself as a wheel onto that vehicle. This assumes that the
+     * VEHICLE comes before the VEHICLE_WHEEL in the ".scene" (properties) file.
+     * 
+     * @param node The node to create a rigid body for; note that the node must have
+     *      a model attached to it prior to creating a rigid body for it.
+     * @param rigidBody The rigid body.
+     */
+    PhysicsVehicleWheel(Node* node, PhysicsRigidBody* rigidBody);
+
+    /**
+     * Private copy constructor to prevent copying.
+     */
+    PhysicsVehicleWheel(const PhysicsVehicleWheel& src);
+
+    /**
+     * Private copy assignment operator.
+     */
+    PhysicsVehicleWheel& operator=(const PhysicsVehicleWheel&);
+
+    /**
+     * Creates a vehicle wheel physics object from the specified properties object.
+     * Also, traverse up the scene graph until we find the first common ancestor with another node
+     * of collision type VEHICLE and add ourself as a wheel onto that vehicle. This assumes that the
+     * VEHICLE comes before the VEHICLE_WHEEL in the ".scene" (properties) file.
+     * 
+     * @param node The node to create a wheel for; note that the node must have
+     *      a model attached to it prior to creating a vehicle wheel for it.
+     * @param properties The properties object defining the vehicle wheel (must have type equal to 'VEHICLE_WHEEL').
+     * @return The newly created wheel, or <code>NULL</code> if the vehicle wheel failed to load.
+     */
+    static PhysicsVehicleWheel* create(Node* node, Properties* properties);
+
+    /**
+     * Destructor.
+     */
+    ~PhysicsVehicleWheel();
+
+    /**
+     * Traverse up the visual scene graph. Upon finding the first ancestor node with an
+     * advertised descendant of collsion type VEHICLE, add this wheel onto the vehicle.
+     */
+    // Note: Currently this method is silent on failure to find a host.
+    void findAncestorAndBind();
+
+    /**
+     * Sets the host vehicle for this wheel.
+     *
+     * @param host the host vehicle.
+     * @param indexInHost the index of this wheel within the host vehicle.
+     */
+    void setHost(PhysicsVehicle* host, unsigned int indexInHost);
+
+    /**
+     * Adds this wheel to the specified Bullet vehicle.
+     *
+     * @param vehicle Bullet vehicle to add self to.
+     */
+    void addToVehicle(btRaycastVehicle* vehicle);
+
+    PhysicsRigidBody* _rigidBody;
+    PhysicsVehicle* _host;
+    unsigned int _indexInHost;
+};
+
+}
+
+#endif

+ 7 - 0
gameplay/src/Platform.h

@@ -207,6 +207,13 @@ public:
      */
      */
     static void unregisterGesture(Gesture::GestureEvent evt);
     static void unregisterGesture(Gesture::GestureEvent evt);
 
 
+    /**
+     * Tests if the specified gesture is registered for gesture recognition for the specified gesture event
+     *
+     * @param evt The gesture event to register to start recognizing events for.
+     */
+    static bool isGestureRegistered(Gesture::GestureEvent evt);
+    
     /** 
     /** 
      * Gets the number of gamepad devices connected to the Platform.
      * Gets the number of gamepad devices connected to the Platform.
      *
      *

+ 205 - 29
gameplay/src/PlatformAndroid.cpp

@@ -7,10 +7,8 @@
 #include "Form.h"
 #include "Form.h"
 #include "ScriptController.h"
 #include "ScriptController.h"
 #include <unistd.h>
 #include <unistd.h>
-
 #include <android/sensor.h>
 #include <android/sensor.h>
 #include <android_native_app_glue.h>
 #include <android_native_app_glue.h>
-
 #include <android/log.h>
 #include <android/log.h>
 
 
 // Externally referenced global variables.
 // Externally referenced global variables.
@@ -45,6 +43,24 @@ PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
 PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 
 
+#define GESTURE_TAP_DURATION_MAX    200
+#define GESTURE_SWIPE_DURATION_MAX  400
+#define GESTURE_SWIPE_DISTANCE_MIN  50
+
+static std::bitset<3> __gestureEventsProcessed;
+
+struct TouchPointerData
+{
+    size_t pointerId;
+    bool pressed;
+    double time;
+    int x;
+    int y;
+};
+
+TouchPointerData __pointer0;
+TouchPointerData __pointer1;
+
 namespace gameplay
 namespace gameplay
 {
 {
 
 
@@ -579,50 +595,177 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
         size_t pointerIndex;
         size_t pointerIndex;
         size_t pointerId;
         size_t pointerId;
         size_t pointerCount;
         size_t pointerCount;
+        int x;
+        int y;
+        
         switch (action & AMOTION_EVENT_ACTION_MASK)
         switch (action & AMOTION_EVENT_ACTION_MASK)
         {
         {
             case AMOTION_EVENT_ACTION_DOWN:
             case AMOTION_EVENT_ACTION_DOWN:
-                // Primary pointer down.
-                pointerId = AMotionEvent_getPointerId(event, 0);
-                gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), pointerId);
-                __primaryTouchId = pointerId;
+                {
+                    pointerId = AMotionEvent_getPointerId(event, 0);
+                    x = AMotionEvent_getX(event, 0);
+                    y = AMotionEvent_getY(event, 0);
+
+                    // Gesture handling
+                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
+                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
+                    {
+                        __pointer0.pressed = true;
+                        __pointer0.time = Game::getInstance()->getAbsoluteTime();
+                        __pointer0.pointerId = pointerId;
+                        __pointer0.x = x;
+                        __pointer0.y = y;
+                    }
+
+                    // Primary pointer down.
+                    gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
+                    __primaryTouchId = pointerId;
+                }
                 break;
                 break;
+
             case AMOTION_EVENT_ACTION_UP:
             case AMOTION_EVENT_ACTION_UP:
-                pointerId = AMotionEvent_getPointerId(event, 0);
-                if (__multiTouch || __primaryTouchId == pointerId)
                 {
                 {
-                    gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), pointerId);
+                    pointerId = AMotionEvent_getPointerId(event, 0);
+                    x = AMotionEvent_getX(event, 0);
+                    y = AMotionEvent_getY(event, 0);
+                    
+                    // Gestures
+                    bool gestureDetected = false;
+                    if ( __pointer0.pressed &&  __pointer0.pointerId == pointerId)
+                    {
+                        int deltaX = x - __pointer0.x;
+                        int deltaY = y - __pointer0.y;
+
+                        // Test for swipe
+                        if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
+                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX && 
+                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
+                        {
+                            int direction = 0;
+                            if ( abs(deltaX) > abs(deltaY) )
+                            {
+                                if (deltaX > 0)
+                                    direction = gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
+                                else if (deltaX < 0)
+                                    direction = gameplay::Gesture::SWIPE_DIRECTION_LEFT;
+                            }
+                            else
+                            {
+                                if (deltaY > 0)
+                                    direction = gameplay::Gesture::SWIPE_DIRECTION_UP;
+                                else if (deltaY < 0)
+                                    direction = gameplay::Gesture::SWIPE_DIRECTION_DOWN;
+                            }
+                            gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
+                            __pointer0.pressed = false;
+                            gestureDetected = true;
+                        }
+                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
+                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
+                        {
+                            gameplay::Game::getInstance()->gestureTapEvent(x, y);
+                            __pointer0.pressed = false;
+                            gestureDetected = true;
+                        }
+                    }
+
+                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
+                    {
+                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, x, y, pointerId);
+                    }
+                    __primaryTouchId = -1;
                 }
                 }
-                __primaryTouchId = -1;
                 break;
                 break;
+
             case AMOTION_EVENT_ACTION_POINTER_DOWN:
             case AMOTION_EVENT_ACTION_POINTER_DOWN:
-                // Non-primary pointer down.
-                if (__multiTouch)
                 {
                 {
-                    pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                    pointerId = AMotionEvent_getPointerId(event, pointerIndex);
-                    gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
+                    pointerId = AMotionEvent_getPointerId(event, 0);
+                    x = AMotionEvent_getX(event, 0);
+                    y = AMotionEvent_getY(event, 0);
+
+                    // Gesture handling
+                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
+                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
+                    {
+                        __pointer1.pressed = true;
+                        __pointer1.time = Game::getInstance()->getAbsoluteTime();
+                        __pointer1.pointerId = pointerId;
+                        __pointer1.x = x;
+                        __pointer1.y = y;
+                    }
+
+                    // Non-primary pointer down.
+                    if (__multiTouch)
+                    {
+                        pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                        pointerId = AMotionEvent_getPointerId(event, pointerIndex);
+                        gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
+                    }
                 }
                 }
                 break;
                 break;
+
             case AMOTION_EVENT_ACTION_POINTER_UP:
             case AMOTION_EVENT_ACTION_POINTER_UP:
-                pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                pointerId = AMotionEvent_getPointerId(event, pointerIndex);
-                if (__multiTouch || __primaryTouchId == pointerId)
                 {
                 {
-                    gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
+                    pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                    pointerId = AMotionEvent_getPointerId(event, 0);
+                    x = AMotionEvent_getX(event, 0);
+                    y = AMotionEvent_getY(event, 0);
+
+                    bool gestureDetected = false;
+                    if ( __pointer1.pressed &&  __pointer1.pointerId == pointerId)
+                    {
+                        int deltaX = x - __pointer1.x;
+                        int deltaY = y - __pointer1.y;
+
+                        // Test for swipe
+                        if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
+                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_SWIPE_DURATION_MAX && 
+                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
+                        {
+                            int direction;
+                            if (deltaX > 0)
+                                direction |= gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
+                            else if (deltaX < 0)
+                                direction |= gameplay::Gesture::SWIPE_DIRECTION_LEFT;
+                            
+                            if (deltaY > 0)
+                                direction |= gameplay::Gesture::SWIPE_DIRECTION_UP;
+                            else if (deltaY < 0)
+                                direction |= gameplay::Gesture::SWIPE_DIRECTION_DOWN;
+
+                            gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
+                            __pointer1.pressed = false;
+                            gestureDetected = true;
+                        }
+                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
+                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_TAP_DURATION_MAX)
+                        {
+                            gameplay::Game::getInstance()->gestureTapEvent(x, y);
+                            __pointer1.pressed = false;
+                            gestureDetected = true;
+                        }
+                    }
+
+                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
+                    {
+                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
+                    }
+                    if (__primaryTouchId == pointerId)
+                        __primaryTouchId = -1;
                 }
                 }
-                if (__primaryTouchId == pointerId)
-                    __primaryTouchId = -1;
                 break;
                 break;
+
             case AMOTION_EVENT_ACTION_MOVE:
             case AMOTION_EVENT_ACTION_MOVE:
-                // ACTION_MOVE events are batched, unlike the other events.
-                pointerCount = AMotionEvent_getPointerCount(event);
-                for (size_t i = 0; i < pointerCount; ++i)
                 {
                 {
-                    pointerId = AMotionEvent_getPointerId(event, i);
-                    if (__multiTouch || __primaryTouchId == pointerId)
+                    // ACTION_MOVE events are batched, unlike the other events.
+                    pointerCount = AMotionEvent_getPointerCount(event);
+                    for (size_t i = 0; i < pointerCount; ++i)
                     {
                     {
-                        gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
+                        pointerId = AMotionEvent_getPointerId(event, i);
+                        if (__multiTouch || __primaryTouchId == pointerId)
+                        {
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
+                        }
                     }
                     }
                 }
                 }
                 break;
                 break;
@@ -1014,15 +1157,49 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
 
 
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
 {
-    return false;
+    // Pinch currently not implemented
+    return evt == gameplay::Gesture::GESTURE_SWIPE || evt == gameplay::Gesture::GESTURE_TAP;
 }
 }
 
 
 void Platform::registerGesture(Gesture::GestureEvent evt)
 void Platform::registerGesture(Gesture::GestureEvent evt)
 {
 {
+    switch(evt)
+    {
+    case Gesture::GESTURE_ANY_SUPPORTED:
+        __gestureEventsProcessed.set();
+        break;
+
+    case Gesture::GESTURE_TAP:
+    case Gesture::GESTURE_SWIPE:
+        __gestureEventsProcessed.set(evt);
+        break;
+
+    default:
+        break;
+    }
 }
 }
 
 
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 {
 {
+    switch(evt)
+    {
+    case Gesture::GESTURE_ANY_SUPPORTED:
+        __gestureEventsProcessed.reset();
+        break;
+
+    case Gesture::GESTURE_TAP:
+    case Gesture::GESTURE_SWIPE:
+        __gestureEventsProcessed.set(evt, 0);
+        break;
+
+    default:
+        break;
+    }
+}
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return __gestureEventsProcessed.test(evt);
 }
 }
 
 
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()
@@ -1072,7 +1249,6 @@ float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int
 
 
 void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
 void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
 {
 {
-
 }
 }
 
 
 unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
 unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)

+ 31 - 26
gameplay/src/PlatformLinux.cpp

@@ -426,10 +426,10 @@ Platform* Platform::create(Game* game, void* attachToWindow)
     GLXFBConfig* configs;
     GLXFBConfig* configs;
     int configCount = 0;
     int configCount = 0;
     configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
     configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
-    if( configCount == 0 || configs == 0 )	
-    {	
+    if( configCount == 0 || configs == 0 )    
+    {    
         perror( "glXChooseFBConfig" );
         perror( "glXChooseFBConfig" );
-        return NULL;	
+        return NULL;    
     }
     }
 
 
     // Create the windows
     // Create the windows
@@ -494,11 +494,11 @@ void cleanupX11()
         glXMakeCurrent(__display, None, NULL);
         glXMakeCurrent(__display, None, NULL);
 
 
         if (__context)
         if (__context)
-     	    glXDestroyContext(__display, __context);
+             glXDestroyContext(__display, __context);
         if (__window)
         if (__window)
-     	    XDestroyWindow(__display, __window);
+             XDestroyWindow(__display, __window);
 
 
-     	XCloseDisplay(__display);
+         XCloseDisplay(__display);
     }
     }
 }
 }
 
 
@@ -508,14 +508,14 @@ double timespec2millis(struct timespec *a)
     return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
     return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
 }
 }
 
 
-void updateWindowSize()	
-{	
-    GP_ASSERT(__display);	
+void updateWindowSize()    
+{    
+    GP_ASSERT(__display);    
     GP_ASSERT(__window);
     GP_ASSERT(__window);
-    XWindowAttributes windowAttrs;	
-    XGetWindowAttributes(__display, __window, &windowAttrs);  	
-    __windowSize[0] = windowAttrs.width;	
-    __windowSize[1] = windowAttrs.height;	
+    XWindowAttributes windowAttrs;    
+    XGetWindowAttributes(__display, __window, &windowAttrs);      
+    __windowSize[0] = windowAttrs.width;    
+    __windowSize[1] = windowAttrs.height;    
 }
 }
 
 
 int Platform::enterMessagePump()
 int Platform::enterMessagePump()
@@ -540,9 +540,9 @@ int Platform::enterMessagePump()
     // Run the game.
     // Run the game.
     _game->run();
     _game->run();
 
 
-    // Setup select for message handling (to allow non-blocking)	
+    // Setup select for message handling (to allow non-blocking)    
     int x11_fd = ConnectionNumber(__display);
     int x11_fd = ConnectionNumber(__display);
-	
+    
     pollfd xpolls[1];
     pollfd xpolls[1];
     xpolls[0].fd = x11_fd;
     xpolls[0].fd = x11_fd;
     xpolls[0].events = POLLIN|POLLPRI;
     xpolls[0].events = POLLIN|POLLPRI;
@@ -845,17 +845,22 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
     }
     }
 }
 }
 
 
-bool Platform::isGestureSupported(Gesture::GestureEvent evt)
-{
-    return false;
-}
-
-void Platform::registerGesture(Gesture::GestureEvent evt)
-{
-}
-
-void Platform::unregisterGesture(Gesture::GestureEvent evt)
-{
+bool Platform::isGestureSupported(Gesture::GestureEvent evt)
+{
+    return false;
+}
+
+void Platform::registerGesture(Gesture::GestureEvent evt)
+{
+}
+
+void Platform::unregisterGesture(Gesture::GestureEvent evt)
+{
+}
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return false;
 }
 }
 
 
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()

+ 71 - 3
gameplay/src/PlatformMacOSX.mm

@@ -57,11 +57,12 @@ double getMachTimeInMilliseconds()
 
 
 @class View;
 @class View;
 
 
-@interface View : NSOpenGLView <NSWindowDelegate> 
+@interface View : NSOpenGLView <NSWindowDelegate>
 {
 {
     CVDisplayLinkRef displayLink;
     CVDisplayLinkRef displayLink;
     NSRecursiveLock* lock;
     NSRecursiveLock* lock;
     Game* _game;
     Game* _game;
+    unsigned int _gestureEvents;    
 }
 }
 
 
 @end
 @end
@@ -600,6 +601,55 @@ int getKey(unsigned short keyCode, unsigned int modifierFlags)
     gameplay::Platform::keyEventInternal(Keyboard::KEY_RELEASE, getKey([event keyCode], [event modifierFlags]));
     gameplay::Platform::keyEventInternal(Keyboard::KEY_RELEASE, getKey([event keyCode], [event modifierFlags]));
 }
 }
 
 
+
+// Gesture support for Mac OS X Trackpads
+- (bool)isGestureRegistered: (Gesture::GestureEvent) evt {
+    return ((_gestureEvents & evt) == evt);
+}
+- (void)registerGesture: (Gesture::GestureEvent) evt {
+    _gestureEvents |= evt;
+}
+- (void)unregisterGesture: (Gesture::GestureEvent) evt {
+    _gestureEvents &= (~evt);
+}
+
+
+- (void)magnifyWithEvent:(NSEvent *)event
+{
+    if([self isGestureRegistered:Gesture::GESTURE_PINCH] == false) return;
+    
+    NSSet *touches = [event touchesMatchingPhase:NSTouchPhaseAny  inView:nil];
+    // Approximate the center by adding and averageing for now
+    // Note this is centroid on the physical device be used for touching, not the display
+    float xavg = 0.0f;
+    float yavg = 0.0f;
+    for(NSTouch *t in touches) {
+        xavg += [t normalizedPosition].x;
+        yavg += [t normalizedPosition].y;
+    }
+    xavg /= [touches count];
+    yavg /= [touches count];
+    
+    _game->gesturePinchEvent((int)xavg, (int)yavg, [event magnification]);
+}
+- (void)swipeWithEvent:(NSEvent *)event
+{
+    if([self isGestureRegistered:Gesture::GESTURE_SWIPE] == false) return;
+    /**
+     * Gesture callback on Gesture::SWIPE events.
+     *
+     * @param x The x-coordinate of the start of the swipe.
+     * @param y The y-coordinate of the start of the swipe.
+     * @param direction The direction of the swipe
+     *
+     * @see Gesture::SWIPE_DIRECTION_UP
+     * @see Gesture::SWIPE_DIRECTION_DOWN
+     * @see Gesture::SWIPE_DIRECTION_LEFT
+     * @see Gesture::SWIPE_DIRECTION_RIGHT
+     */
+    //virtual void gestureSwipeEvent(int x, int y, int direction);
+}
+
 @end
 @end
 
 
 @interface FullscreenWindow : NSWindow
 @interface FullscreenWindow : NSWindow
@@ -638,7 +688,7 @@ Platform::~Platform()
 
 
 Platform* Platform::create(Game* game, void* attachToWindow)
 Platform* Platform::create(Game* game, void* attachToWindow)
 {
 {
-	__attachToWindow = attachToWindow;
+    __attachToWindow = attachToWindow;
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
     
     
     return platform;
     return platform;
@@ -775,7 +825,7 @@ void Platform::setMultiTouch(bool enabled)
     
     
 bool Platform::isMultiTouch()
 bool Platform::isMultiTouch()
 {
 {
-    return false;
+    return true;
 }
 }
     
     
 void Platform::getAccelerometerValues(float* pitch, float* roll)
 void Platform::getAccelerometerValues(float* pitch, float* roll)
@@ -881,16 +931,34 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
 
 
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
 {
+    // TODO: Support Swipe and Tap
+    switch(evt)
+    {
+        case Gesture::GESTURE_PINCH:
+            return true;
+        default:
+            break;
+    }
     return false;
     return false;
 }
 }
 
 
 void Platform::registerGesture(Gesture::GestureEvent evt)
 void Platform::registerGesture(Gesture::GestureEvent evt)
 {
 {
+    [__view registerGesture:evt];
 }
 }
 
 
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 {
 {
+    [__view unregisterGesture:evt];
 }
 }
+  
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+     return [__view isGestureRegistered:evt];
+}
+
+    
+
 
 
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()
 {
 {

+ 86 - 72
gameplay/src/PlatformQNX.cpp

@@ -45,6 +45,7 @@ static float __roll;
 static const char* __glExtensions;
 static const char* __glExtensions;
 static struct gestures_set * __gestureSet;
 static struct gestures_set * __gestureSet;
 static bitset<3> __gestureEventsProcessed;
 static bitset<3> __gestureEventsProcessed;
+static bool __gestureSwipeRecognized = false;
 PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
 PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
 PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
 PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
@@ -450,7 +451,12 @@ void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* para
             if ( __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
             if ( __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
             {
             {
                 gesture_swipe_t* swipe = (gesture_swipe_t*)gesture;
                 gesture_swipe_t* swipe = (gesture_swipe_t*)gesture;
-                Game::getInstance()->gestureSwipeEvent(swipe->coords.x, swipe->coords.y, swipe->direction);
+                if (!__gestureSwipeRecognized)
+                {
+                    Game::getInstance()->gestureSwipeEvent(swipe->coords.x, swipe->coords.y, swipe->direction);
+                    __gestureSwipeRecognized = true;
+                }
+
             }
             }
             break;
             break;
         }
         }
@@ -565,8 +571,8 @@ Platform* Platform::create(Game* game, void* attachToWindow)
     int screenSwapInterval = WINDOW_VSYNC ? 1 : 0;
     int screenSwapInterval = WINDOW_VSYNC ? 1 : 0;
     int screenTransparency = SCREEN_TRANSPARENCY_NONE;
     int screenTransparency = SCREEN_TRANSPARENCY_NONE;
 
 
-	char *width_str = getenv("WIDTH");
-	char *height_str = getenv("HEIGHT");
+    char *width_str = getenv("WIDTH");
+    char *height_str = getenv("HEIGHT");
 
 
     // Hard-coded to (0,0).
     // Hard-coded to (0,0).
     int windowPosition[] =
     int windowPosition[] =
@@ -633,74 +639,74 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         goto error;
         goto error;
     }
     }
 
 
-	if (width_str && height_str)
-	{
-		__screenWindowSize[0] = atoi(width_str);
-		__screenWindowSize[1] = atoi(height_str);
-	}
-	else
-	{
-		int angle = atoi(getenv("ORIENTATION"));
-
-		screen_display_t screen_display;
-		rc = screen_get_window_property_pv(__screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_display);
-		if (rc)
-		{
-			perror("screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)");
-			goto error;
-		}
-
-		screen_display_mode_t screen_mode;
-		rc = screen_get_display_property_pv(screen_display, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
-		if (rc)
-		{
-			perror("screen_get_display_property_pv(SCREEN_PROPERTY_MODE)");
-			goto error;
-		}
-
-		int size[2];
-		rc = screen_get_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
-		if (rc)
-		{
-			perror("screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
-			goto error;
-		}
-
-		__screenWindowSize[0] = size[0];
-		__screenWindowSize[1] = size[1];
-
-		if ((angle == 0) || (angle == 180))
-		{
-			if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
-				((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
-			{
-				__screenWindowSize[1] = size[0];
-				__screenWindowSize[0] = size[1];
-			}
-		}
-		else if ((angle == 90) || (angle == 270))
-		{
-			if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
-				((screen_mode.width < screen_mode.height) && (size[0] < size[1])))
-			{
-				__screenWindowSize[1] = size[0];
-				__screenWindowSize[0] = size[1];
-			}
-		}
-		else
-		{
-			perror("Navigator returned an unexpected orientation angle.");
-			goto error;
-		}
-
-
-	    rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_ROTATION, &angle);
-	    if (rc)
-	    {
-	        perror("screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)");
-	        goto error;
-	    }
-	}
+    if (width_str && height_str)
+    {
+        __screenWindowSize[0] = atoi(width_str);
+        __screenWindowSize[1] = atoi(height_str);
+    }
+    else
+    {
+        int angle = atoi(getenv("ORIENTATION"));
+
+        screen_display_t screen_display;
+        rc = screen_get_window_property_pv(__screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_display);
+        if (rc)
+        {
+            perror("screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)");
+            goto error;
+        }
+
+        screen_display_mode_t screen_mode;
+        rc = screen_get_display_property_pv(screen_display, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
+        if (rc)
+        {
+            perror("screen_get_display_property_pv(SCREEN_PROPERTY_MODE)");
+            goto error;
+        }
+
+        int size[2];
+        rc = screen_get_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size);
+        if (rc)
+        {
+            perror("screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)");
+            goto error;
+        }
+
+        __screenWindowSize[0] = size[0];
+        __screenWindowSize[1] = size[1];
+
+        if ((angle == 0) || (angle == 180))
+        {
+            if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
+                ((screen_mode.width < screen_mode.height) && (size[0] > size[1])))
+            {
+                __screenWindowSize[1] = size[0];
+                __screenWindowSize[0] = size[1];
+            }
+        }
+        else if ((angle == 90) || (angle == 270))
+        {
+            if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
+                ((screen_mode.width < screen_mode.height) && (size[0] < size[1])))
+            {
+                __screenWindowSize[1] = size[0];
+                __screenWindowSize[0] = size[1];
+            }
+        }
+        else
+        {
+            perror("Navigator returned an unexpected orientation angle.");
+            goto error;
+        }
+
+
+        rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_ROTATION, &angle);
+        if (rc)
+        {
+            perror("screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)");
+            goto error;
+        }
+    }
 
 
     rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, __screenWindowSize);
     rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, __screenWindowSize);
     if (rc)
     if (rc)
@@ -844,7 +850,6 @@ int Platform::enterMessagePump()
     int position[2];
     int position[2];
     int domain;
     int domain;
     mtouch_event_t touchEvent;
     mtouch_event_t touchEvent;
-    int touchId = 0;
     bool suspended = false;
     bool suspended = false;
 
 
     // Get the initial time.
     // Get the initial time.
@@ -898,6 +903,10 @@ int Platform::enterMessagePump()
                         {
                         {
                             gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
                             gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, touchEvent.x, touchEvent.y, touchEvent.contact_id);
                         }
                         }
+                        if (__gestureSwipeRecognized)
+                        {
+                            __gestureSwipeRecognized = false;
+                        }
                         break;
                         break;
                     }
                     }
 
 
@@ -1312,6 +1321,11 @@ void Platform::unregisterGesture(Gesture::GestureEvent evt)
         break;
         break;
     }
     }
 }
 }
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return __gestureEventsProcessed.test(evt);
+}
 
 
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()
 {
 {

+ 5 - 1
gameplay/src/PlatformWin32.cpp

@@ -1027,7 +1027,6 @@ error:
 int Platform::enterMessagePump()
 int Platform::enterMessagePump()
 {
 {
     GP_ASSERT(_game);
     GP_ASSERT(_game);
-    int rc = 0;
 
 
     // Get the initial time.
     // Get the initial time.
     LARGE_INTEGER tps;
     LARGE_INTEGER tps;
@@ -1218,6 +1217,11 @@ void Platform::registerGesture(Gesture::GestureEvent evt)
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 {
 {
 }
 }
+    
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return false;
+}
 
 
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()
 {
 {

+ 119 - 15
gameplay/src/PlatformiOS.mm

@@ -51,7 +51,7 @@ int getKey(unichar keyCode);
 
 
 @interface View : UIView <UIKeyInput>
 @interface View : UIView <UIKeyInput>
 {
 {
-    EAGLContext* context;	
+    EAGLContext* context;
     CADisplayLink* displayLink;
     CADisplayLink* displayLink;
     GLuint defaultFramebuffer;
     GLuint defaultFramebuffer;
     GLuint colorRenderbuffer;
     GLuint colorRenderbuffer;
@@ -61,6 +61,10 @@ int getKey(unichar keyCode);
     NSInteger swapInterval;
     NSInteger swapInterval;
     BOOL updating;
     BOOL updating;
     Game* _game;
     Game* _game;
+    
+    UITapGestureRecognizer *_tapRecognizer;
+    UIPinchGestureRecognizer *_pinchRecognizer;
+    UISwipeGestureRecognizer *_swipeRecognizer;
 }
 }
 
 
 @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
 @property (readonly, nonatomic, getter=isUpdating) BOOL updating;
@@ -237,7 +241,7 @@ int getKey(unichar keyCode);
 {
 {
     if (interval >= 1)
     if (interval >= 1)
     {
     {
-        swapInterval = interval;		
+        swapInterval = interval;        
         if (updating)
         if (updating)
         {
         {
             [self stopUpdating];
             [self stopUpdating];
@@ -384,6 +388,98 @@ int getKey(unichar keyCode);
     }
     }
 }
 }
 
 
+// Gesture support for Mac OS X Trackpads
+- (bool)isGestureRegistered: (Gesture::GestureEvent) evt
+{
+    switch(evt) {
+        case Gesture::GESTURE_SWIPE:
+            return (_swipeRecognizer != NULL);
+        case Gesture::GESTURE_PINCH:
+            return (_pinchRecognizer != NULL);
+        case Gesture::GESTURE_TAP:
+            return (_tapRecognizer != NULL);
+        default:
+            break;
+    }
+    return false;
+}
+
+- (void)registerGesture: (Gesture::GestureEvent) evt
+{
+    if((evt & Gesture::GESTURE_SWIPE) == Gesture::GESTURE_SWIPE && _swipeRecognizer == NULL)
+    {
+        _swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
+        [self addGestureRecognizer:_swipeRecognizer];
+    }
+    if((evt & Gesture::GESTURE_PINCH) == Gesture::GESTURE_PINCH && _pinchRecognizer == NULL)
+    {
+        _pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
+        [self addGestureRecognizer:_pinchRecognizer];
+    }
+    if((evt & Gesture::GESTURE_TAP) == Gesture::GESTURE_TAP && _tapRecognizer == NULL)
+    {
+        _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
+        [self addGestureRecognizer:_swipeRecognizer];
+    }
+}
+
+- (void)unregisterGesture: (Gesture::GestureEvent) evt
+{
+    if((evt & Gesture::GESTURE_SWIPE) == Gesture::GESTURE_SWIPE && _swipeRecognizer != NULL)
+    {
+        [self removeGestureRecognizer:_swipeRecognizer];
+        [_swipeRecognizer release];
+        _swipeRecognizer = NULL;
+    }
+    if((evt & Gesture::GESTURE_PINCH) == Gesture::GESTURE_PINCH && _pinchRecognizer != NULL)
+    {
+        [self removeGestureRecognizer:_pinchRecognizer];
+        [_pinchRecognizer release];
+        _pinchRecognizer = NULL;
+    }
+    if((evt & Gesture::GESTURE_TAP) == Gesture::GESTURE_TAP && _tapRecognizer != NULL)
+    {
+        [self removeGestureRecognizer:_tapRecognizer];
+        [_tapRecognizer release];
+        _tapRecognizer = NULL;
+    }
+}
+
+- (void)handleTapGesture:(UITapGestureRecognizer *)sender
+{
+    CGPoint location = [sender locationInView:self];
+    _game->gestureTapEvent(location.x, location.y);
+}
+
+- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender
+{
+    CGFloat factor = [sender scale];
+    CGPoint location = [sender locationInView:self];
+    _game->gesturePinchEvent(location.x, location.y, factor);
+}
+
+- (void)handleSwipeGesture:(UISwipeGestureRecognizer *)sender
+{
+    UISwipeGestureRecognizerDirection direction = [sender direction];
+    CGPoint location = [sender locationInView:self];
+    int gameplayDirection = 0;
+    switch(direction) {
+        case UISwipeGestureRecognizerDirectionRight:
+            gameplayDirection = Gesture::SWIPE_DIRECTION_RIGHT;
+            break;
+        case UISwipeGestureRecognizerDirectionLeft:
+            gameplayDirection = Gesture::SWIPE_DIRECTION_LEFT;
+            break;
+        case UISwipeGestureRecognizerDirectionUp:
+            gameplayDirection = Gesture::SWIPE_DIRECTION_UP;
+            break;
+        case UISwipeGestureRecognizerDirectionDown:
+            gameplayDirection = Gesture::SWIPE_DIRECTION_DOWN;
+            break;
+    }
+    _game->gestureSwipeEvent(location.x, location.y, gameplayDirection);
+}
+
 @end
 @end
 
 
 
 
@@ -555,7 +651,7 @@ int getKey(unichar keyCode);
 }
 }
 
 
 - (void)applicationWillEnterForeground:(UIApplication*)application 
 - (void)applicationWillEnterForeground:(UIApplication*)application 
-{	
+{    
     [viewController startUpdating];
     [viewController startUpdating];
 }
 }
 
 
@@ -565,7 +661,7 @@ int getKey(unichar keyCode);
 }
 }
 
 
 - (void)applicationWillTerminate:(UIApplication*)application 
 - (void)applicationWillTerminate:(UIApplication*)application 
-{	
+{    
     [viewController stopUpdating];
     [viewController stopUpdating];
 }
 }
 
 
@@ -988,19 +1084,27 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
     }
     }
 }    
 }    
 
 
-bool Platform::isGestureSupported(Gesture::GestureEvent evt)
-{
-    return false;
-}
-
-void Platform::registerGesture(Gesture::GestureEvent evt)
-{
-}
-
-void Platform::unregisterGesture(Gesture::GestureEvent evt)
-{
+bool Platform::isGestureSupported(Gesture::GestureEvent evt)
+{
+    return true;
 }
 }
 
 
+void Platform::registerGesture(Gesture::GestureEvent evt)
+{
+    [__view registerGesture:evt];
+}
+
+void Platform::unregisterGesture(Gesture::GestureEvent evt)
+{
+    [__view unregisterGesture:evt];
+}
+
+bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
+{
+    return [__view isGestureRegistered:evt];
+}
+
+
 unsigned int Platform::getGamepadsConnected()
 unsigned int Platform::getGamepadsConnected()
 {
 {
     return 0;
     return 0;

+ 8 - 14
gameplay/src/Properties.cpp

@@ -17,15 +17,11 @@ Properties::Properties()
 }
 }
 
 
 Properties::Properties(const Properties& copy)
 Properties::Properties(const Properties& copy)
+    : _namespace(copy._namespace), _id(copy._id), _parentID(copy._parentID), _properties(copy._properties)
 {
 {
-    _namespace = copy._namespace;
-    _id = copy._id;
-    _parentID = copy._parentID;
-    _properties = copy._properties;
-    
     _namespaces = std::vector<Properties*>();
     _namespaces = std::vector<Properties*>();
     std::vector<Properties*>::const_iterator it;
     std::vector<Properties*>::const_iterator it;
-    for (it = copy._namespaces.begin(); it < copy._namespaces.end(); it++)
+    for (it = copy._namespaces.begin(); it < copy._namespaces.end(); ++it)
     {
     {
         GP_ASSERT(*it);
         GP_ASSERT(*it);
         _namespaces.push_back(new Properties(**it));
         _namespaces.push_back(new Properties(**it));
@@ -327,7 +323,7 @@ void Properties::readProperties(FILE* file)
 Properties::~Properties()
 Properties::~Properties()
 {
 {
     unsigned int count = _namespaces.size();
     unsigned int count = _namespaces.size();
-    for (unsigned int i = 0; i < count; i++)
+    for (unsigned int i = 0; i < count; ++i)
     {
     {
         SAFE_DELETE(_namespaces[i]);
         SAFE_DELETE(_namespaces[i]);
     }
     }
@@ -423,7 +419,7 @@ void Properties::resolveInheritance(const char* id)
                 derived->_properties = parent->_properties;
                 derived->_properties = parent->_properties;
                 derived->_namespaces = std::vector<Properties*>();
                 derived->_namespaces = std::vector<Properties*>();
                 std::vector<Properties*>::const_iterator itt;
                 std::vector<Properties*>::const_iterator itt;
-                for (itt = parent->_namespaces.begin(); itt < parent->_namespaces.end(); itt++)
+                for (itt = parent->_namespaces.begin(); itt < parent->_namespaces.end(); ++itt)
                 {
                 {
                     GP_ASSERT(*itt);
                     GP_ASSERT(*itt);
                     derived->_namespaces.push_back(new Properties(**itt));
                     derived->_namespaces.push_back(new Properties(**itt));
@@ -466,7 +462,7 @@ void Properties::mergeWith(Properties* overrides)
         this->_properties[name] = value;
         this->_properties[name] = value;
         name = overrides->getNextProperty(&value);
         name = overrides->getNextProperty(&value);
     }
     }
-    SAFE_DELETE(value);
+    SAFE_DELETE_ARRAY(value);
     this->_propertiesItr = this->_properties.end();
     this->_propertiesItr = this->_properties.end();
 
 
     // Merge all common nested namespaces, add new ones.
     // Merge all common nested namespaces, add new ones.
@@ -512,7 +508,7 @@ const char* Properties::getNextProperty(char** value)
     else
     else
     {
     {
         // Move to the next property
         // Move to the next property
-        _propertiesItr++;
+        ++_propertiesItr;
     }
     }
 
 
     if (_propertiesItr != _properties.end())
     if (_propertiesItr != _properties.end())
@@ -540,7 +536,7 @@ Properties* Properties::getNextNamespace()
     }
     }
     else
     else
     {
     {
-        _namespacesItr++;
+        ++_namespacesItr;
     }
     }
 
 
     if (_namespacesItr != _namespaces.end())
     if (_namespacesItr != _namespaces.end())
@@ -565,7 +561,7 @@ Properties* Properties::getNamespace(const char* id, bool searchNames) const
     Properties* ret = NULL;
     Properties* ret = NULL;
     std::vector<Properties*>::const_iterator it;
     std::vector<Properties*>::const_iterator it;
     
     
-    for (it = _namespaces.begin(); it < _namespaces.end(); it++)
+    for (it = _namespaces.begin(); it < _namespaces.end(); ++it)
     {
     {
         ret = *it;
         ret = *it;
         if (strcmp(searchNames ? ret->_namespace.c_str() : ret->_id.c_str(), id) == 0)
         if (strcmp(searchNames ? ret->_namespace.c_str() : ret->_id.c_str(), id) == 0)
@@ -998,11 +994,9 @@ Properties* getPropertiesFromNamespacePath(Properties* properties, const std::ve
 {
 {
     // If the url references a specific namespace within the file,
     // If the url references a specific namespace within the file,
     // return the specified namespace or notify the user if it cannot be found.
     // return the specified namespace or notify the user if it cannot be found.
-    Properties* originalProperties = properties;
     if (namespacePath.size() > 0)
     if (namespacePath.size() > 0)
     {
     {
         unsigned int size = namespacePath.size();
         unsigned int size = namespacePath.size();
-        const char* tmp = namespacePath[0].c_str();
         properties->rewind();
         properties->rewind();
         Properties* iter = properties->getNextNamespace();
         Properties* iter = properties->getNextNamespace();
         for (unsigned int i = 0; i < size;)
         for (unsigned int i = 0; i < size;)

+ 1 - 1
gameplay/src/Quaternion.cpp

@@ -57,7 +57,7 @@ bool Quaternion::isIdentity() const
 
 
 bool Quaternion::isZero() const
 bool Quaternion::isZero() const
 {
 {
-    return x == 0.0f && y == 0.0f && z == 0.0f && z == 0.0f;
+    return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
 }
 }
 
 
 void Quaternion::createFromRotationMatrix(const Matrix& m, Quaternion* dst)
 void Quaternion::createFromRotationMatrix(const Matrix& m, Quaternion* dst)

+ 12 - 12
gameplay/src/RadioButton.cpp

@@ -5,7 +5,7 @@ namespace gameplay
 {
 {
 static std::vector<RadioButton*> __radioButtons;
 static std::vector<RadioButton*> __radioButtons;
 
 
-RadioButton::RadioButton() : _selected(false)
+RadioButton::RadioButton() : _selected(false), _image(NULL)
 {
 {
 }
 }
 
 
@@ -102,16 +102,16 @@ bool RadioButton::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int c
         {
         {
             if (_contactIndex == (int) _contactIndex && _state == Control::ACTIVE)
             if (_contactIndex == (int) _contactIndex && _state == Control::ACTIVE)
             {
             {
-				if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
-					y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
-				{
-					if (!_selected)
-					{
-						RadioButton::clearSelected(_groupId);
-						_selected = true;
-						notifyListeners(Listener::VALUE_CHANGED);
-					}
-				}
+                if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
+                    y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
+                {
+                    if (!_selected)
+                    {
+                        RadioButton::clearSelected(_groupId);
+                        _selected = true;
+                        notifyListeners(Listener::VALUE_CHANGED);
+                    }
+                }
             }
             }
         }
         }
         break;
         break;
@@ -123,7 +123,7 @@ bool RadioButton::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int c
 void RadioButton::clearSelected(const std::string& groupId)
 void RadioButton::clearSelected(const std::string& groupId)
 {
 {
     std::vector<RadioButton*>::const_iterator it;
     std::vector<RadioButton*>::const_iterator it;
-    for (it = __radioButtons.begin(); it < __radioButtons.end(); it++)
+    for (it = __radioButtons.begin(); it < __radioButtons.end(); ++it)
     {
     {
         RadioButton* radioButton = *it;
         RadioButton* radioButton = *it;
         GP_ASSERT(radioButton);
         GP_ASSERT(radioButton);

+ 1 - 1
gameplay/src/Rectangle.cpp

@@ -126,7 +126,7 @@ void Rectangle::inflate(float horizontalAmount, float verticalAmount)
     height += verticalAmount * 2;
     height += verticalAmount * 2;
 }
 }
 
 
-const Rectangle& Rectangle::operator = (const Rectangle& r)
+Rectangle& Rectangle::operator = (const Rectangle& r)
 {
 {
     x = r.x;
     x = r.x;
     y = r.y;
     y = r.y;

+ 1 - 1
gameplay/src/Rectangle.h

@@ -214,7 +214,7 @@ public:
     /**
     /**
      * operator =
      * operator =
      */
      */
-    const Rectangle& operator = (const Rectangle& r);
+    Rectangle& operator = (const Rectangle& r);
 
 
     /**
     /**
      * operator ==
      * operator ==

+ 1 - 1
gameplay/src/RenderState.cpp

@@ -193,7 +193,7 @@ void RenderState::setNodeBinding(Node* node)
         while (itr != _autoBindings.end())
         while (itr != _autoBindings.end())
         {
         {
             applyAutoBinding(itr->first.c_str(), itr->second);
             applyAutoBinding(itr->first.c_str(), itr->second);
-            itr++;
+            ++itr;
         }
         }
     }
     }
 }
 }

+ 1 - 1
gameplay/src/RenderTarget.cpp

@@ -47,7 +47,7 @@ RenderTarget* RenderTarget::getRenderTarget(const char* id)
 
 
     // Search the vector for a matching ID.
     // Search the vector for a matching ID.
     std::vector<RenderTarget*>::const_iterator it;
     std::vector<RenderTarget*>::const_iterator it;
-    for (it = __renderTargets.begin(); it < __renderTargets.end(); it++)
+    for (it = __renderTargets.begin(); it < __renderTargets.end(); ++it)
     {
     {
         RenderTarget* dst = *it;
         RenderTarget* dst = *it;
         GP_ASSERT(dst);
         GP_ASSERT(dst);

+ 3 - 9
gameplay/src/SceneLoader.cpp

@@ -88,7 +88,6 @@ Scene* SceneLoader::loadInternal(const char* url)
 
 
     // Find the physics properties object.
     // Find the physics properties object.
     Properties* physics = NULL;
     Properties* physics = NULL;
-    Properties* ns = NULL;
     sceneProperties->rewind();
     sceneProperties->rewind();
     while (true)
     while (true)
     {
     {
@@ -106,7 +105,7 @@ Scene* SceneLoader::loadInternal(const char* url)
 
 
     // Clean up all loaded properties objects.
     // Clean up all loaded properties objects.
     std::map<std::string, Properties*>::iterator iter = _propertiesFromFile.begin();
     std::map<std::string, Properties*>::iterator iter = _propertiesFromFile.begin();
-    for (; iter != _propertiesFromFile.end(); iter++)
+    for (; iter != _propertiesFromFile.end(); ++iter)
     {
     {
         SAFE_DELETE(iter->second);
         SAFE_DELETE(iter->second);
     }
     }
@@ -201,10 +200,6 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             break;
             break;
         }
         }
         case SceneNodeProperty::MATERIAL:
         case SceneNodeProperty::MATERIAL:
-            {
-                const char* id = node->getId();
-                id = NULL;
-            }
             if (!node->getModel())
             if (!node->getModel())
             {
             {
                 GP_ERROR("Attempting to set a material on node '%s', which has no model.", sceneNode._nodeID);
                 GP_ERROR("Attempting to set a material on node '%s', which has no model.", sceneNode._nodeID);
@@ -288,7 +283,6 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
     {
     {
         // Handle scale, rotate and translate.
         // Handle scale, rotate and translate.
         Properties* np = sceneProperties->getNamespace(sceneNode._nodeID);
         Properties* np = sceneProperties->getNamespace(sceneNode._nodeID);
-        const char* name = NULL;
 
 
         switch (snp._type)
         switch (snp._type)
         {
         {
@@ -916,7 +910,7 @@ void SceneLoader::loadReferencedFiles()
 {
 {
     // Load all referenced properties files.
     // Load all referenced properties files.
     std::map<std::string, Properties*>::iterator iter = _properties.begin();
     std::map<std::string, Properties*>::iterator iter = _properties.begin();
-    for (; iter != _properties.end(); iter++)
+    for (; iter != _properties.end(); ++iter)
     {
     {
         if (iter->second == NULL)
         if (iter->second == NULL)
         {
         {
@@ -1096,7 +1090,7 @@ SceneLoader::SceneNode::SceneNode()
 {
 {
 }
 }
 
 
-SceneLoader::SceneNodeProperty::SceneNodeProperty(Type type, std::string url, int index)
+SceneLoader::SceneNodeProperty::SceneNodeProperty(Type type, const std::string& url, int index)
     : _type(type), _url(url), _index(index)
     : _type(type), _url(url), _index(index)
 {
 {
 }
 }

+ 1 - 1
gameplay/src/SceneLoader.h

@@ -56,7 +56,7 @@ private:
             URL = 128
             URL = 128
         };
         };
 
 
-        SceneNodeProperty(Type type, std::string url, int index);
+        SceneNodeProperty(Type type, const std::string& url, int index);
 
 
         Type _type;
         Type _type;
         std::string _url;
         std::string _url;

+ 13 - 13
gameplay/src/ScriptController.cpp

@@ -23,7 +23,7 @@
         return LuaArray<type>((type*)NULL); \
         return LuaArray<type>((type*)NULL); \
     \
     \
     /* Declare a LuaArray to store the values. */ \
     /* Declare a LuaArray to store the values. */ \
-	LuaArray<type> arr(size); \
+    LuaArray<type> arr(size); \
     \
     \
     /* Push the first key. */ \
     /* Push the first key. */ \
     lua_pushnil(sc->_lua); \
     lua_pushnil(sc->_lua); \
@@ -59,13 +59,13 @@ void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions)
     lua_setglobal(sc->_lua, name);
     lua_setglobal(sc->_lua, name);
 }
 }
 
 
-void ScriptUtil::registerConstantBool(std::string name, bool value, std::vector<std::string> scopePath)
+void ScriptUtil::registerConstantBool(const std::string& name, bool value, const std::vector<std::string>& scopePath)
 {
 {
     ScriptController* sc = Game::getInstance()->getScriptController();
     ScriptController* sc = Game::getInstance()->getScriptController();
 
 
     // If the constant is within a scope, get the correct parent 
     // If the constant is within a scope, get the correct parent 
     // table on the stack before setting its value.
     // table on the stack before setting its value.
-    if (scopePath.size() > 0)
+    if (!scopePath.empty())
     {
     {
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         for (unsigned int i = 1; i < scopePath.size(); i++)
         for (unsigned int i = 1; i < scopePath.size(); i++)
@@ -92,13 +92,13 @@ void ScriptUtil::registerConstantBool(std::string name, bool value, std::vector<
     }
     }
 }
 }
 
 
-void ScriptUtil::registerConstantNumber(std::string name, double value, std::vector<std::string> scopePath)
+void ScriptUtil::registerConstantNumber(const std::string& name, double value, const std::vector<std::string>& scopePath)
 {
 {
     ScriptController* sc = Game::getInstance()->getScriptController();
     ScriptController* sc = Game::getInstance()->getScriptController();
 
 
     // If the constant is within a scope, get the correct parent 
     // If the constant is within a scope, get the correct parent 
     // table on the stack before setting its value.
     // table on the stack before setting its value.
-    if (scopePath.size() > 0)
+    if (!scopePath.empty())
     {
     {
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         for (unsigned int i = 1; i < scopePath.size(); i++)
         for (unsigned int i = 1; i < scopePath.size(); i++)
@@ -125,13 +125,13 @@ void ScriptUtil::registerConstantNumber(std::string name, double value, std::vec
     }
     }
 }
 }
 
 
-void ScriptUtil::registerConstantString(std::string name, std::string value, std::vector<std::string> scopePath)
+void ScriptUtil::registerConstantString(const std::string& name, const std::string& value, const std::vector<std::string>& scopePath)
 {
 {
     ScriptController* sc = Game::getInstance()->getScriptController();
     ScriptController* sc = Game::getInstance()->getScriptController();
 
 
     // If the constant is within a scope, get the correct parent 
     // If the constant is within a scope, get the correct parent 
     // table on the stack before setting its value.
     // table on the stack before setting its value.
-    if (scopePath.size() > 0)
+    if (!scopePath.empty())
     {
     {
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         lua_getglobal(sc->_lua, scopePath[0].c_str());
         for (unsigned int i = 1; i < scopePath.size(); i++)
         for (unsigned int i = 1; i < scopePath.size(); i++)
@@ -159,13 +159,13 @@ void ScriptUtil::registerConstantString(std::string name, std::string value, std
 }
 }
 
 
 void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction, 
 void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction, 
-    lua_CFunction deleteFunction, const luaL_Reg* statics,  std::vector<std::string> scopePath)
+    lua_CFunction deleteFunction, const luaL_Reg* statics,  const std::vector<std::string>& scopePath)
 {
 {
     ScriptController* sc = Game::getInstance()->getScriptController();
     ScriptController* sc = Game::getInstance()->getScriptController();
 
 
     // If the type is an inner type, get the correct parent 
     // If the type is an inner type, get the correct parent 
     // table on the stack before creating the table for the class.
     // table on the stack before creating the table for the class.
-    if (scopePath.size() > 0)
+    if (!scopePath.empty())
     {
     {
         std::string tablename = name;
         std::string tablename = name;
 
 
@@ -229,7 +229,7 @@ void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CF
     }
     }
 
 
     // Set the table we just created within the correct parent table.
     // Set the table we just created within the correct parent table.
-    if (scopePath.size() > 0)
+    if (!scopePath.empty())
     {
     {
         lua_settable(sc->_lua, -3);
         lua_settable(sc->_lua, -3);
 
 
@@ -250,7 +250,7 @@ void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunc
     lua_setglobal(Game::getInstance()->getScriptController()->_lua, luaFunction);
     lua_setglobal(Game::getInstance()->getScriptController()->_lua, luaFunction);
 }
 }
 
 
-void ScriptUtil::setGlobalHierarchyPair(std::string base, std::string derived)
+void ScriptUtil::setGlobalHierarchyPair(const std::string& base, const std::string& derived)
 {
 {
     Game::getInstance()->getScriptController()->_hierarchy[base].push_back(derived);
     Game::getInstance()->getScriptController()->_hierarchy[base].push_back(derived);
 }
 }
@@ -784,7 +784,7 @@ void ScriptController::executeFunctionHelper(int resultCount, const char* func,
         GP_WARN("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
         GP_WARN("Failed to call function '%s' with error '%s'.", func, lua_tostring(_lua, -1));
 }
 }
 
 
-void ScriptController::registerCallback(ScriptCallback callback, std::string function)
+void ScriptController::registerCallback(ScriptCallback callback, const std::string& function)
 {
 {
     SAFE_DELETE(_callbacks[callback]);
     SAFE_DELETE(_callbacks[callback]);
     _callbacks[callback] = new std::string(function);
     _callbacks[callback] = new std::string(function);
@@ -1058,4 +1058,4 @@ template<> std::string ScriptController::executeFunction<std::string>(const char
     SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(std::string, luaL_checkstring);
     SCRIPT_EXECUTE_FUNCTION_PARAM_LIST(std::string, luaL_checkstring);
 }
 }
 
 
-}
+}

+ 55 - 55
gameplay/src/ScriptController.h

@@ -39,46 +39,46 @@ class LuaArray
 {
 {
 public:
 public:
 
 
-	/**
-	 * Creates a LuaArray to store a single pointer value.
-	 */
-	LuaArray(T* param);
-
-	/**
-	 * Allocates a LuaArray to store an array of values.
-	 *
-	 * Individual items in the array can be set using the 
-	 * set(unsigned int, const T&) method.
-	 * 
-	 * @param count Number of elements to store in the parameter.
-	 */
-	LuaArray(int count);
-
-	/**
-	 * Copy construcotr.
-	 */
-	LuaArray(const LuaArray<T>& copy);
-
-	/**
-	 * Destructor.
-	 */
-	~LuaArray();
-
-	/**
-	 * Assignment operator.
-	 */
-	LuaArray<T>& operator = (const LuaArray<T>& p);
-
-	/**
-	 * Copies the value of the object pointed to by itemPtr into the specified
+    /**
+     * Creates a LuaArray to store a single pointer value.
+     */
+    LuaArray(T* param);
+
+    /**
+     * Allocates a LuaArray to store an array of values.
+     *
+     * Individual items in the array can be set using the 
+     * set(unsigned int, const T&) method.
+     * 
+     * @param count Number of elements to store in the parameter.
+     */
+    LuaArray(int count);
+
+    /**
+     * Copy construcotr.
+     */
+    LuaArray(const LuaArray<T>& copy);
+
+    /**
+     * Destructor.
+     */
+    ~LuaArray();
+
+    /**
+     * Assignment operator.
+     */
+    LuaArray<T>& operator = (const LuaArray<T>& p);
+
+    /**
+     * Copies the value of the object pointed to by itemPtr into the specified
      * index of this LuaArray's array.
      * index of this LuaArray's array.
-	 */
-	void set(unsigned int index, const T* itemPtr);
+     */
+    void set(unsigned int index, const T* itemPtr);
 
 
-	/**
-	 * Conversion operator from LuaArray to T*.
-	 */
-	operator T* () const;
+    /**
+     * Conversion operator from LuaArray to T*.
+     */
+    operator T* () const;
 
 
     /**
     /**
      * Overloades [] operator to get/set item value at index.
      * Overloades [] operator to get/set item value at index.
@@ -87,14 +87,14 @@ public:
 
 
 private:
 private:
 
 
-	struct Data
-	{
+    struct Data
+    {
         Data() : value(NULL), refCount(0) { }
         Data() : value(NULL), refCount(0) { }
-		T* value;
-		int refCount;
-	};
+        T* value;
+        int refCount;
+    };
 
 
-	Data* _data;
+    Data* _data;
 };
 };
 
 
 /**
 /**
@@ -114,7 +114,7 @@ void registerLibrary(const char* name, const luaL_Reg* functions);
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @script{ignore}
  * @script{ignore}
  */
  */
-void registerConstantBool(std::string name, bool value, std::vector<std::string> scopePath);
+void registerConstantBool(const std::string& name, bool value, const std::vector<std::string>& scopePath);
 
 
 /**
 /**
  * Registers the given number constant as valid for the given scope path.
  * Registers the given number constant as valid for the given scope path.
@@ -124,7 +124,7 @@ void registerConstantBool(std::string name, bool value, std::vector<std::string>
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @script{ignore}
  * @script{ignore}
  */
  */
-void registerConstantNumber(std::string name, double value, std::vector<std::string> scopePath);
+void registerConstantNumber(const std::string& name, double value, const std::vector<std::string>& scopePath);
 
 
 /**
 /**
  * Registers the given string constant as valid for the given scope path.
  * Registers the given string constant as valid for the given scope path.
@@ -134,7 +134,7 @@ void registerConstantNumber(std::string name, double value, std::vector<std::str
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @param scopePath The list of containing classes, going inward from the most outer class.
  * @script{ignore}
  * @script{ignore}
  */
  */
-void registerConstantString(std::string name, std::string value, std::vector<std::string> scopePath);
+void registerConstantString(const std::string& name, const std::string& value, const std::vector<std::string>& scopePath);
 
 
 /**
 /**
  * Registers the given class type with Lua.
  * Registers the given class type with Lua.
@@ -148,7 +148,7 @@ void registerConstantString(std::string name, std::string value, std::vector<std
  * @script{ignore}
  * @script{ignore}
  */
  */
 void registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction, lua_CFunction deleteFunction, const luaL_Reg* statics,
 void registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction, lua_CFunction deleteFunction, const luaL_Reg* statics,
-    std::vector<std::string> scopePath = std::vector<std::string>());
+    const std::vector<std::string>& scopePath);
 
 
 /**
 /**
  * Register a function with Lua.
  * Register a function with Lua.
@@ -166,7 +166,7 @@ void registerFunction(const char* luaFunction, lua_CFunction cppFunction);
  * @param derived The derived class of the inheritance pair.
  * @param derived The derived class of the inheritance pair.
  * @script{ignore}
  * @script{ignore}
  */
  */
-void setGlobalHierarchyPair(std::string base, std::string derived);
+void setGlobalHierarchyPair(const std::string& base, const std::string& derived);
 
 
 /**
 /**
  * Adds the given function as a string-from-enumerated value conversion function.
  * Adds the given function as a string-from-enumerated value conversion function.
@@ -781,7 +781,7 @@ private:
      * @param callback The script callback to register for.
      * @param callback The script callback to register for.
      * @param function The name of the function within the Lua script to call.
      * @param function The name of the function within the Lua script to call.
      */
      */
-    void registerCallback(ScriptCallback callback, std::string function);
+    void registerCallback(ScriptCallback callback, const std::string& function);
 
 
     /**
     /**
      * Converts the given string to a valid script callback enumeration value
      * Converts the given string to a valid script callback enumeration value
@@ -794,13 +794,13 @@ private:
 
 
     // Friend functions (used by Lua script bindings).
     // Friend functions (used by Lua script bindings).
     friend void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions);
     friend void ScriptUtil::registerLibrary(const char* name, const luaL_Reg* functions);
-    friend void ScriptUtil::registerConstantBool(std::string name, bool value, std::vector<std::string> scopePath);
-    friend void ScriptUtil::registerConstantNumber(std::string name, double value, std::vector<std::string> scopePath);
-    friend void ScriptUtil::registerConstantString(std::string name, std::string value, std::vector<std::string> scopePath);
+    friend void ScriptUtil::registerConstantBool(const std::string& name, bool value, const std::vector<std::string>& scopePath);
+    friend void ScriptUtil::registerConstantNumber(const std::string& name, double value, const std::vector<std::string>& scopePath);
+    friend void ScriptUtil::registerConstantString(const std::string& name, const std::string& value, const std::vector<std::string>& scopePath);
     friend void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction,
     friend void ScriptUtil::registerClass(const char* name, const luaL_Reg* members, lua_CFunction newFunction,
-        lua_CFunction deleteFunction, const luaL_Reg* statics, std::vector<std::string> scopePath);
+        lua_CFunction deleteFunction, const luaL_Reg* statics, const std::vector<std::string>& scopePath);
     friend void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunction);
     friend void ScriptUtil::registerFunction(const char* luaFunction, lua_CFunction cppFunction);
-    friend void ScriptUtil::setGlobalHierarchyPair(std::string base, std::string derived);
+    friend void ScriptUtil::setGlobalHierarchyPair(const std::string& base, const std::string& derived);
     friend void ScriptUtil::addStringFromEnumConversionFunction(luaStringEnumConversionFunction stringFromEnum);
     friend void ScriptUtil::addStringFromEnumConversionFunction(luaStringEnumConversionFunction stringFromEnum);
     friend ScriptUtil::LuaArray<bool> ScriptUtil::getBoolPointer(int index);
     friend ScriptUtil::LuaArray<bool> ScriptUtil::getBoolPointer(int index);
     friend ScriptUtil::LuaArray<short> ScriptUtil::getShortPointer(int index);
     friend ScriptUtil::LuaArray<short> ScriptUtil::getShortPointer(int index);

+ 32 - 32
gameplay/src/ScriptController.inl

@@ -6,71 +6,71 @@ namespace gameplay
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>::LuaArray(T* param)
 ScriptUtil::LuaArray<T>::LuaArray(T* param)
 {
 {
-	_data = new ScriptUtil::LuaArray<T>::Data();
-	_data->value = param;
+    _data = new ScriptUtil::LuaArray<T>::Data();
+    _data->value = param;
 
 
-	// Initial ref count of zero means no memory management
-	_data->refCount = 0;
+    // Initial ref count of zero means no memory management
+    _data->refCount = 0;
 }
 }
 
 
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>::LuaArray(int count)
 ScriptUtil::LuaArray<T>::LuaArray(int count)
 {
 {
-	_data = new ScriptUtil::LuaArray<T>::Data();
+    _data = new ScriptUtil::LuaArray<T>::Data();
 
 
-	// Allocate a chunk of memory to store 'count' number of T.
-	// Use new instead of malloc since we track memory allocations
-	// int DebugMem configurations.
-	_data->value = (T*)new unsigned char[sizeof(T) * count];
+    // Allocate a chunk of memory to store 'count' number of T.
+    // Use new instead of malloc since we track memory allocations
+    // int DebugMem configurations.
+    _data->value = (T*)new unsigned char[sizeof(T) * count];
 
 
-	// Positive ref count means we automatically cleanup memory
-	_data->refCount = 1;
+    // Positive ref count means we automatically cleanup memory
+    _data->refCount = 1;
 }
 }
 
 
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>::LuaArray(const ScriptUtil::LuaArray<T>& copy)
 ScriptUtil::LuaArray<T>::LuaArray(const ScriptUtil::LuaArray<T>& copy)
 {
 {
-	_data = copy._data;
-	++_data->refCount;
+    _data = copy._data;
+    ++_data->refCount;
 }
 }
 
 
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>::~LuaArray()
 ScriptUtil::LuaArray<T>::~LuaArray()
 {
 {
-	if ((--_data->refCount) <= 0)
-	{
+    if ((--_data->refCount) <= 0)
+    {
         // Non managed arrays/pointers start with ref count zero, so only delete data if
         // Non managed arrays/pointers start with ref count zero, so only delete data if
         // the decremented ref count == 0 (otherwise it will be -1).
         // the decremented ref count == 0 (otherwise it will be -1).
         if (_data->refCount == 0)
         if (_data->refCount == 0)
         {
         {
             unsigned char* value = (unsigned char*)_data->value;
             unsigned char* value = (unsigned char*)_data->value;
-		    SAFE_DELETE_ARRAY(value);
+            SAFE_DELETE_ARRAY(value);
         }
         }
 
 
         SAFE_DELETE(_data);
         SAFE_DELETE(_data);
-	}
+    }
 }
 }
 
 
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>& ScriptUtil::LuaArray<T>::operator = (const ScriptUtil::LuaArray<T>& p)
 ScriptUtil::LuaArray<T>& ScriptUtil::LuaArray<T>::operator = (const ScriptUtil::LuaArray<T>& p)
 {
 {
     _data = p._data;
     _data = p._data;
-	++_data->refCount;
+    ++_data->refCount;
 }
 }
 
 
 template <typename T>
 template <typename T>
 void ScriptUtil::LuaArray<T>::set(unsigned int index, const T* itemPtr)
 void ScriptUtil::LuaArray<T>::set(unsigned int index, const T* itemPtr)
 {
 {
-	// WARNING: The following code will only work properly for arrays of pointers
-	// to objects (i.e. T**) or for simple structs that are being passed
-	// in as read-only. Since the memory is directly copied, any member data that
-	// is modified with the object that is copied, will not modify the original object.
-	// What is even scarier is that if an array of objects that contain virtual functions
-	// is copied here, then the vtables are copied directly, meaning the new object
-	// contains a copy of a vtable that points to functions in the old object. Calling
-	// virtual fucntions on the new object would then call the functions on the old object.
-	// If the old object is deleted, the vtable on the new object would point to addressess
-	// for functions that no longer exist.
+    // WARNING: The following code will only work properly for arrays of pointers
+    // to objects (i.e. T**) or for simple structs that are being passed
+    // in as read-only. Since the memory is directly copied, any member data that
+    // is modified with the object that is copied, will not modify the original object.
+    // What is even scarier is that if an array of objects that contain virtual functions
+    // is copied here, then the vtables are copied directly, meaning the new object
+    // contains a copy of a vtable that points to functions in the old object. Calling
+    // virtual fucntions on the new object would then call the functions on the old object.
+    // If the old object is deleted, the vtable on the new object would point to addressess
+    // for functions that no longer exist.
     if (itemPtr)
     if (itemPtr)
         memcpy((void*)&_data->value[index], (void*)itemPtr, sizeof(T));
         memcpy((void*)&_data->value[index], (void*)itemPtr, sizeof(T));
     else
     else
@@ -80,7 +80,7 @@ void ScriptUtil::LuaArray<T>::set(unsigned int index, const T* itemPtr)
 template <typename T>
 template <typename T>
 ScriptUtil::LuaArray<T>::operator T* () const
 ScriptUtil::LuaArray<T>::operator T* () const
 {
 {
-	return _data->value;
+    return _data->value;
 }
 }
 
 
 template <typename T>
 template <typename T>
@@ -111,7 +111,7 @@ ScriptUtil::LuaArray<T> ScriptUtil::getObjectPointer(int index, const char* type
         if (size <= 0)
         if (size <= 0)
             return LuaArray<T>((T*)NULL);
             return LuaArray<T>((T*)NULL);
 
 
-		LuaArray<T> arr(size);
+        LuaArray<T> arr(size);
 
 
         // Push the first key.
         // Push the first key.
         lua_pushnil(sc->_lua);
         lua_pushnil(sc->_lua);
@@ -128,7 +128,7 @@ ScriptUtil::LuaArray<T> ScriptUtil::getObjectPointer(int index, const char* type
                     if (lua_rawequal(sc->_lua, -1, -2))
                     if (lua_rawequal(sc->_lua, -1, -2))
                     {
                     {
                         lua_pop(sc->_lua, 2);
                         lua_pop(sc->_lua, 2);
-						arr.set(i, (T*)((ScriptUtil::LuaObject*)p)->instance);
+                        arr.set(i, (T*)((ScriptUtil::LuaObject*)p)->instance);
                         lua_pop(sc->_lua, 1);
                         lua_pop(sc->_lua, 1);
                         continue;
                         continue;
                     }
                     }
@@ -142,7 +142,7 @@ ScriptUtil::LuaArray<T> ScriptUtil::getObjectPointer(int index, const char* type
                         if (lua_rawequal(sc->_lua, -1, -2))
                         if (lua_rawequal(sc->_lua, -1, -2))
                         {
                         {
                             lua_pop(sc->_lua, 2);
                             lua_pop(sc->_lua, 2);
-							arr.set(i, (T*)((ScriptUtil::LuaObject*)p)->instance);
+                            arr.set(i, (T*)((ScriptUtil::LuaObject*)p)->instance);
                             lua_pop(sc->_lua, 1);
                             lua_pop(sc->_lua, 1);
                             continue;
                             continue;
                         }
                         }

+ 1 - 4
gameplay/src/Slider.cpp

@@ -6,7 +6,7 @@ namespace gameplay
 // Fraction of slider to scroll when mouse scrollwheel is used.
 // Fraction of slider to scroll when mouse scrollwheel is used.
 static const float SCROLL_FRACTION = 0.1f;
 static const float SCROLL_FRACTION = 0.1f;
 
 
-Slider::Slider() : _minImage(NULL), _maxImage(NULL), _trackImage(NULL), _markerImage(NULL)
+Slider::Slider() : _min(0.0f), _max(0.0f), _step(0.0f), _value(0.0f), _minImage(NULL), _maxImage(NULL), _trackImage(NULL), _markerImage(NULL)
 {
 {
 }
 }
 
 
@@ -240,9 +240,6 @@ void Slider::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
     // The slider is drawn in the center of the control (perpendicular to orientation).
     // The slider is drawn in the center of the control (perpendicular to orientation).
     // The track is stretched according to orientation.
     // The track is stretched according to orientation.
     // Caps and marker are not stretched.
     // Caps and marker are not stretched.
-    const Theme::Border& border = getBorder(_state);
-    const Theme::Padding& padding = getPadding();
-
     const Rectangle& minCapRegion = _minImage->getRegion();
     const Rectangle& minCapRegion = _minImage->getRegion();
     const Rectangle& maxCapRegion = _maxImage->getRegion();
     const Rectangle& maxCapRegion = _maxImage->getRegion();
     const Rectangle& markerRegion = _markerImage->getRegion();
     const Rectangle& markerRegion = _markerImage->getRegion();

+ 4 - 4
gameplay/src/SpriteBatch.h

@@ -124,7 +124,7 @@ public:
      * @param color The color to tint the sprite. Use white for no tint.
      * @param color The color to tint the sprite. Use white for no tint.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
-     * @param rotationAngle The rotation angle.
+     * @param rotationAngle The rotation angle in radians.
      */
      */
     void draw(const Vector3& dst, const Rectangle& src, const Vector2& scale, const Vector4& color,
     void draw(const Vector3& dst, const Rectangle& src, const Vector2& scale, const Vector4& color,
               const Vector2& rotationPoint, float rotationAngle);
               const Vector2& rotationPoint, float rotationAngle);
@@ -142,7 +142,7 @@ public:
      * @param color The color to tint the sprite. Use white for no tint.
      * @param color The color to tint the sprite. Use white for no tint.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
-     * @param rotationAngle The rotation angle.
+     * @param rotationAngle The rotation angle in radians.
      * @param positionIsCenter Specified whether the given destination is to be the center of the sprite or not (if not, it is treated as the bottom-left).
      * @param positionIsCenter Specified whether the given destination is to be the center of the sprite or not (if not, it is treated as the bottom-left).
      */
      */
     void draw(const Vector3& dst, float width, float height, float u1, float v1, float u2, float v2, const Vector4& color,
     void draw(const Vector3& dst, float width, float height, float u1, float v1, float u2, float v2, const Vector4& color,
@@ -163,7 +163,7 @@ public:
      * @param color The color to tint the sprite. Use white for no tint.
      * @param color The color to tint the sprite. Use white for no tint.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
-     * @param rotationAngle The rotation angle.
+     * @param rotationAngle The rotation angle in radians.
      * @param positionIsCenter Specified whether the given destination is to be the center of the sprite or not (if not, it is treated as the bottom-left).
      * @param positionIsCenter Specified whether the given destination is to be the center of the sprite or not (if not, it is treated as the bottom-left).
      */
      */
     void draw(float x, float y, float z, float width, float height, float u1, float v1, float u2, float v2, const Vector4& color,
     void draw(float x, float y, float z, float width, float height, float u1, float v1, float u2, float v2, const Vector4& color,
@@ -184,7 +184,7 @@ public:
      * @param color The color to tint the sprite. Use white for no tint.
      * @param color The color to tint the sprite. Use white for no tint.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      * @param rotationPoint The point to rotate around, relative to dst's x and y values.
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
      *                      (e.g. Use Vector2(0.5f, 0.5f) to rotate around the quad's center.)
-     * @param rotationAngle The rotation angle.
+     * @param rotationAngle The rotation angle in radians.
      */
      */
     void draw(const Vector3& position, const Vector3& right, const Vector3& forward, float width, float height, 
     void draw(const Vector3& position, const Vector3& right, const Vector3& forward, float width, float height, 
               float u1, float v1, float u2, float v2, const Vector4& color, const Vector2& rotationPoint, float rotationAngle);
               float u1, float v1, float u2, float v2, const Vector4& color, const Vector2& rotationPoint, float rotationAngle);

+ 11 - 11
gameplay/src/TextBox.cpp

@@ -4,7 +4,7 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-TextBox::TextBox() : _lastKeypress(0)
+TextBox::TextBox() : _textIndex(0), _lastKeypress(0), _fontSize(0), _caretImage(NULL)
 {
 {
 }
 }
 
 
@@ -250,11 +250,11 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                 {
                 {
                     case Keyboard::KEY_BACKSPACE:
                     case Keyboard::KEY_BACKSPACE:
                     {
                     {
-                        if (textIndex > 0)
+                        if (_textIndex > 0)
                         {
                         {
-                            --textIndex;
-                            _text.erase(textIndex, 1);
-                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
+                            --_textIndex;
+                            _text.erase(_textIndex, 1);
+                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
                                 textAlignment, true, rightToLeft);
                                 textAlignment, true, rightToLeft);
 
 
                             _dirty = true;
                             _dirty = true;
@@ -272,11 +272,11 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     default:
                     default:
                     {
                     {
                         // Insert character into string.
                         // Insert character into string.
-                        _text.insert(textIndex, 1, (char)key);
+                        _text.insert(_textIndex, 1, (char)key);
                         consume = true;
                         consume = true;
 
 
                         // Get new location of caret.
                         // Get new location of caret.
-                        font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
+                        font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex + 1,
                             textAlignment, true, rightToLeft);
                             textAlignment, true, rightToLeft);
 
 
                         if (key == ' ')
                         if (key == ' ')
@@ -286,8 +286,8 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                                 _caretLocation.y >= _textBounds.y + _textBounds.height)
                                 _caretLocation.y >= _textBounds.y + _textBounds.height)
                             {
                             {
                                 // If not, undo the character insertion.
                                 // If not, undo the character insertion.
-                                _text.erase(textIndex, 1);
-                                font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
+                                _text.erase(_textIndex, 1);
+                                font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
                                     textAlignment, true, rightToLeft);
                                     textAlignment, true, rightToLeft);
 
 
                                 // No need to check again.
                                 // No need to check again.
@@ -302,8 +302,8 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                             textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
                             textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
                         {
                         {
                             // If not, undo the character insertion.
                             // If not, undo the character insertion.
-                            _text.erase(textIndex, 1);
-                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
+                            _text.erase(_textIndex, 1);
+                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
                                 textAlignment, true, rightToLeft);
                                 textAlignment, true, rightToLeft);
 
 
                             // TextBox is not dirty.
                             // TextBox is not dirty.

+ 1 - 1
gameplay/src/TextBox.h

@@ -152,7 +152,7 @@ protected:
     /**
     /**
      * The index into the TextBox's string that the caret is.
      * The index into the TextBox's string that the caret is.
      */
      */
-    unsigned int textIndex;
+    unsigned int _textIndex;
     
     
     /**
     /**
      * The last character that was entered into the TextBox.
      * The last character that was entered into the TextBox.

+ 1 - 0
gameplay/src/Texture.cpp

@@ -402,6 +402,7 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, FILE* file, GLsizei* wid
     read = fread(data, 1, dataSize, file);
     read = fread(data, 1, dataSize, file);
     if (read != dataSize)
     if (read != dataSize)
     {
     {
+        SAFE_DELETE_ARRAY(data);
         GP_ERROR("Failed to read texture data from PVR file '%s'.", path);
         GP_ERROR("Failed to read texture data from PVR file '%s'.", path);
         return NULL;
         return NULL;
     }
     }

+ 5 - 7
gameplay/src/Theme.cpp

@@ -457,7 +457,7 @@ Theme::Style* Theme::getEmptyStyle()
         overlay->addRef();
         overlay->addRef();
         overlay->addRef();
         overlay->addRef();
         overlay->addRef();
         overlay->addRef();
-        emptyStyle = new Theme::Style((Theme*)this, "EMPTY_STYLE", 1.0f / _texture->getWidth(), 1.0f / _texture->getHeight(),
+        emptyStyle = new Theme::Style(const_cast<Theme*>(this), "EMPTY_STYLE", 1.0f / _texture->getWidth(), 1.0f / _texture->getHeight(),
             Theme::Margin::empty(), Theme::Border::empty(), overlay, overlay, overlay, overlay);
             Theme::Margin::empty(), Theme::Border::empty(), overlay, overlay, overlay, overlay);
 
 
         _styles.push_back(emptyStyle);
         _styles.push_back(emptyStyle);
@@ -584,12 +584,10 @@ Theme::ImageList::ImageList(const Vector4& color) : _color(color)
 }
 }
 
 
 Theme::ImageList::ImageList(const ImageList& copy)
 Theme::ImageList::ImageList(const ImageList& copy)
+    : _id(copy._id), _color(copy._color)
 {
 {
-    _id = copy._id;
-    _color = copy._color;
-
     std::vector<ThemeImage*>::const_iterator it;
     std::vector<ThemeImage*>::const_iterator it;
-    for (it = copy._images.begin(); it != copy._images.end(); it++)
+    for (it = copy._images.begin(); it != copy._images.end(); ++it)
     {
     {
         ThemeImage* image = *it;
         ThemeImage* image = *it;
         GP_ASSERT(image);
         GP_ASSERT(image);
@@ -600,7 +598,7 @@ Theme::ImageList::ImageList(const ImageList& copy)
 Theme::ImageList::~ImageList()
 Theme::ImageList::~ImageList()
 {
 {
     std::vector<ThemeImage*>::const_iterator it;
     std::vector<ThemeImage*>::const_iterator it;
-    for (it = _images.begin(); it != _images.end(); it++)
+    for (it = _images.begin(); it != _images.end(); ++it)
     {
     {
         ThemeImage* image = *it;
         ThemeImage* image = *it;
         SAFE_RELEASE(image);
         SAFE_RELEASE(image);
@@ -647,7 +645,7 @@ Theme::ThemeImage* Theme::ImageList::getImage(const char* imageId) const
     GP_ASSERT(imageId);
     GP_ASSERT(imageId);
 
 
     std::vector<ThemeImage*>::const_iterator it;
     std::vector<ThemeImage*>::const_iterator it;
-    for (it = _images.begin(); it != _images.end(); it++)
+    for (it = _images.begin(); it != _images.end(); ++it)
     {
     {
         ThemeImage* image = *it;
         ThemeImage* image = *it;
         GP_ASSERT(image);
         GP_ASSERT(image);

+ 2 - 2
gameplay/src/Transform.cpp

@@ -829,7 +829,7 @@ void Transform::removeListener(Transform::Listener* listener)
 
 
     if (_listeners)
     if (_listeners)
     {
     {
-        for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); itr++)
+        for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr)
         {
         {
             if ((*itr).listener == listener)
             if ((*itr).listener == listener)
             {
             {
@@ -844,7 +844,7 @@ void Transform::transformChanged()
 {
 {
     if (_listeners)
     if (_listeners)
     {
     {
-        for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); itr++)
+        for (std::list<TransformListener>::iterator itr = _listeners->begin(); itr != _listeners->end(); ++itr)
         {
         {
             TransformListener& l = *itr;
             TransformListener& l = *itr;
             GP_ASSERT(l.listener);
             GP_ASSERT(l.listener);

+ 1 - 1
gameplay/src/Vector4.cpp

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

+ 1 - 1
gameplay/src/gameplay-main-ios.mm

@@ -15,7 +15,7 @@ int main(int argc, char** argv)
     Platform* platform = Platform::create(game);
     Platform* platform = Platform::create(game);
     GP_ASSERT(platform);
     GP_ASSERT(platform);
     int result = platform->enterMessagePump();
     int result = platform->enterMessagePump();
-	delete platform;
+    delete platform;
     [p release];
     [p release];
     return result;
     return result;
 }
 }

+ 1 - 1
gameplay/src/gameplay-main-macosx.mm

@@ -15,7 +15,7 @@ int main(int argc, char** argv)
     Platform* platform = Platform::create(game);
     Platform* platform = Platform::create(game);
     GP_ASSERT(platform);
     GP_ASSERT(platform);
     int result = platform->enterMessagePump();
     int result = platform->enterMessagePump();
-	delete platform;
+    delete platform;
     [p release];
     [p release];
     return result;
     return result;
 }
 }

+ 2 - 0
gameplay/src/gameplay.h

@@ -74,6 +74,8 @@
 #include "PhysicsRigidBody.h"
 #include "PhysicsRigidBody.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsCharacter.h"
 #include "PhysicsCharacter.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
 
 
 // AI
 // AI
 #include "AIController.h"
 #include "AIController.h"

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

@@ -34,6 +34,7 @@ void luaRegister_Game()
         {"getAIController", lua_Game_getAIController},
         {"getAIController", lua_Game_getAIController},
         {"getAccelerometerValues", lua_Game_getAccelerometerValues},
         {"getAccelerometerValues", lua_Game_getAccelerometerValues},
         {"getAnimationController", lua_Game_getAnimationController},
         {"getAnimationController", lua_Game_getAnimationController},
+        {"getAspectRatio", lua_Game_getAspectRatio},
         {"getAudioController", lua_Game_getAudioController},
         {"getAudioController", lua_Game_getAudioController},
         {"getAudioListener", lua_Game_getAudioListener},
         {"getAudioListener", lua_Game_getAudioListener},
         {"getConfig", lua_Game_getConfig},
         {"getConfig", lua_Game_getConfig},
@@ -49,6 +50,7 @@ void luaRegister_Game()
         {"getWidth", lua_Game_getWidth},
         {"getWidth", lua_Game_getWidth},
         {"hasMouse", lua_Game_hasMouse},
         {"hasMouse", lua_Game_hasMouse},
         {"isCursorVisible", lua_Game_isCursorVisible},
         {"isCursorVisible", lua_Game_isCursorVisible},
+        {"isGestureRegistered", lua_Game_isGestureRegistered},
         {"isGestureSupported", lua_Game_isGestureSupported},
         {"isGestureSupported", lua_Game_isGestureSupported},
         {"isInitialized", lua_Game_isInitialized},
         {"isInitialized", lua_Game_isInitialized},
         {"isMouseCaptured", lua_Game_isMouseCaptured},
         {"isMouseCaptured", lua_Game_isMouseCaptured},
@@ -640,6 +642,43 @@ int lua_Game_getAnimationController(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Game_getAspectRatio(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);
+                float result = instance->getAspectRatio();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Game_getAspectRatio - 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_getAudioController(lua_State* state)
 int lua_Game_getAudioController(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -1262,6 +1301,47 @@ int lua_Game_isCursorVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Game_isGestureRegistered(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_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Gesture::GestureEvent param1 = (Gesture::GestureEvent)lua_enumFromString_GestureGestureEvent(luaL_checkstring(state, 2));
+
+                Game* instance = getInstance(state);
+                bool result = instance->isGestureRegistered(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Game_isGestureRegistered - 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_isGestureSupported(lua_State* state)
 int lua_Game_isGestureSupported(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

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

@@ -17,6 +17,7 @@ int lua_Game_gestureTapEvent(lua_State* state);
 int lua_Game_getAIController(lua_State* state);
 int lua_Game_getAIController(lua_State* state);
 int lua_Game_getAccelerometerValues(lua_State* state);
 int lua_Game_getAccelerometerValues(lua_State* state);
 int lua_Game_getAnimationController(lua_State* state);
 int lua_Game_getAnimationController(lua_State* state);
+int lua_Game_getAspectRatio(lua_State* state);
 int lua_Game_getAudioController(lua_State* state);
 int lua_Game_getAudioController(lua_State* state);
 int lua_Game_getAudioListener(lua_State* state);
 int lua_Game_getAudioListener(lua_State* state);
 int lua_Game_getConfig(lua_State* state);
 int lua_Game_getConfig(lua_State* state);
@@ -32,6 +33,7 @@ int lua_Game_getViewport(lua_State* state);
 int lua_Game_getWidth(lua_State* state);
 int lua_Game_getWidth(lua_State* state);
 int lua_Game_hasMouse(lua_State* state);
 int lua_Game_hasMouse(lua_State* state);
 int lua_Game_isCursorVisible(lua_State* state);
 int lua_Game_isCursorVisible(lua_State* state);
+int lua_Game_isGestureRegistered(lua_State* state);
 int lua_Game_isGestureSupported(lua_State* state);
 int lua_Game_isGestureSupported(lua_State* state);
 int lua_Game_isInitialized(lua_State* state);
 int lua_Game_isInitialized(lua_State* state);
 int lua_Game_isMouseCaptured(lua_State* state);
 int lua_Game_isMouseCaptured(lua_State* state);

+ 6 - 6
gameplay/src/lua/lua_GestureGestureEvent.cpp

@@ -6,33 +6,33 @@ namespace gameplay
 
 
 static const char* enumStringEmpty = "";
 static const char* enumStringEmpty = "";
 
 
+static const char* luaEnumString_GestureGestureEvent_GESTURE_TAP = "GESTURE_TAP";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_SWIPE = "GESTURE_SWIPE";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_SWIPE = "GESTURE_SWIPE";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_PINCH = "GESTURE_PINCH";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_PINCH = "GESTURE_PINCH";
-static const char* luaEnumString_GestureGestureEvent_GESTURE_TAP = "GESTURE_TAP";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED = "GESTURE_ANY_SUPPORTED";
 static const char* luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED = "GESTURE_ANY_SUPPORTED";
 
 
 Gesture::GestureEvent lua_enumFromString_GestureGestureEvent(const char* s)
 Gesture::GestureEvent lua_enumFromString_GestureGestureEvent(const char* s)
 {
 {
+    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_TAP) == 0)
+        return Gesture::GESTURE_TAP;
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_SWIPE) == 0)
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_SWIPE) == 0)
         return Gesture::GESTURE_SWIPE;
         return Gesture::GESTURE_SWIPE;
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_PINCH) == 0)
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_PINCH) == 0)
         return Gesture::GESTURE_PINCH;
         return Gesture::GESTURE_PINCH;
-    if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_TAP) == 0)
-        return Gesture::GESTURE_TAP;
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED) == 0)
     if (strcmp(s, luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED) == 0)
         return Gesture::GESTURE_ANY_SUPPORTED;
         return Gesture::GESTURE_ANY_SUPPORTED;
     GP_ERROR("Invalid enumeration value '%s' for enumeration Gesture::GestureEvent.", s);
     GP_ERROR("Invalid enumeration value '%s' for enumeration Gesture::GestureEvent.", s);
-    return Gesture::GESTURE_SWIPE;
+    return Gesture::GESTURE_TAP;
 }
 }
 
 
 const char* lua_stringFromEnum_GestureGestureEvent(Gesture::GestureEvent e)
 const char* lua_stringFromEnum_GestureGestureEvent(Gesture::GestureEvent e)
 {
 {
+    if (e == Gesture::GESTURE_TAP)
+        return luaEnumString_GestureGestureEvent_GESTURE_TAP;
     if (e == Gesture::GESTURE_SWIPE)
     if (e == Gesture::GESTURE_SWIPE)
         return luaEnumString_GestureGestureEvent_GESTURE_SWIPE;
         return luaEnumString_GestureGestureEvent_GESTURE_SWIPE;
     if (e == Gesture::GESTURE_PINCH)
     if (e == Gesture::GESTURE_PINCH)
         return luaEnumString_GestureGestureEvent_GESTURE_PINCH;
         return luaEnumString_GestureGestureEvent_GESTURE_PINCH;
-    if (e == Gesture::GESTURE_TAP)
-        return luaEnumString_GestureGestureEvent_GESTURE_TAP;
     if (e == Gesture::GESTURE_ANY_SUPPORTED)
     if (e == Gesture::GESTURE_ANY_SUPPORTED)
         return luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED;
         return luaEnumString_GestureGestureEvent_GESTURE_ANY_SUPPORTED;
     GP_ERROR("Invalid enumeration value '%d' for enumeration Gesture::GestureEvent.", e);
     GP_ERROR("Invalid enumeration value '%d' for enumeration Gesture::GestureEvent.", e);

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

@@ -44,6 +44,8 @@ void luaRegister_lua_Global()
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsCharacter");
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsCharacter");
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsGhostObject");
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsGhostObject");
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsRigidBody");
     ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsRigidBody");
+    ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsVehicle");
+    ScriptUtil::setGlobalHierarchyPair("PhysicsCollisionObject", "PhysicsVehicleWheel");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsFixedConstraint");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsFixedConstraint");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsGenericConstraint");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsGenericConstraint");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsHingeConstraint");
     ScriptUtil::setGlobalHierarchyPair("PhysicsConstraint", "PhysicsHingeConstraint");
@@ -360,9 +362,9 @@ void luaRegister_lua_Global()
     {
     {
         std::vector<std::string> scopePath;
         std::vector<std::string> scopePath;
         scopePath.push_back("Gesture");
         scopePath.push_back("Gesture");
+        ScriptUtil::registerConstantString("GESTURE_TAP", "GESTURE_TAP", scopePath);
         ScriptUtil::registerConstantString("GESTURE_SWIPE", "GESTURE_SWIPE", scopePath);
         ScriptUtil::registerConstantString("GESTURE_SWIPE", "GESTURE_SWIPE", scopePath);
         ScriptUtil::registerConstantString("GESTURE_PINCH", "GESTURE_PINCH", scopePath);
         ScriptUtil::registerConstantString("GESTURE_PINCH", "GESTURE_PINCH", scopePath);
-        ScriptUtil::registerConstantString("GESTURE_TAP", "GESTURE_TAP", scopePath);
         ScriptUtil::registerConstantString("GESTURE_ANY_SUPPORTED", "GESTURE_ANY_SUPPORTED", scopePath);
         ScriptUtil::registerConstantString("GESTURE_ANY_SUPPORTED", "GESTURE_ANY_SUPPORTED", scopePath);
     }
     }
 
 
@@ -632,6 +634,8 @@ void luaRegister_lua_Global()
         ScriptUtil::registerConstantString("RIGID_BODY", "RIGID_BODY", scopePath);
         ScriptUtil::registerConstantString("RIGID_BODY", "RIGID_BODY", scopePath);
         ScriptUtil::registerConstantString("CHARACTER", "CHARACTER", scopePath);
         ScriptUtil::registerConstantString("CHARACTER", "CHARACTER", scopePath);
         ScriptUtil::registerConstantString("GHOST_OBJECT", "GHOST_OBJECT", scopePath);
         ScriptUtil::registerConstantString("GHOST_OBJECT", "GHOST_OBJECT", scopePath);
+        ScriptUtil::registerConstantString("VEHICLE", "VEHICLE", scopePath);
+        ScriptUtil::registerConstantString("VEHICLE_WHEEL", "VEHICLE_WHEEL", scopePath);
         ScriptUtil::registerConstantString("NONE", "NONE", scopePath);
         ScriptUtil::registerConstantString("NONE", "NONE", scopePath);
     }
     }
 
 

+ 130 - 0
gameplay/src/lua/lua_Joint.cpp

@@ -12,6 +12,8 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsCharacter.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsRigidBody.h"
 #include "PhysicsRigidBody.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
 #include "Ref.h"
 #include "Ref.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "ScriptController.h"
 #include "ScriptController.h"
@@ -28,6 +30,7 @@ void luaRegister_Joint()
 {
 {
     const luaL_Reg lua_members[] = 
     const luaL_Reg lua_members[] = 
     {
     {
+        {"addAdvertisedDescendant", lua_Joint_addAdvertisedDescendant},
         {"addChild", lua_Joint_addChild},
         {"addChild", lua_Joint_addChild},
         {"addListener", lua_Joint_addListener},
         {"addListener", lua_Joint_addListener},
         {"addRef", lua_Joint_addRef},
         {"addRef", lua_Joint_addRef},
@@ -40,6 +43,7 @@ void luaRegister_Joint()
         {"findNode", lua_Joint_findNode},
         {"findNode", lua_Joint_findNode},
         {"getActiveCameraTranslationView", lua_Joint_getActiveCameraTranslationView},
         {"getActiveCameraTranslationView", lua_Joint_getActiveCameraTranslationView},
         {"getActiveCameraTranslationWorld", lua_Joint_getActiveCameraTranslationWorld},
         {"getActiveCameraTranslationWorld", lua_Joint_getActiveCameraTranslationWorld},
+        {"getAdvertisedDescendant", lua_Joint_getAdvertisedDescendant},
         {"getAgent", lua_Joint_getAgent},
         {"getAgent", lua_Joint_getAgent},
         {"getAnimation", lua_Joint_getAnimation},
         {"getAnimation", lua_Joint_getAnimation},
         {"getAnimationPropertyComponentCount", lua_Joint_getAnimationPropertyComponentCount},
         {"getAnimationPropertyComponentCount", lua_Joint_getAnimationPropertyComponentCount},
@@ -67,6 +71,7 @@ void luaRegister_Joint()
         {"getMatrix", lua_Joint_getMatrix},
         {"getMatrix", lua_Joint_getMatrix},
         {"getModel", lua_Joint_getModel},
         {"getModel", lua_Joint_getModel},
         {"getNextSibling", lua_Joint_getNextSibling},
         {"getNextSibling", lua_Joint_getNextSibling},
+        {"getNumAdvertisedDescendants", lua_Joint_getNumAdvertisedDescendants},
         {"getParent", lua_Joint_getParent},
         {"getParent", lua_Joint_getParent},
         {"getParticleEmitter", lua_Joint_getParticleEmitter},
         {"getParticleEmitter", lua_Joint_getParticleEmitter},
         {"getPreviousSibling", lua_Joint_getPreviousSibling},
         {"getPreviousSibling", lua_Joint_getPreviousSibling},
@@ -216,6 +221,44 @@ int lua_Joint__gc(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Joint_addAdvertisedDescendant(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                ScriptUtil::LuaArray<Node> param1 = ScriptUtil::getObjectPointer<Node>(2, "Node", false);
+
+                Joint* instance = getInstance(state);
+                instance->addAdvertisedDescendant(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Joint_addAdvertisedDescendant - 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_Joint_addChild(lua_State* state)
 int lua_Joint_addChild(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -1043,6 +1086,56 @@ int lua_Joint_getActiveCameraTranslationWorld(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Joint_getAdvertisedDescendant(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_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                Joint* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAdvertisedDescendant(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Node");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Joint_getAdvertisedDescendant - 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_Joint_getAgent(lua_State* state)
 int lua_Joint_getAgent(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2370,6 +2463,43 @@ int lua_Joint_getNextSibling(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Joint_getNumAdvertisedDescendants(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))
+            {
+                Joint* instance = getInstance(state);
+                unsigned int result = instance->getNumAdvertisedDescendants();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Joint_getNumAdvertisedDescendants - 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_Joint_getParent(lua_State* state)
 int lua_Joint_getParent(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

+ 3 - 0
gameplay/src/lua/lua_Joint.h

@@ -6,6 +6,7 @@ namespace gameplay
 
 
 // Lua bindings for Joint.
 // Lua bindings for Joint.
 int lua_Joint__gc(lua_State* state);
 int lua_Joint__gc(lua_State* state);
+int lua_Joint_addAdvertisedDescendant(lua_State* state);
 int lua_Joint_addChild(lua_State* state);
 int lua_Joint_addChild(lua_State* state);
 int lua_Joint_addListener(lua_State* state);
 int lua_Joint_addListener(lua_State* state);
 int lua_Joint_addRef(lua_State* state);
 int lua_Joint_addRef(lua_State* state);
@@ -18,6 +19,7 @@ int lua_Joint_destroyAnimation(lua_State* state);
 int lua_Joint_findNode(lua_State* state);
 int lua_Joint_findNode(lua_State* state);
 int lua_Joint_getActiveCameraTranslationView(lua_State* state);
 int lua_Joint_getActiveCameraTranslationView(lua_State* state);
 int lua_Joint_getActiveCameraTranslationWorld(lua_State* state);
 int lua_Joint_getActiveCameraTranslationWorld(lua_State* state);
+int lua_Joint_getAdvertisedDescendant(lua_State* state);
 int lua_Joint_getAgent(lua_State* state);
 int lua_Joint_getAgent(lua_State* state);
 int lua_Joint_getAnimation(lua_State* state);
 int lua_Joint_getAnimation(lua_State* state);
 int lua_Joint_getAnimationPropertyComponentCount(lua_State* state);
 int lua_Joint_getAnimationPropertyComponentCount(lua_State* state);
@@ -45,6 +47,7 @@ int lua_Joint_getLight(lua_State* state);
 int lua_Joint_getMatrix(lua_State* state);
 int lua_Joint_getMatrix(lua_State* state);
 int lua_Joint_getModel(lua_State* state);
 int lua_Joint_getModel(lua_State* state);
 int lua_Joint_getNextSibling(lua_State* state);
 int lua_Joint_getNextSibling(lua_State* state);
+int lua_Joint_getNumAdvertisedDescendants(lua_State* state);
 int lua_Joint_getParent(lua_State* state);
 int lua_Joint_getParent(lua_State* state);
 int lua_Joint_getParticleEmitter(lua_State* state);
 int lua_Joint_getParticleEmitter(lua_State* state);
 int lua_Joint_getPreviousSibling(lua_State* state);
 int lua_Joint_getPreviousSibling(lua_State* state);

+ 47 - 0
gameplay/src/lua/lua_MaterialParameter.cpp

@@ -28,6 +28,7 @@ void luaRegister_MaterialParameter()
         {"getAnimationPropertyValue", lua_MaterialParameter_getAnimationPropertyValue},
         {"getAnimationPropertyValue", lua_MaterialParameter_getAnimationPropertyValue},
         {"getName", lua_MaterialParameter_getName},
         {"getName", lua_MaterialParameter_getName},
         {"getRefCount", lua_MaterialParameter_getRefCount},
         {"getRefCount", lua_MaterialParameter_getRefCount},
+        {"getSampler", lua_MaterialParameter_getSampler},
         {"release", lua_MaterialParameter_release},
         {"release", lua_MaterialParameter_release},
         {"setAnimationPropertyValue", lua_MaterialParameter_setAnimationPropertyValue},
         {"setAnimationPropertyValue", lua_MaterialParameter_setAnimationPropertyValue},
         {"setValue", lua_MaterialParameter_setValue},
         {"setValue", lua_MaterialParameter_setValue},
@@ -788,6 +789,52 @@ int lua_MaterialParameter_getRefCount(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_MaterialParameter_getSampler(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))
+            {
+                MaterialParameter* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getSampler();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "TextureSampler");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_MaterialParameter_getSampler - 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_MaterialParameter_release(lua_State* state)
 int lua_MaterialParameter_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

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

@@ -17,6 +17,7 @@ int lua_MaterialParameter_getAnimationPropertyComponentCount(lua_State* state);
 int lua_MaterialParameter_getAnimationPropertyValue(lua_State* state);
 int lua_MaterialParameter_getAnimationPropertyValue(lua_State* state);
 int lua_MaterialParameter_getName(lua_State* state);
 int lua_MaterialParameter_getName(lua_State* state);
 int lua_MaterialParameter_getRefCount(lua_State* state);
 int lua_MaterialParameter_getRefCount(lua_State* state);
+int lua_MaterialParameter_getSampler(lua_State* state);
 int lua_MaterialParameter_release(lua_State* state);
 int lua_MaterialParameter_release(lua_State* state);
 int lua_MaterialParameter_setAnimationPropertyValue(lua_State* state);
 int lua_MaterialParameter_setAnimationPropertyValue(lua_State* state);
 int lua_MaterialParameter_setValue(lua_State* state);
 int lua_MaterialParameter_setValue(lua_State* state);

+ 209 - 1
gameplay/src/lua/lua_Mesh.cpp

@@ -1241,9 +1241,217 @@ int lua_Mesh_static_createQuad(lua_State* state)
             }
             }
             break;
             break;
         }
         }
+        case 5:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 1);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 3);
+
+                // Get parameter 4 off the stack.
+                float param4 = (float)luaL_checknumber(state, 4);
+
+                // Get parameter 5 off the stack.
+                float param5 = (float)luaL_checknumber(state, 5);
+
+                void* returnPtr = (void*)Mesh::createQuad(param1, param2, param3, param4, param5);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Mesh");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Mesh_static_createQuad - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        case 6:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER &&
+                lua_type(state, 6) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 1);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 3);
+
+                // Get parameter 4 off the stack.
+                float param4 = (float)luaL_checknumber(state, 4);
+
+                // Get parameter 5 off the stack.
+                float param5 = (float)luaL_checknumber(state, 5);
+
+                // Get parameter 6 off the stack.
+                float param6 = (float)luaL_checknumber(state, 6);
+
+                void* returnPtr = (void*)Mesh::createQuad(param1, param2, param3, param4, param5, param6);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Mesh");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Mesh_static_createQuad - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        case 7:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER &&
+                lua_type(state, 6) == LUA_TNUMBER &&
+                lua_type(state, 7) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 1);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 3);
+
+                // Get parameter 4 off the stack.
+                float param4 = (float)luaL_checknumber(state, 4);
+
+                // Get parameter 5 off the stack.
+                float param5 = (float)luaL_checknumber(state, 5);
+
+                // Get parameter 6 off the stack.
+                float param6 = (float)luaL_checknumber(state, 6);
+
+                // Get parameter 7 off the stack.
+                float param7 = (float)luaL_checknumber(state, 7);
+
+                void* returnPtr = (void*)Mesh::createQuad(param1, param2, param3, param4, param5, param6, param7);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Mesh");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Mesh_static_createQuad - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        case 8:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER &&
+                lua_type(state, 5) == LUA_TNUMBER &&
+                lua_type(state, 6) == LUA_TNUMBER &&
+                lua_type(state, 7) == LUA_TNUMBER &&
+                lua_type(state, 8) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 1);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 3);
+
+                // Get parameter 4 off the stack.
+                float param4 = (float)luaL_checknumber(state, 4);
+
+                // Get parameter 5 off the stack.
+                float param5 = (float)luaL_checknumber(state, 5);
+
+                // Get parameter 6 off the stack.
+                float param6 = (float)luaL_checknumber(state, 6);
+
+                // Get parameter 7 off the stack.
+                float param7 = (float)luaL_checknumber(state, 7);
+
+                // Get parameter 8 off the stack.
+                float param8 = (float)luaL_checknumber(state, 8);
+
+                void* returnPtr = (void*)Mesh::createQuad(param1, param2, param3, param4, param5, param6, param7, param8);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = true;
+                    luaL_getmetatable(state, "Mesh");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Mesh_static_createQuad - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_pushstring(state, "Invalid number of parameters (expected 4, 5, 6, 7 or 8).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 130 - 0
gameplay/src/lua/lua_Node.cpp

@@ -11,6 +11,8 @@
 #include "PhysicsCharacter.h"
 #include "PhysicsCharacter.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsGhostObject.h"
 #include "PhysicsRigidBody.h"
 #include "PhysicsRigidBody.h"
+#include "PhysicsVehicle.h"
+#include "PhysicsVehicleWheel.h"
 #include "Ref.h"
 #include "Ref.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "ScriptController.h"
 #include "ScriptController.h"
@@ -27,6 +29,7 @@ void luaRegister_Node()
 {
 {
     const luaL_Reg lua_members[] = 
     const luaL_Reg lua_members[] = 
     {
     {
+        {"addAdvertisedDescendant", lua_Node_addAdvertisedDescendant},
         {"addChild", lua_Node_addChild},
         {"addChild", lua_Node_addChild},
         {"addListener", lua_Node_addListener},
         {"addListener", lua_Node_addListener},
         {"addRef", lua_Node_addRef},
         {"addRef", lua_Node_addRef},
@@ -39,6 +42,7 @@ void luaRegister_Node()
         {"findNode", lua_Node_findNode},
         {"findNode", lua_Node_findNode},
         {"getActiveCameraTranslationView", lua_Node_getActiveCameraTranslationView},
         {"getActiveCameraTranslationView", lua_Node_getActiveCameraTranslationView},
         {"getActiveCameraTranslationWorld", lua_Node_getActiveCameraTranslationWorld},
         {"getActiveCameraTranslationWorld", lua_Node_getActiveCameraTranslationWorld},
+        {"getAdvertisedDescendant", lua_Node_getAdvertisedDescendant},
         {"getAgent", lua_Node_getAgent},
         {"getAgent", lua_Node_getAgent},
         {"getAnimation", lua_Node_getAnimation},
         {"getAnimation", lua_Node_getAnimation},
         {"getAnimationPropertyComponentCount", lua_Node_getAnimationPropertyComponentCount},
         {"getAnimationPropertyComponentCount", lua_Node_getAnimationPropertyComponentCount},
@@ -65,6 +69,7 @@ void luaRegister_Node()
         {"getMatrix", lua_Node_getMatrix},
         {"getMatrix", lua_Node_getMatrix},
         {"getModel", lua_Node_getModel},
         {"getModel", lua_Node_getModel},
         {"getNextSibling", lua_Node_getNextSibling},
         {"getNextSibling", lua_Node_getNextSibling},
+        {"getNumAdvertisedDescendants", lua_Node_getNumAdvertisedDescendants},
         {"getParent", lua_Node_getParent},
         {"getParent", lua_Node_getParent},
         {"getParticleEmitter", lua_Node_getParticleEmitter},
         {"getParticleEmitter", lua_Node_getParticleEmitter},
         {"getPreviousSibling", lua_Node_getPreviousSibling},
         {"getPreviousSibling", lua_Node_getPreviousSibling},
@@ -215,6 +220,44 @@ int lua_Node__gc(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Node_addAdvertisedDescendant(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_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                ScriptUtil::LuaArray<Node> param1 = ScriptUtil::getObjectPointer<Node>(2, "Node", false);
+
+                Node* instance = getInstance(state);
+                instance->addAdvertisedDescendant(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Node_addAdvertisedDescendant - 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_Node_addChild(lua_State* state)
 int lua_Node_addChild(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -1042,6 +1085,56 @@ int lua_Node_getActiveCameraTranslationWorld(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Node_getAdvertisedDescendant(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_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                Node* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAdvertisedDescendant(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Node");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Node_getAdvertisedDescendant - 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_Node_getAgent(lua_State* state)
 int lua_Node_getAgent(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2323,6 +2416,43 @@ int lua_Node_getNextSibling(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Node_getNumAdvertisedDescendants(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))
+            {
+                Node* instance = getInstance(state);
+                unsigned int result = instance->getNumAdvertisedDescendants();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Node_getNumAdvertisedDescendants - 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_Node_getParent(lua_State* state)
 int lua_Node_getParent(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików