Browse Source

Merge branch 'next' of https://github.com/blackberry/GamePlay into next
Also fixing a memory leak in Gamepad.cpp.

Conflicts:
gameplay-tests/src/TestsGame.cpp

Adam Blake 13 years ago
parent
commit
bad067b854
50 changed files with 2199 additions and 2769 deletions
  1. 2 1
      CHANGES.md
  2. 7 7
      README.md
  3. 23 7
      gameplay-encoder/README.md
  4. 5 0
      gameplay-encoder/src/Base.h
  5. 2 2
      gameplay-encoder/src/FileIO.h
  6. 2 1
      gameplay-encoder/src/Heightmap.cpp
  7. 72 11
      gameplay-encoder/src/NormalMapGenerator.cpp
  8. 0 15
      gameplay-luagen/gameplay-api/xml/combine.xslt
  9. 0 832
      gameplay-luagen/gameplay-api/xml/compound.xsd
  10. 0 3
      gameplay-luagen/gameplay-api/xml/index.xml
  11. 0 66
      gameplay-luagen/gameplay-api/xml/index.xsd
  12. 2 2
      gameplay-luagen/gameplay-luagen.vcxproj
  13. 2 1
      gameplay-luagen/src/main.cpp
  14. 2 8
      gameplay-newproject.sh
  15. 6 12
      gameplay-template/template.bar-descriptor.xml
  16. 12 3
      gameplay/.cproject
  17. 1 1
      gameplay/android/jni/Android.mk
  18. 2 1
      gameplay/res/shaders/terrain.frag
  19. 11 1
      gameplay/src/Button.h
  20. 1 1
      gameplay/src/CheckBox.h
  21. 2 2
      gameplay/src/Container.h
  22. 1 1
      gameplay/src/Control.h
  23. 2 2
      gameplay/src/DebugNew.cpp
  24. 1 1
      gameplay/src/Game.h
  25. 2 0
      gameplay/src/Gamepad.cpp
  26. 14 16
      gameplay/src/HeightField.cpp
  27. 7 9
      gameplay/src/HeightField.h
  28. 6 1
      gameplay/src/Joystick.h
  29. 1 1
      gameplay/src/Layout.h
  30. 4 5
      gameplay/src/Matrix.h
  31. 6 1
      gameplay/src/Platform.h
  32. 13 13
      gameplay/src/PlatformBlackBerry.cpp
  33. 1 1
      gameplay/src/PlatformMacOSX.mm
  34. 1 1
      gameplay/src/RadioButton.h
  35. 1 1
      gameplay/src/ScriptController.h
  36. 30 30
      gameplay/src/Slider.cpp
  37. 33 3
      gameplay/src/Slider.h
  38. 2 2
      gameplay/src/Terrain.cpp
  39. 8 11
      gameplay/src/Terrain.h
  40. 671 673
      gameplay/src/TerrainPatch.cpp
  41. 7 14
      gameplay/src/TerrainPatch.h
  42. 1 1
      gameplay/src/TextBox.h
  43. 1 1
      gameplay/src/Texture.cpp
  44. 2 0
      gameplay/src/Texture.h
  45. 3 3
      gameplay/src/lua/lua_Global.cpp
  46. 1 0
      gameplay/src/lua/lua_Scene.cpp
  47. 219 0
      gameplay/src/lua/lua_Slider.cpp
  48. 6 0
      gameplay/src/lua/lua_Slider.h
  49. 991 991
      gameplay/src/lua/lua_Terrain.cpp
  50. 10 10
      gameplay/src/lua/lua_TerrainFlags.cpp

+ 2 - 1
CHANGES.md

@@ -22,6 +22,7 @@
 - Adds support for latest Bullet Physics 2.81 with NEON optimizations for mobile targets.
 - Adds support for preprocessor directive NO_LUA_BINDINGS in the gameplay project to omit inclusion of generated lua bindings in compilation for developer mode value. 
 - Adds optimizations to Lua generator to only write generated files if they differ from existing files, reducing both build times and committing of unchanged script binding files.
+- Adds changes to Slider for setValueTextVisible, setValueTextAlignment, setValueTextPrecision and getters.
 - Adds Windows 7 64-bit support.
 - Fixes to external-deps to reduce the size of the libraries on Windows.
 - Fixes for Android to no longer need to copy files to the SD card before reading them. None of the Android samples require an SD card.
@@ -143,7 +144,7 @@
 - Fixes to the material/shader system.
 - Fixes to the ParticleEmitter.
 
-## v1.0.1
+## v1.0.0
 
 - Initial release.
 

+ 7 - 7
README.md

@@ -8,17 +8,17 @@ GamePlay3D is an open-source, cross-platform 3D native C++ game framework making
 - [Forums](http://www.gameplay3d.org/forums/)
 - [Wiki](https://github.com/blackberry/GamePlay/wiki)
 - [API Reference](http://www.gameplay3d.org/api.php)
-- [Documentation](http://www.gameplay3d.org/docs.php)
+- [Development Guide](https://github.com/blackberry/GamePlay/wiki#wiki-Development_Guide)
 
 ## Supported Mobile Platforms
-- BlackBerry 10 and PlayBook (using [BlackBerry Native SDK](http://developer.blackberry.com/native/))
-- Apple iOS 5 (using Apple XCode 4)
-- Google Android 2.3+ (using Google Android NDK)
+- [BlackBerry 10 and PlayBook](https://github.com/blackberry/GamePlay/wiki/BlackBerry-Setup) (using BlackBerry Native SDK)
+- [Apple iOS 5](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
+- [Google Android 2.3+](https://github.com/blackberry/GamePlay/wiki/Android-NDK-Setup) (using Google Android NDK)
 
 ## Supported Desktop Platforms
-- Microsoft Windows 7 (using Microsoft Visual Studio 2010)
-- Apple MacOS X (using Apple XCode 4)
-- Linux (using CMake)
+- [Microsoft Windows 7](https://github.com/blackberry/GamePlay/wiki/Visual-Studio-Setup) (using Microsoft Visual Studio 2010)
+- [Apple MacOS X](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
+- [Linux](https://github.com/blackberry/GamePlay/wiki/Linux-Setup) (using CMake)
 
 ## Roadmap for 'next' branch
 - [Version 1.7.0 Milestone](https://github.com/blackberry/GamePlay/issues?milestone=4)

+ 23 - 7
gameplay-encoder/README.md

@@ -2,7 +2,7 @@
 Command-line tool for encoding games assets like true-type fonts and 3D scene files
 into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
 The 'bin' folder contains pre-built versions of the gameplay-encoder executables for 
-Windows 7, MacOS X and Linux (tested on Ubuntu 12) with support built-in support for:
+Windows 7, MacOS X and Linux Ubuntu 12 (32-bit) with support built-in support for:
 
 ## TrueType Font
 TrueType Fonts represent a standard in defining outline fonts and has become the 
@@ -20,8 +20,17 @@ between several Autodesk content creation packages
 Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
 For more information goto "http://www.autodesk.com/fbx".
 
+## Running gameplay-encoder
+Simply execute the gameplay-encoder command-line executable:
+
+`Usage: gameplay-encoder [options] <file(s)>`
+
+Note: On Linux Ubuntu 12 (64-bit), you must first install the required 32-bit libs via:
+
+`sudo apt-get install ia32-libs`
+
 ## Building gameplay-encoder
-The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux x64 in the 'bin' folder.
+The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux Ubuntu 12 (32-bit) in the 'bin' folder.
 However, to build the gameplay-encoder yourself just open either the 
 Visual Studio 2010 project "gameplay-encoder.vccproj" on Windows 7 or
 XCode project "gameplay-encoder.xcodeproj" on MacOSX.
@@ -39,8 +48,8 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: fbxsdk-2013.3-mdd.lib
 - Build gameplay-encoder
 
-### Building with FBX Support on Mac OS X using XCode 4.3.2+
-- Download and install the FBX SDK for Mac OS X (http://www.autodesk.com/fbx)
+### Building with FBX Support on MacOS X using XCode 4
+- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
 - Edit the project properties of target "gameplay-encoder".
 - Add Preprocessor Macro "USE_FBX" to both Debug/Release sections. (Build Settings)
 - Add the FBX include directory to Header Search Paths: (Build Settings)
@@ -49,8 +58,8 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: /Applications/Autodesk/FBX SDK/2013.3/lib/gcc4/ub/libfbxsdk-2013.3-static.a  (Add Other)
 - Build gameplay-encoder
 
-### Building with FBX Support on Linux
-- Download and install the FBX SDK for Mac OS X (http://www.autodesk.com/fbx)
+### Building with FBX Support on Linux Ubuntu 12 (32-bit) using CMake
+- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
 - Edit the gameplay-encoder/CMakeLists.txt adding the following:
 - Add the FBX include directory to Header Search Paths: (Build Settings)
   * Example: /usr/include/fbxsdk
@@ -61,7 +70,14 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: fbxsdk-2013.3-static
 - Add the FBX library to the library to the add_definitions(-l...) section of the CMakeLists.txt
   * Example -lfbxsdk-2013.3-static
-- Build gameplay-encoder via main cmake .. in build then make.
+- Build gameplay-encoder by uncommenting the last line in the gameplay/CMakeLists.txt and running the CMake build via:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+ ```
 
 ## Bundle File Format
 The gameplay bundle file format is well defined in the gameplay-encoder/gameplay-bundle.txt file.

+ 5 - 0
gameplay-encoder/src/Base.h

@@ -20,6 +20,11 @@
 #include <algorithm>
 #include <sys/stat.h>
 
+using std::memcpy;
+using std::size_t;
+using std::min;
+using std::max;
+
 // PNG
 #include <png.h>
 

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

@@ -29,7 +29,7 @@ void fprintfElement(FILE* file, const char* elementName, const std::string& valu
 void fprintfElement(FILE* file, const char* elementName, const float values[], int length);
 
 template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T> list)
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T>& list)
 {
     fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
     typename std::vector<T>::const_iterator i;
@@ -41,7 +41,7 @@ void fprintfElement(FILE* file, const char* format, const char* elementName, std
 }
 
 template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T> list)
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T>& list)
 {
     fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
     typename std::list<T>::const_iterator i;

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

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Heightmap.h"
 #include "GPBFile.h"
 #include "Thread.h"
@@ -108,7 +109,7 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, int width, int
     __totalHeightmapScanlines = height;
 
     // Determine # of threads to spawn
-    int threadCount = std::min(THREAD_COUNT, height);
+    int threadCount = min(THREAD_COUNT, height);
 
     // Split the work into separate threads to make max use of available cpu cores and speed up computation.
     HeightmapThreadData* threadData = new HeightmapThreadData[threadCount];

+ 72 - 11
gameplay-encoder/src/NormalMapGenerator.cpp

@@ -60,6 +60,16 @@ void calculateNormal(
     Vector3::cross(Q, P, normal);
 }
 
+float normalizedHeightPacked(float r, float g, float b)
+{
+    // This formula is intended for 24-bit packed heightmap images (that are generated
+    // with gameplay-encoder. However, it is also compatible with normal grayscale 
+    // heightmap images, with an error of approximately 0.4%. This can be seen by
+    // setting r=g=b=x and comparing the grayscale height expression to the packed
+    // height expression: the error is 2^-8 + 2^-16 which is just under 0.4%.
+    return (256.0f*r + g + 0.00390625f*b) / 65536.0f;
+}
+
 void NormalMapGenerator::generate()
 {
     // Load the input heightmap
@@ -76,8 +86,6 @@ void NormalMapGenerator::generate()
             return;
         }
 
-        // TODO: Add command-line argument for high precision heightmaps
-
         _resolutionX = image->getWidth();
         _resolutionY = image->getHeight();
         int size = _resolutionX * _resolutionY;
@@ -88,20 +96,20 @@ void NormalMapGenerator::generate()
             switch (image->getFormat())
             {
             case Image::LUMINANCE:
-                heights[i] = data[i];
+                heights[i] = data[i] / 255.0f;
                 break;
             case Image::RGB:
             case Image::RGBA:
                 {
                     int pos = i * image->getBpp();
-                    heights[i] = (data[pos] + data[pos+1] + data[pos+2]) / 3.0f;
+                    heights[i] = normalizedHeightPacked(data[pos], data[pos+1], data[pos+2]);
                 }
                 break;
             default:
                 heights[i] = 0.0f;
                 break;
             }
-            heights[i] = (heights[i] / 255.0f) * _worldSize.y;
+            heights[i] = heights[i] * _worldSize.y;
         }
         SAFE_DELETE(image);
     }
@@ -110,16 +118,69 @@ void NormalMapGenerator::generate()
         // Load heights from RAW 8 or 16-bit file
         if (_resolutionX <= 0 || _resolutionY <= 0)
         {
-            LOG(1, "Missing resolution argument - must be explicitly specified for RAW heightmap files: %s\n.", _inputFile.c_str());
+            LOG(1, "Missing resolution argument - must be explicitly specified for RAW heightmap files: %s.\n", _inputFile.c_str());
             return;
         }
 
-        // TODO
-        heights = new float[_resolutionX * _resolutionY];
-        // TODO
+        // Read all data from file
+        FILE* fp = fopen(_inputFile.c_str(), "rb");
+        if (fp == NULL)
+        {
+            LOG(1, "Failed to open input file: %s.\n", _inputFile.c_str());
+            return;
+        }
 
-        LOG(1, "RAW files not yet implemented...");
-        return;
+        fseek(fp, 0, SEEK_END);
+        long fileSize = ftell(fp);
+        fseek(fp, 0, SEEK_SET);
+
+        unsigned char* data = new unsigned char[fileSize];
+        if (fread(data, 1, fileSize, fp) != (size_t)fileSize)
+        {
+            fclose(fp);
+            delete[] data;
+            LOG(1, "Failed to read bytes from input file: %s.\n", _inputFile.c_str());
+            return;
+        }
+        fclose(fp);
+
+        // Determine if the RAW file is 8-bit or 16-bit based on file size.
+        int bits = (fileSize / (_resolutionX * _resolutionY)) * 8;
+        if (bits != 8 && bits != 16)
+        {
+            LOG(1, "Invalid RAW file - must be 8-bit or 16-bit, but found neither: %s.", _inputFile.c_str());
+            delete[] data;
+            return;
+        }
+
+        int size = _resolutionX * _resolutionY;
+        heights = new float[size];
+        if (bits == 16)
+        {
+            // 16-bit (0-65535)
+            int idx;
+            for (unsigned int y = 0, i = 0; y < (unsigned int)_resolutionY; ++y)
+            {
+                for (unsigned int x = 0; x < (unsigned int)_resolutionX; ++x, ++i)
+                {
+                    idx = (y * _resolutionX + x) << 1;
+                    heights[i] = ((data[idx] | (int)data[idx+1] << 8) / 65535.0f) * _worldSize.y;
+                }
+            }
+        }
+        else
+        {
+            // 8-bit (0-255)
+            for (unsigned int y = 0, i = 0; y < (unsigned int)_resolutionY; ++y)
+            {
+                for (unsigned int x = 0; x < (unsigned int)_resolutionX; ++x, ++i)
+                {
+                    heights[i] = (data[y * _resolutionX + x] / 255.0f) * _worldSize.y;
+                }
+            }
+        }
+
+        delete[] data;
     }
     else
     {

+ 0 - 15
gameplay-luagen/gameplay-api/xml/combine.xslt

@@ -1,15 +0,0 @@
-<!-- XSLT script to combine the generated output into a single file. 
-     If you have xsltproc you could use:
-     xsltproc combine.xslt index.xml >all.xml
--->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-  <xsl:output method="xml" version="1.0" indent="no" standalone="yes" />
-  <xsl:template match="/">
-    <doxygen version="{doxygenindex/@version}">
-      <!-- Load all doxgen generated xml files -->
-      <xsl:for-each select="doxygenindex/compound">
-        <xsl:copy-of select="document( concat( @refid, '.xml' ) )/doxygen/*" />
-      </xsl:for-each>
-    </doxygen>
-  </xsl:template>
-</xsl:stylesheet>

+ 0 - 832
gameplay-luagen/gameplay-api/xml/compound.xsd

@@ -1,832 +0,0 @@
-<?xml version='1.0' encoding='utf-8' ?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-  <xsd:element name="doxygen" type="DoxygenType"/>
-
-  <!-- Complex types -->
-
-  <xsd:complexType name="DoxygenType">
-    <xsd:sequence maxOccurs="unbounded">
-      <xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="version" type="DoxVersionNumber" use="required" />
-  </xsd:complexType>
-
-  <xsd:complexType name="compounddefType">
-    <xsd:sequence>
-      <xsd:element name="compoundname" type="xsd:string"/>
-      <xsd:element name="title" type="xsd:string" minOccurs="0" />
-      <xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
-      <xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
-      <xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="programlisting" type="listingType" minOccurs="0" />
-      <xsd:element name="location" type="locationType" minOccurs="0" />
-      <xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="kind" type="DoxCompoundKind" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="listofallmembersType">
-    <xsd:sequence>
-      <xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="memberRefType">
-    <xsd:sequence>
-      <xsd:element name="scope" />
-      <xsd:element name="name" />
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-    <xsd:attribute name="virt" type="DoxVirtualKind" />
-    <xsd:attribute name="ambiguityscope" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="compoundRefType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" use="optional" />
-        <xsd:attribute name="prot" type="DoxProtectionKind" />
-        <xsd:attribute name="virt" type="DoxVirtualKind" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="reimplementType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="incType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-        <xsd:attribute name="local" type="DoxBool" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="refType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-        <xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="refTextType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-       <xsd:attribute name="refid" type="xsd:string" />
-       <xsd:attribute name="kindref" type="DoxRefKind" />
-       <xsd:attribute name="external" type="xsd:string" use="optional"/>
-       <xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="sectiondefType">
-    <xsd:sequence>
-      <xsd:element name="header" type="xsd:string" minOccurs="0" />
-      <xsd:element name="description" type="descriptionType" minOccurs="0" />
-      <xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxSectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="memberdefType">
-    <xsd:sequence>
-      <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
-      <xsd:element name="type" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="definition" minOccurs="0" />
-      <xsd:element name="argsstring" minOccurs="0" />
-      <xsd:element name="name" />
-      <xsd:element name="read" minOccurs="0" />
-      <xsd:element name="write" minOccurs="0" />
-      <xsd:element name="bitfield" minOccurs="0" />
-      <xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="location" type="locationType" />
-      <xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxMemberKind" />
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-    <xsd:attribute name="static" type="DoxBool" />
-    <xsd:attribute name="const" type="DoxBool" />
-    <xsd:attribute name="explicit" type="DoxBool" />
-    <xsd:attribute name="inline" type="DoxBool" />
-    <xsd:attribute name="virt" type="DoxVirtualKind" />
-    <xsd:attribute name="volatile" type="DoxBool" />
-    <xsd:attribute name="mutable" type="DoxBool" />
-    <!-- Qt property -->
-    <xsd:attribute name="readable" type="DoxBool" use="optional"/>
-    <xsd:attribute name="writable" type="DoxBool" use="optional"/>
-    <!-- C++/CLI variable -->
-    <xsd:attribute name="initonly" type="DoxBool" use="optional"/>
-    <!-- C++/CLI and C# property -->
-    <xsd:attribute name="settable" type="DoxBool" use="optional"/>
-    <xsd:attribute name="gettable" type="DoxBool" use="optional"/>
-    <!-- C++/CLI function -->
-    <xsd:attribute name="final" type="DoxBool" use="optional"/>
-    <xsd:attribute name="sealed" type="DoxBool" use="optional"/>
-    <xsd:attribute name="new" type="DoxBool" use="optional"/>
-    <!-- C++/CLI event -->
-    <xsd:attribute name="add" type="DoxBool" use="optional"/>
-    <xsd:attribute name="remove" type="DoxBool" use="optional"/>
-    <xsd:attribute name="raise" type="DoxBool" use="optional"/>
-    <!-- Objective-C 2.0 protocol method -->
-    <xsd:attribute name="optional" type="DoxBool" use="optional"/>
-    <xsd:attribute name="required" type="DoxBool" use="optional"/>
-    <!-- Objective-C 2.0 property accessor -->
-    <xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="descriptionType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" minOccurs="0"/>	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalType" minOccurs="0" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="enumvalueType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="name" />
-      <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="templateparamlistType">
-    <xsd:sequence>
-      <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="paramType">
-    <xsd:sequence>
-      <xsd:element name="type" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="declname" minOccurs="0" />
-      <xsd:element name="defname" minOccurs="0" />
-      <xsd:element name="array" minOccurs="0" />
-      <xsd:element name="defval" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="linkedTextType" mixed="true">
-    <xsd:sequence>
-    <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="graphType">
-    <xsd:sequence>
-      <xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="nodeType">
-    <xsd:sequence>
-      <xsd:element name="label" />
-      <xsd:element name="link" type="linkType" minOccurs="0" />
-      <xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="childnodeType">
-    <xsd:sequence>
-      <xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="relation" type="DoxGraphRelation" />
-  </xsd:complexType>
-
-  <xsd:complexType name="linkType">
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="external" type="xsd:string" use="optional"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="listingType">
-    <xsd:sequence>
-      <xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="codelineType">
-    <xsd:sequence>
-      <xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="lineno" type="xsd:integer" />
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="refkind" type="DoxRefKind" />
-    <xsd:attribute name="external" type="DoxBool" />
-  </xsd:complexType>
-
-  <xsd:complexType name="highlightType" mixed="true">
-    <xsd:choice minOccurs="0" maxOccurs="unbounded">
-      <xsd:element name="sp" />
-      <xsd:element name="ref" type="refTextType" />
-    </xsd:choice>
-    <xsd:attribute name="class" type="DoxHighlightClass" />
-  </xsd:complexType>
-
-  <xsd:complexType name="referenceType" mixed="true">
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="compoundref" type="xsd:string" use="optional" />
-    <xsd:attribute name="startline" type="xsd:integer" />
-    <xsd:attribute name="endline" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="locationType">
-    <xsd:attribute name="file" type="xsd:string" />
-    <xsd:attribute name="line" type="xsd:integer" />
-    <xsd:attribute name="bodyfile" type="xsd:string" />
-    <xsd:attribute name="bodystart" type="xsd:integer" />
-    <xsd:attribute name="bodyend" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect1Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect2Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect3Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect4Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS1Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS2Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS3Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS4Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
- 
-  <xsd:group name="docTitleCmdGroup">
-    <xsd:choice>
-      <xsd:element name="ulink" type="docURLLink" />
-      <xsd:element name="bold" type="docMarkupType" />
-      <xsd:element name="emphasis" type="docMarkupType" />
-      <xsd:element name="computeroutput" type="docMarkupType" />
-      <xsd:element name="subscript" type="docMarkupType" />
-      <xsd:element name="superscript" type="docMarkupType" />
-      <xsd:element name="center" type="docMarkupType" />
-      <xsd:element name="small" type="docMarkupType" />
-      <xsd:element name="htmlonly" type="xsd:string" />
-      <xsd:element name="manonly" type="xsd:string" />
-      <xsd:element name="xmlonly" type="xsd:string" />
-      <xsd:element name="rtfonly" type="xsd:string" />
-      <xsd:element name="latexonly" type="xsd:string" />
-      <xsd:element name="dot" type="xsd:string" />
-      <xsd:element name="anchor" type="docAnchorType" />
-      <xsd:element name="formula" type="docFormulaType" />
-      <xsd:element name="ref" type="docRefTextType" />
-      <xsd:element name="copy" type="docEmptyType" />
-      <xsd:element name="trademark" type="docEmptyType" />
-      <xsd:element name="registered" type="docEmptyType" />
-      <xsd:element name="lsquo" type="docEmptyType" />
-      <xsd:element name="rsquo" type="docEmptyType" />
-      <xsd:element name="ldquo" type="docEmptyType" />
-      <xsd:element name="rdquo" type="docEmptyType" />
-      <xsd:element name="ndash" type="docEmptyType" />
-      <xsd:element name="mdash" type="docEmptyType" />
-      <xsd:element name="umlaut" type="docCharType" />
-      <xsd:element name="acute" type="docCharType" />
-      <xsd:element name="grave" type="docCharType" />
-      <xsd:element name="circ" type="docCharType" />
-      <xsd:element name="slash" type="docCharType" />
-      <xsd:element name="tilde" type="docCharType" />
-      <xsd:element name="cedil" type="docCharType" />
-      <xsd:element name="ring" type="docCharType" />
-      <xsd:element name="szlig" type="docEmptyType" />
-      <xsd:element name="nonbreakablespace" type="docEmptyType" />
-    </xsd:choice>
-  </xsd:group>
-
-  <xsd:complexType name="docTitleType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:group name="docCmdGroup">
-    <xsd:choice>
-      <xsd:group ref="docTitleCmdGroup"/>
-      <xsd:element name="linebreak" type="docEmptyType" />
-      <xsd:element name="hruler" type="docEmptyType" />
-      <xsd:element name="preformatted" type="docMarkupType" />
-      <xsd:element name="programlisting" type="listingType" />
-      <xsd:element name="verbatim" type="xsd:string" />
-      <xsd:element name="indexentry" type="docIndexEntryType" />
-      <xsd:element name="orderedlist" type="docListType" />
-      <xsd:element name="itemizedlist" type="docListType" />
-      <xsd:element name="simplesect" type="docSimpleSectType" />
-      <xsd:element name="title" type="docTitleType" />
-      <xsd:element name="variablelist" type="docVariableListType" />
-      <xsd:element name="table" type="docTableType" />
-      <xsd:element name="heading" type="docHeadingType" />
-      <xsd:element name="image" type="docImageType" />
-      <xsd:element name="dotfile" type="docDotFileType" />
-      <xsd:element name="toclist" type="docTocListType" />
-      <xsd:element name="language" type="docLanguageType" />
-      <xsd:element name="parameterlist" type="docParamListType" />
-      <xsd:element name="xrefsect" type="docXRefSectType" />
-      <xsd:element name="copydoc" type="docCopyType" />
-      <xsd:element name="blockquote" type="docBlockQuoteType" />
-    </xsd:choice>
-  </xsd:group>
-
-  <xsd:complexType name="docParaType" mixed="true">
-    <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docMarkupType" mixed="true">
-    <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docURLLink" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="url" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docAnchorType" mixed="true">
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docFormulaType" mixed="true">
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docIndexEntryType">
-    <xsd:sequence>
-      <xsd:element name="primaryie" type="xsd:string" />
-      <xsd:element name="secondaryie" type="xsd:string" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docListType">
-    <xsd:sequence>
-      <xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docListItemType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docSimpleSectType">
-    <xsd:sequence>
-      <xsd:element name="title" type="docTitleType" minOccurs="0" />
-      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-        <xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
-        <xsd:element name="simplesectsep" type="docEmptyType" minOccurs="0"/>
-      </xsd:sequence>
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxSimpleSectKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docVarListEntryType">
-    <xsd:sequence>
-      <xsd:element name="term" type="docTitleType" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:group name="docVariableListGroup">
-    <xsd:sequence>
-      <xsd:element name="varlistentry" type="docVarListEntryType" />
-      <xsd:element name="listitem" type="docListItemType" />
-    </xsd:sequence>
-  </xsd:group>
-
-  <xsd:complexType name="docVariableListType">
-    <xsd:sequence>
-      <xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docRefTextType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="kindref" type="DoxRefKind" />
-    <xsd:attribute name="external" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docTableType">
-    <xsd:sequence>
-      <xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="caption" type="docCaptionType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="rows" type="xsd:integer" />
-    <xsd:attribute name="cols" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docRowType">
-    <xsd:sequence>
-      <xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docEntryType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="thead" type="DoxBool" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docCaptionType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docHeadingType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
-  </xsd:complexType>
-
-  <xsd:complexType name="docImageType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="type" type="DoxImageKind" /> 
-    <xsd:attribute name="name" type="xsd:string" /> 
-    <xsd:attribute name="width" type="xsd:string" /> 
-    <xsd:attribute name="height" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docDotFileType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="name" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docTocItemType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="id" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docTocListType">
-    <xsd:sequence>
-      <xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docLanguageType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="langid" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamListType">
-    <xsd:sequence>
-      <xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxParamListKind" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamListItem">
-    <xsd:sequence>
-      <xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="parameterdescription" type="descriptionType" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamNameList">
-    <xsd:sequence>
-      <xsd:element name="parametertype" type="docParamType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamName" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
-    </xsd:sequence>
-    <xsd:attribute name="direction" type="DoxParamDir" use="optional" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docXRefSectType">
-    <xsd:sequence>
-      <xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="xrefdescription" type="descriptionType" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docCopyType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="link" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docBlockQuoteType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docCharType">
-    <xsd:attribute name="char" type="DoxCharRange"/> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docEmptyType"/>
-
-  <!-- Simple types -->
-
-  <xsd:simpleType name="DoxBool">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="yes" />
-      <xsd:enumeration value="no" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxGraphRelation">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="include" />
-      <xsd:enumeration value="usage" />
-      <xsd:enumeration value="template-instance" />
-      <xsd:enumeration value="public-inheritance" />
-      <xsd:enumeration value="protected-inheritance" />
-      <xsd:enumeration value="private-inheritance" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxRefKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="compound" />
-      <xsd:enumeration value="member" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxMemberKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="define" />
-      <xsd:enumeration value="property" />
-      <xsd:enumeration value="event" />
-      <xsd:enumeration value="variable" />
-      <xsd:enumeration value="typedef" />
-      <xsd:enumeration value="enum" />
-      <xsd:enumeration value="function" />
-      <xsd:enumeration value="signal" />
-      <xsd:enumeration value="prototype" />
-      <xsd:enumeration value="friend" />
-      <xsd:enumeration value="dcop" />
-      <xsd:enumeration value="slot" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxProtectionKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="public" />
-      <xsd:enumeration value="protected" />
-      <xsd:enumeration value="private" />
-      <xsd:enumeration value="package" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxVirtualKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="non-virtual" />
-      <xsd:enumeration value="virtual" />
-      <xsd:enumeration value="pure-virtual" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxCompoundKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="class" />
-      <xsd:enumeration value="struct" />
-      <xsd:enumeration value="union" />
-      <xsd:enumeration value="interface" />
-      <xsd:enumeration value="protocol" />
-      <xsd:enumeration value="category" />
-      <xsd:enumeration value="exception" />
-      <xsd:enumeration value="file" />
-      <xsd:enumeration value="namespace" />
-      <xsd:enumeration value="group" />
-      <xsd:enumeration value="page" />
-      <xsd:enumeration value="example" />
-      <xsd:enumeration value="dir" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxSectionKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="user-defined" />
-      <xsd:enumeration value="public-type" />
-      <xsd:enumeration value="public-func" />
-      <xsd:enumeration value="public-attrib" />
-      <xsd:enumeration value="public-slot" />
-      <xsd:enumeration value="signal" />
-      <xsd:enumeration value="dcop-func" />
-      <xsd:enumeration value="property" />
-      <xsd:enumeration value="event" />
-      <xsd:enumeration value="public-static-func" />
-      <xsd:enumeration value="public-static-attrib" />
-      <xsd:enumeration value="protected-type" />
-      <xsd:enumeration value="protected-func" />
-      <xsd:enumeration value="protected-attrib" />
-      <xsd:enumeration value="protected-slot" />
-      <xsd:enumeration value="protected-static-func" />
-      <xsd:enumeration value="protected-static-attrib" />
-      <xsd:enumeration value="package-type" />
-      <xsd:enumeration value="package-func" />
-      <xsd:enumeration value="package-attrib" />
-      <xsd:enumeration value="package-static-func" />
-      <xsd:enumeration value="package-static-attrib" />
-      <xsd:enumeration value="private-type" />
-      <xsd:enumeration value="private-func" />
-      <xsd:enumeration value="private-attrib" />
-      <xsd:enumeration value="private-slot" />
-      <xsd:enumeration value="private-static-func" />
-      <xsd:enumeration value="private-static-attrib" />
-      <xsd:enumeration value="friend" />
-      <xsd:enumeration value="related" />
-      <xsd:enumeration value="define" />
-      <xsd:enumeration value="prototype" />
-      <xsd:enumeration value="typedef" />
-      <xsd:enumeration value="enum" />
-      <xsd:enumeration value="func" />
-      <xsd:enumeration value="var" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxHighlightClass">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="comment" />
-      <xsd:enumeration value="normal" />
-      <xsd:enumeration value="preprocessor" />
-      <xsd:enumeration value="keyword" />
-      <xsd:enumeration value="keywordtype" />
-      <xsd:enumeration value="keywordflow" />
-      <xsd:enumeration value="stringliteral" />
-      <xsd:enumeration value="charliteral" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxSimpleSectKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="see" />
-      <xsd:enumeration value="return" />
-      <xsd:enumeration value="author" />
-      <xsd:enumeration value="authors" />
-      <xsd:enumeration value="version" />
-      <xsd:enumeration value="since" />
-      <xsd:enumeration value="date" />
-      <xsd:enumeration value="note" />
-      <xsd:enumeration value="warning" />
-      <xsd:enumeration value="pre" />
-      <xsd:enumeration value="post" />
-      <xsd:enumeration value="copyright" />
-      <xsd:enumeration value="invariant" />
-      <xsd:enumeration value="remark" />
-      <xsd:enumeration value="attention" />
-      <xsd:enumeration value="par" />
-      <xsd:enumeration value="rcs" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxVersionNumber">
-    <xsd:restriction base="xsd:string">
-      <xsd:pattern value="\d+\.\d+.*" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxImageKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="html" />
-      <xsd:enumeration value="latex" />
-      <xsd:enumeration value="rtf" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxParamListKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="param" />
-      <xsd:enumeration value="retval" />
-      <xsd:enumeration value="exception" />
-      <xsd:enumeration value="templateparam" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxCharRange">
-    <xsd:restriction base="xsd:string">
-      <xsd:pattern value="[aeiouncAEIOUNC]" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxParamDir">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="in"/>
-      <xsd:enumeration value="out"/>
-      <xsd:enumeration value="inout"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxAccessor">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="retain"/>
-      <xsd:enumeration value="copy"/>
-      <xsd:enumeration value="assign"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-</xsd:schema>
-

+ 0 - 3
gameplay-luagen/gameplay-api/xml/index.xml

@@ -1,3 +0,0 @@
-<?xml version='1.0' encoding='UTF-8' standalone='no'?>
-<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.8.1">
-</doxygenindex>

+ 0 - 66
gameplay-luagen/gameplay-api/xml/index.xsd

@@ -1,66 +0,0 @@
-<?xml version='1.0' encoding='utf-8' ?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-  <xsd:element name="doxygenindex" type="DoxygenType"/>
-
-  <xsd:complexType name="DoxygenType">
-    <xsd:sequence>
-      <xsd:element name="compound" type="CompoundType" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="version" type="xsd:string" use="required"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="CompoundType">
-    <xsd:sequence>
-      <xsd:element name="name" type="xsd:string"/>
-      <xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" use="required"/>
-    <xsd:attribute name="kind" type="CompoundKind" use="required"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="MemberType">
-    <xsd:sequence>
-      <xsd:element name="name" type="xsd:string"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" use="required"/>
-    <xsd:attribute name="kind" type="MemberKind" use="required"/>
-  </xsd:complexType>
-  
-  <xsd:simpleType name="CompoundKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="class"/>
-      <xsd:enumeration value="struct"/>
-      <xsd:enumeration value="union"/>
-      <xsd:enumeration value="interface"/>
-      <xsd:enumeration value="protocol"/>
-      <xsd:enumeration value="category"/>
-      <xsd:enumeration value="exception"/>
-      <xsd:enumeration value="file"/>
-      <xsd:enumeration value="namespace"/>
-      <xsd:enumeration value="group"/>
-      <xsd:enumeration value="page"/>
-      <xsd:enumeration value="example"/>
-      <xsd:enumeration value="dir"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="MemberKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="define"/>
-      <xsd:enumeration value="property"/>
-      <xsd:enumeration value="event"/>
-      <xsd:enumeration value="variable"/>
-      <xsd:enumeration value="typedef"/>
-      <xsd:enumeration value="enum"/>
-      <xsd:enumeration value="enumvalue"/>
-      <xsd:enumeration value="function"/>
-      <xsd:enumeration value="signal"/>
-      <xsd:enumeration value="prototype"/>
-      <xsd:enumeration value="friend"/>
-      <xsd:enumeration value="dcop"/>
-      <xsd:enumeration value="slot"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-</xsd:schema>
-

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

@@ -126,10 +126,10 @@
       </Message>
     </CustomBuildStep>
     <PostBuildEvent>
-      <Command>copy $(TargetPath) $(ProjectDir)..\bin\win32\$(TargetFileName)</Command>
+      <Command>copy $(TargetPath) $(ProjectDir)..\bin\windows\$(TargetFileName)</Command>
     </PostBuildEvent>
     <PostBuildEvent>
-      <Message>Copying executable to bin/win32 folder ...</Message>
+      <Message>Copying executable to bin/windows folder ...</Message>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 2 - 1
gameplay-luagen/src/main.cpp

@@ -65,7 +65,8 @@ int main(int argc, char** argv)
     // Ensure the user is calling the program correctly.
     if (argc < 2 || argc > 4)
     {
-        GP_ERROR("Usage: gameplay-luagen <doxygen-xml-input-directory> [output-directory] [binding-namespace]");
+        printf("Usage: gameplay-luagen <doxygen-xml-input-directory> [output-directory] [binding-namespace]\n");
+        exit(0);
     }
 
     // Generate the bindings.

+ 2 - 8
gameplay-newproject.sh

@@ -16,10 +16,10 @@
 #Find out which OS we're on. 
 unamestr=$(uname)
 
-#Switch-on alias expansion within the script (see http://chiefsandendians.blogspot.co.uk/2010/07/linux-scripts-and-alias.html)
+# Switch-on alias expansion within the script 
 shopt -s expand_aliases
 
-#alias the sed in-place command for OSX and Linux - incompatibilities between BSD and Linux sed args
+#Alias the sed in-place command for OSX and Linux - incompatibilities between BSD and Linux sed args
 if [[ "$unamestr" == "Darwin" ]]; then
 	alias aliassedinplace='sed -i ""'
 else
@@ -43,7 +43,6 @@ if [[ "$projName" == "" ]]; then
 	exit -1;
 fi
 echo 
-
 echo
 echo "2. Enter a game title."
 echo
@@ -117,7 +116,6 @@ if [[ "$className" == "" ]]; then
 fi
 echo 
 
-
 echo
 echo "7. Enter the project path."
 echo
@@ -171,7 +169,6 @@ if [[ ${gpPathAbs} == ${common_path} ]]; then
 	gpPath=${back}
 fi
 
-
 #############################################
 # Copy Microsoft Visual Studio project files
 #############################################
@@ -239,13 +236,11 @@ cp "gameplay-template/android/template.build.xml" "$projPath/android/build.xml"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/build.xml"
 
 cp "gameplay-template/android/jni/Application.mk" "$projPath/android/jni/Application.mk"
-
 cp "gameplay-template/android/jni/template.Android.mk" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/jni/Android.mk"
 
-
 cp "gameplay-template/icon.png" "$projPath/android/res/drawable/icon.png"
 cp "gameplay-template/android/res/values/template.strings.xml" "$projPath/android/res/values/strings.xml"
 aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/android/res/values/strings.xml"
@@ -259,7 +254,6 @@ aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/CMakeLists.txt"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/CMakeLists.txt"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/CMakeLists.txt"
 
-
 #############################################
 # Copy source files
 #############################################

+ 6 - 12
gameplay-template/template.bar-descriptor.xml

@@ -24,20 +24,14 @@
          <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
     <buildId>1</buildId>
 
-    <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. -->
-    <!-- <versionLabel></versionLabel> -->
-
     <!-- Description, displayed in the BlackBerry Tablet OS application installer.
          May have multiple values for each language. See samples or xsd schema file. Optional. -->
     <description>TEMPLATE_DESCRIPTION</description>
-    
-    <!-- Copyright information. Optional. -->
-    <!-- <copyright></copyright> -->
 
-    <!--  Name of author which is used for signing. Must match the developer name of your development certificate. -->
+    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
     <author>TEMPLATE_AUTHOR</author>
 
-    <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
+    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
     <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
 
     <initialWindow>
@@ -47,7 +41,7 @@
         <transparent>false</transparent>
     </initialWindow>
 
-    <!--  The category where the application appears. Either core.games or core.media. -->
+    <!-- The category where the application appears. Either core.games or core.media. -->
     <category>core.games</category>
 
     <asset path="icon.png">icon.png</asset>
@@ -82,18 +76,18 @@
        <asset path="Simulator-Coverage/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
     </configuration>
 
-    <!--  The icon for the application, which should be 86x86. -->
+    <!-- The icon for the application, which should be 150x150. -->
     <icon>
         <image>icon.png</image>
     </icon>
 
-    <!--  The splash screen that will appear when your application is launching. Should be 1024x600. -->
+    <!-- The splash screen that will appear when your application is launching. Should be 1280x768. -->
     <!-- <splashscreen></splashscreen> -->
 
     <!-- Request permission to execute native code.  Required for native applications. -->
     <action system="true">run_native</action>
 
-    <!--  The permissions requested by your application. -->
+    <!-- The permissions requested by your application. -->
     <!--  <action>access_shared</action> -->
     <!--  <action>record_audio</action> -->
     <!--  <action>read_geolocation</action> -->

+ 12 - 3
gameplay/.cproject

@@ -23,8 +23,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.311918799" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1481323494" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="__BB10__"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.2133604142" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/lua/include&quot;"/>
@@ -43,7 +43,7 @@
 							</tool>
 							<tool id="com.qnx.qcc.tool.assembler.1988140188" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
 								<option id="com.qnx.qcc.option.assembler.debug.1929307156" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.assembler.defines.1866459653" name="Defines (-D)" superClass="com.qnx.qcc.option.assembler.defines" valueType="definedSymbols"/>
+								<option id="com.qnx.qcc.option.assembler.defines.1866459653" name="Defines (-D)" superClass="com.qnx.qcc.option.assembler.defines"/>
 								<inputType id="com.qnx.qcc.inputType.assembler.1944074393" superClass="com.qnx.qcc.inputType.assembler"/>
 							</tool>
 							<tool id="com.qnx.qcc.tool.linker.85592747" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
@@ -88,6 +88,7 @@
 								<option id="com.qnx.qcc.option.compiler.defines.398688299" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1670164593" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -148,7 +149,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.1649809766" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.276653249" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="BY_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1503059677" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -213,6 +215,7 @@
 								<option id="com.qnx.qcc.option.compiler.defines.374283024" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1769677874" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -274,6 +277,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.1671403331" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1863269886" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.847642559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -333,6 +338,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.1329750381" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1679396285" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.513622172" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -393,6 +400,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.1296061040" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1925901823" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
+									<listOptionValue builtIn="false" value="BLACKBERRY_USE_GAMEPAD"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1685994750" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>

+ 1 - 1
gameplay/android/jni/Android.mk

@@ -170,7 +170,7 @@ LOCAL_SRC_FILES := \
     lua/lua_Game.cpp \
     lua/lua_GameClearFlags.cpp \
     lua/lua_Gamepad.cpp \
-    lua/lua_GamepadButtonState.cpp \
+    lua/lua_GamepadButtonMapping.cpp \
     lua/lua_GamepadGamepadEvent.cpp \
     lua/lua_GameState.cpp \
     lua/lua_Gesture.cpp \

+ 2 - 1
gameplay/res/shaders/terrain.frag

@@ -47,7 +47,8 @@ void main()
 #if (LAYER_COUNT > 0)
     // Set base diffuse color
     vec2 uvCoord = mod(v_texCoord0 * TEXTURE_REPEAT_0, vec2(1,1));
-	_baseColor = texture2D(u_samplers[TEXTURE_INDEX_0], uvCoord);
+	_baseColor.rgb = texture2D(u_samplers[TEXTURE_INDEX_0], uvCoord).rgb;
+    _baseColor.a = 1.0;
 #else
     // If no layers are defined, simple use a white color
     _baseColor = vec4(1,1,1,1);

+ 11 - 1
gameplay/src/Button.h

@@ -77,7 +77,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
+     * @param contactIndex An integer to identify this contact point within the currently active touch set.
      *
      * @return Whether the touch event was consumed by the control.
      *
@@ -90,8 +90,18 @@ protected:
      */
     const char* getType() const;
 
+    /**
+     * Gets the data binding index for this control.
+     *
+     * @return The data binding index for control. 
+     */
     const unsigned int getDataBinding() const;
 
+    /**
+     * Sets the data binding provider for this control.
+     *
+     * @param dataBinding The data binding index for control. 
+     */
     void setDataBinding(unsigned int dataBinding);
 
 private:

+ 1 - 1
gameplay/src/CheckBox.h

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

+ 2 - 2
gameplay/src/Container.h

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

+ 1 - 1
gameplay/src/Control.h

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

+ 2 - 2
gameplay/src/DebugNew.cpp

@@ -106,7 +106,7 @@ void* debugAlloc(std::size_t size, const char* file, int line)
     mem += sizeof(MemoryAllocationRecord);
 
     rec->address = (unsigned long)mem;
-    rec->size = size;
+    rec->size = (unsigned int)size;
     rec->file = file;
     rec->line = line;
     rec->next = __memoryAllocations;
@@ -114,7 +114,7 @@ void* debugAlloc(std::size_t size, const char* file, int line)
 
     // Capture the stack frame (up to MAX_STACK_FRAMES) if we 
     // are running on Windows and the user has enabled it.
-#if defined(WIN32)
+#if defined(WIN32) && defined(_M_IX86)
     rec->trackStackTrace = __trackStackTrace;
     if (rec->trackStackTrace)
     {

+ 1 - 1
gameplay/src/Game.h

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

+ 2 - 0
gameplay/src/Gamepad.cpp

@@ -75,6 +75,7 @@ void Gamepad::remove(GamepadHandle handle)
         if (gamepad->_handle == handle)
         {
             Game::getInstance()->gamepadEvent(DISCONNECTED_EVENT, gamepad);
+            SAFE_DELETE(gamepad);
             it = __gamepads.erase(it);
         }
         else
@@ -93,6 +94,7 @@ void Gamepad::remove(Gamepad* gamepad)
         if (g == gamepad)
         {
             Game::getInstance()->gamepadEvent(DISCONNECTED_EVENT, g);
+            SAFE_DELETE(gamepad);
             it = __gamepads.erase(it);
         }
         else

+ 14 - 16
gameplay/src/HeightField.cpp

@@ -35,20 +35,20 @@ float normalizedHeightPacked(float r, float g, float b)
     return (256.0f*r + g + 0.00390625f*b) / 65536.0f;
 }
 
-HeightField* HeightField::createFromImage(const char* path, float minHeight, float maxHeight)
+HeightField* HeightField::createFromImage(const char* path, float heightMin, float heightMax)
 {
-    return create(path, 0, 0, minHeight, maxHeight);
+    return create(path, 0, 0, heightMin, heightMax);
 }
 
-HeightField* HeightField::createFromRAW(const char* path, unsigned int width, unsigned int height, float minHeight, float maxHeight)
+HeightField* HeightField::createFromRAW(const char* path, unsigned int width, unsigned int height, float heightMin, float heightMax)
 {
-    return create(path, width, height, minHeight, maxHeight);
+    return create(path, width, height, heightMin, heightMax);
 }
 
-HeightField* HeightField::create(const char* path, unsigned int width, unsigned int height, float minHeight, float maxHeight)
+HeightField* HeightField::create(const char* path, unsigned int width, unsigned int height, float heightMin, float heightMax)
 {
     GP_ASSERT(path);
-    GP_ASSERT(maxHeight >= minHeight);
+    GP_ASSERT(heightMax >= heightMin);
 
     // Validate input parameters
     size_t pathLength = strlen(path);
@@ -58,7 +58,7 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
         return NULL;
     }
 
-    float heightScale = maxHeight - minHeight;
+    float heightScale = heightMax - heightMin;
 
     HeightField* heightfield = NULL;
 
@@ -96,7 +96,7 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
             for (unsigned int x = 0, w = image->getWidth(); x < w; ++x)
             {
                 idx = (y*w + x) * pixelSize;
-                heights[i++] = minHeight + normalizedHeightPacked(data[idx], data[idx + 1], data[idx + 2]) * heightScale;
+                heights[i++] = heightMin + normalizedHeightPacked(data[idx], data[idx + 1], data[idx + 2]) * heightScale;
             }
         }
 
@@ -105,9 +105,9 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
     else if (ext[0] == '.' && toupper(ext[1]) == 'R' && toupper(ext[2]) == 'A' && toupper(ext[3]) == 'W')
     {
         // RAW image (headerless)
-        if (width < 2 || height < 2 || maxHeight < 0)
+        if (width < 2 || height < 2 || heightMax < 0)
         {
-            GP_WARN("Invalid 'width', 'height' or 'maxHeight' parameter for RAW heightfield image: %s.", path);
+            GP_WARN("Invalid 'width', 'height' or 'heightMax' parameter for RAW heightfield image: %s.", path);
             return NULL;
         }
 
@@ -132,29 +132,27 @@ HeightField* HeightField::create(const char* path, unsigned int width, unsigned
         heightfield = HeightField::create(width, height);
         float* heights = heightfield->getArray();
 
-        // RAW files have an origin of bottom left, whereas our height array needs an origin of
-        // top left, so we need to flip the Y as we write height values out.
         if (bits == 16)
         {
             // 16-bit (0-65535)
             int idx;
-            for (int y = height-1, i = 0; y >= 0; --y)
+            for (unsigned int y = 0, i = 0; y < height; ++y)
             {
                 for (unsigned int x = 0; x < width; ++x, ++i)
                 {
                     idx = (y * width + x) << 1;
-                    heights[i] = minHeight + ((bytes[idx] | (int)bytes[idx+1] << 8) / 65535.0f) * heightScale;
+                    heights[i] = heightMin + ((bytes[idx] | (int)bytes[idx+1] << 8) / 65535.0f) * heightScale;
                 }
             }
         }
         else
         {
             // 8-bit (0-255)
-            for (int y = height-1, i = 0; y >= 0; --y)
+            for (unsigned int y = 0, i = 0; y < height; ++y)
             {
                 for (unsigned int x = 0; x < width; ++x, ++i)
                 {
-                    heights[i] = minHeight + (bytes[y * width + x] / 255.0f) * heightScale;
+                    heights[i] = heightMin + (bytes[y * width + x] / 255.0f) * heightScale;
                 }
             }
         }

+ 7 - 9
gameplay/src/HeightField.h

@@ -38,14 +38,12 @@ namespace gameplay
          * pixel, while maxHeight maxHeight is mapped to full intensity pixels.
          *
          * @param path Path to a heightfield image.
-         * @param width Width of the image (required for headerless/RAW files, can be zero for other image formats).
-         * @param height Height of the image (required for headerless/RAW files, can be zero for other image formats).
-         * @param minHeight Minimum height value for a zero intensity pixel.
-         * @param maxHeight Maximum height value for a full intensity heightfield pixel (must be >= minHeight).
+         * @param heightMin Minimum height value for a zero intensity pixel.
+         * @param heightMax Maximum height value for a full intensity heightfield pixel (must be >= minHeight).
          * 
          * @return The new HeightField.
          */
-        static HeightField* createFromImage(const char* path, float minHeight = 0, float maxHeight = 1);
+        static HeightField* createFromImage(const char* path, float heightMin = 0, float heightMax = 1);
 
         /**
          * Creates a HeightField from the specified RAW8 or RAW16 file.
@@ -67,12 +65,12 @@ namespace gameplay
          * @param path Path to the RAW file.
          * @param width Width of the RAW data.
          * @param height Height of the RAW data.
-         * @param minHeight Minimum height value for a zero intensity pixel.
-         * @param maxHeight Maximum height value for a full intensity heightfield pixel (must be >= minHeight).
+         * @param heightMin Minimum height value for a zero intensity pixel.
+         * @param heightMax Maximum height value for a full intensity heightfield pixel (must be >= minHeight).
          * 
          * @return The new HeightField.
          */
-        static HeightField* createFromRAW(const char* path, unsigned int width, unsigned int height, float minHeight = 0, float maxHeight = 1);
+        static HeightField* createFromRAW(const char* path, unsigned int width, unsigned int height, float heightMin = 0, float heightMax = 1);
 
         /**
          * Returns a pointer to the underying height array.
@@ -130,7 +128,7 @@ namespace gameplay
         /**
          * Internal method for creating a HeightField.
          */
-        static HeightField* create(const char* path, unsigned int width, unsigned int height, float minHeight, float maxHeight);
+        static HeightField* create(const char* path, unsigned int width, unsigned int height, float heightMin, float heightMax);
 
         float* _array;
         unsigned int _cols;

+ 6 - 1
gameplay/src/Joystick.h

@@ -113,6 +113,11 @@ public:
      */
     const char* getType() const;
 
+    /**
+     * Gets the index of this joystick across all joysticks on a form.
+     *
+     * @return The index of this joystick on a form.
+     */
     inline const unsigned int getIndex() const;
 
 protected:
@@ -148,7 +153,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
+     * @param contactIndex An integer to identify this contact point within the currently active touch set.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 1 - 1
gameplay/src/Layout.h

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

+ 4 - 5
gameplay/src/Matrix.h

@@ -213,7 +213,7 @@ public:
     static void createOrthographicOffCenter(float left, float right, float bottom, float top,
                                             float zNearPlane, float zFarPlane, Matrix* dst);
 
-    /*
+    /**
      * Creates a spherical billboard that rotates around a specified object position.
      *
      * This method computes the facing direction of the billboard from the object position
@@ -230,7 +230,7 @@ public:
     static void createBillboard(const Vector3& objectPosition, const Vector3& cameraPosition,
                                 const Vector3& cameraUpVector, Matrix* dst);
 
-    /*
+    /**
      * Creates a spherical billboard that rotates around a specified object position with
      * provision for a safe default orientation.
      *
@@ -243,15 +243,14 @@ public:
      * @param objectPosition The position of the object the billboard will rotate around.
      * @param cameraPosition The position of the camera.
      * @param cameraUpVector The up vector of the camera.
-     * @param cameraForwardVector The forward vector of the camera, used if the positions
-     *                            are too close.
+     * @param cameraForwardVector The forward vector of the camera, used if the positions are too close.
      * @param dst A matrix to store the result in.
      */
     static void createBillboard(const Vector3& objectPosition, const Vector3& cameraPosition,
                                 const Vector3& cameraUpVector, const Vector3& cameraForwardVector,
                                 Matrix* dst);
 
-    /*
+    /**
      * Fills in an existing Matrix so that it reflects the coordinate system about a specified Plane.
      *
      * @param plane The Plane about which to create a reflection.

+ 6 - 1
gameplay/src/Platform.h

@@ -222,6 +222,11 @@ public:
      */
     static bool isGestureRegistered(Gesture::GestureEvent evt);
 
+    /**
+     * Polls the platform for the updated Gamepad states such as joysticks, buttons and trigger values.
+     *
+     * @param gamepad The gamepad to be returned with the latest polled values populated.
+     */
     static void pollGamepadState(Gamepad* gamepad);
 
     /**
@@ -230,7 +235,7 @@ public:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
+     * @param contactIndex An integer to identify this contact point within the currently active touch set.
      *
      * @see Touch::TouchEvent
      */

+ 13 - 13
gameplay/src/PlatformBlackBerry.cpp

@@ -491,19 +491,7 @@ void gesture_callback(gesture_base_t* gesture, mtouch_event_t* event, void* para
     }
 }
 
-#ifdef __BB10__
-
-static const int __VIDs[] = {
-    0x1038,
-    0x057e,
-    0x25b6
-};
-
-static const int __PIDs[] = {
-    0x1412,
-    0x0306,
-    0x0001
-};
+#ifdef BLACKBERRY_USE_GAMEPAD
 
 static const char* __vendorStrings[] =
 {
@@ -519,6 +507,18 @@ static const char* __productStrings[] =
     "Gametel"
 };
 
+static const int __VIDs[] = {
+    0x1038,
+    0x057e,
+    0x25b6
+};
+
+static const int __PIDs[] = {
+    0x1412,
+    0x0306,
+    0x0001
+};
+
 static const unsigned int __knownGamepads = 3;
 
 void loadGamepad(GamepadHandle handle, int* buttonCount, int* joystickCount, int* productId, int* vendorId, char* id, char* productString, char* vendorString)

+ 1 - 1
gameplay/src/PlatformMacOSX.mm

@@ -882,7 +882,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
 - (void) mouseDragged: (NSEvent*) event
 {
     NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
-    if (__leftMouseDown)
+    if (__leftMouseDown && !__mouseCaptured)
     {
         [self mouse: Mouse::MOUSE_MOVE orTouchEvent: Touch::TOUCH_MOVE x: point.x y: __height - point.y s: 0];
     }

+ 1 - 1
gameplay/src/RadioButton.h

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

+ 1 - 1
gameplay/src/ScriptController.h

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

+ 30 - 30
gameplay/src/Slider.cpp

@@ -93,6 +93,36 @@ void Slider::setValue(float value)
     _value = MATH_CLAMP(value, _min, _max);
 }
 
+void Slider::setValueTextVisible(bool valueTextVisible)
+{
+    _valueTextVisible = valueTextVisible;
+}
+
+bool Slider::isValueTextVisible() const
+{
+    return _valueTextVisible;
+}
+
+void Slider::setValueTextAlignment(Font::Justify alignment)
+{
+    _valueTextAlignment = alignment;
+}
+
+Font::Justify Slider::getValueTextAlignment() const
+{
+    return _valueTextAlignment;
+}
+
+void Slider::setValueTextPrecision(unsigned int precision)
+{
+    _valueTextPrecision = precision;
+}
+
+unsigned int Slider::getValueTextPrecision() const
+{
+    return _valueTextPrecision;
+}
+
 void Slider::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Listener::TEXT_CHANGED) == Listener::TEXT_CHANGED)
@@ -334,34 +364,4 @@ const char* Slider::getType() const
     return "slider";
 }
 
-void Slider::setValueTextVisible(bool valueTextVisible)
-{
-    _valueTextVisible = valueTextVisible;
-}
-
-bool Slider::getValueTextVisible() const
-{
-    return _valueTextVisible;
-}
-
-void Slider::setValueTextAlignment(Font::Justify alignment)
-{
-    _valueTextAlignment = alignment;
-}
-
-Font::Justify Slider::getValueTextAlignment() const
-{
-    return _valueTextAlignment;
-}
-
-void Slider::setValueTextPrecision(unsigned int precision)
-{
-    _valueTextPrecision = precision;
-}
-
-unsigned int Slider::getValueTextPrecision() const
-{
-    return _valueTextPrecision;
-}
-
 }

+ 33 - 3
gameplay/src/Slider.h

@@ -110,16 +110,46 @@ public:
      */
     const char* getType() const;
 
-    void setValueTextVisible(bool displayValue);
+    /**
+     * Sets if the slider value text is rendered below the control.
+     * 
+     * @param visible If the slider value text is rendered below the control. 
+     */
+    void setValueTextVisible(bool visible);
 
-    bool getValueTextVisible() const;
+    /**
+     * Gets if the slider value text is rendered below the control.
+     *
+     * @return true if the slider value text is rendered below the control, false if otherwise.
+     */
+    bool isValueTextVisible() const;
 
+    /**
+     * Sets the slider value text alignment.
+     * 
+     * @param alignment the slider value text alignment. 
+     */
     void setValueTextAlignment(Font::Justify alignment);
 
+    /**
+     * Gets the slider value text alignment.
+     *
+     * @return The slider value text alignment. 
+     */
     Font::Justify getValueTextAlignment() const;
 
+    /**
+     * Sets the precision, which is the number floating point digits after the decimal.
+     *
+     * @param precision The number floating point precision/digits after the decimal.
+     */
     void setValueTextPrecision(unsigned int precision);
 
+    /**
+     * Gets the precision, which is the number floating point digits after the decimal.
+     *
+     * @return The number floating point precision/digits after the decimal.
+     */
     unsigned int getValueTextPrecision() const;
 
     /**
@@ -162,7 +192,7 @@ protected:
      * @param evt The touch event that occurred.
      * @param x The x position of the touch in pixels. Left edge is zero.
      * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
+     * @param contactIndex An integer to identify this contact point within the currently active touch set.
      *
      * @return Whether the touch event was consumed by the control.
      *

+ 2 - 2
gameplay/src/Terrain.cpp

@@ -15,7 +15,7 @@ namespace gameplay
 // specified terrain size, expressed as a ratio of the average
 // of the dimensions of the terrain heightfield:
 //
-//   maxHeight = (image.width + image.height) / 2 * DEFAULT_TERRAIN_HEIGHT_RATIO
+//   heightMax = (image.width + image.height) / 2 * DEFAULT_TERRAIN_HEIGHT_RATIO
 //
 #define DEFAULT_TERRAIN_HEIGHT_RATIO 0.3f
 
@@ -30,7 +30,7 @@ namespace gameplay
 float getDefaultHeight(unsigned int width, unsigned int height);
 
 Terrain::Terrain() :
-    _heightfield(NULL), _node(NULL), _normalMap(NULL), _flags(ENABLE_FRUSTUM_CULLING | ENABLE_LEVEL_OF_DETAIL),
+    _heightfield(NULL), _node(NULL), _normalMap(NULL), _flags(FRUSTUM_CULLING | LEVEL_OF_DETAIL),
     _dirtyFlags(TERRAIN_DIRTY_WORLD_MATRIX | TERRAIN_DIRTY_INV_WORLD_MATRIX | TERRAIN_DIRTY_NORMAL_MATRIX)
 {
 }

+ 8 - 11
gameplay/src/Terrain.h

@@ -98,7 +98,7 @@ public:
          * Frustum culling uses the scene's active camera. The terrain must be attached
          * to a node that is within a scene for this to work.
          */
-        ENABLE_FRUSTUM_CULLING = 2,
+        FRUSTUM_CULLING = 2,
 
          /**
           * Enables level of detail (on by default).
@@ -107,7 +107,7 @@ public:
           * "detailLevels" was not set to a value greater than 1 in the terrain
           * properties file at creation time.
           */
-         ENABLE_LEVEL_OF_DETAIL = 8
+         LEVEL_OF_DETAIL = 8
     };
 
     /**
@@ -149,7 +149,7 @@ public:
      *      physics hegihtfield is scaled by this amount. Pass Vector3::one() to use the exact dimensions and heights
      *      in the supplied height array.
      * @param patchSize Size of terrain patches (number of quads).
-     * @param detailLevel Number of detail levels to generate for the terrain (a value of one generates only the base
+     * @param detailLevels Number of detail levels to generate for the terrain (a value of one generates only the base
      *      level, resulting in no LOD at runtime.
      * @param skirtScale A positive value indicates that vertical skirts should be generated at the specified
      *      scale, which is relative to the height of the terrain. For example, a value of 0.5f indicates that
@@ -160,10 +160,8 @@ public:
      * @return A new Terrain.
      * @script{create}
      */
-    static Terrain* create(HeightField* heightfield,
-        const Vector3& scale = Vector3::one(), unsigned int patchSize = 32,
-        unsigned int detailLevels = 1, float skirtScale = 0.0f,
-        const char* normalMapPath = NULL);
+    static Terrain* create(HeightField* heightfield, const Vector3& scale = Vector3::one(), unsigned int patchSize = 32,  
+                           unsigned int detailLevels = 1, float skirtScale = 0.0f, const char* normalMapPath = NULL);
 
     /**
      * Sets the detail textures information for a terrain layer.
@@ -202,9 +200,9 @@ public:
      * @script{ignore}
      */
     bool setLayer(int index,
-        const char* texturePath, const Vector2& textureRepeat = Vector2::one(),
-        const char* blendPath = NULL, int blendChannel = 0,
-        int row = -1, int column = -1);
+                  const char* texturePath, const Vector2& textureRepeat = Vector2::one(),
+                  const char* blendPath = NULL, int blendChannel = 0, 
+                  int row = -1, int column = -1);
 
     /**
      * Returns the node that this terrain is bound to.
@@ -367,7 +365,6 @@ private:
     mutable Matrix _normalMatrix;
     mutable unsigned int _dirtyFlags;
     BoundingBox _boundingBox;
-
 };
 
 }

+ 671 - 673
gameplay/src/TerrainPatch.cpp

@@ -1,674 +1,672 @@
-#include "Base.h"
-#include "TerrainPatch.h"
-#include "Terrain.h"
-#include "MeshPart.h"
-#include "Scene.h"
-#include "Game.h"
-
-// Default terrain shaders
+#include "Base.h"
+#include "TerrainPatch.h"
+#include "Terrain.h"
+#include "MeshPart.h"
+#include "Scene.h"
+#include "Game.h"
+
+// Default terrain shaders
 #define TERRAIN_VSH "res/shaders/terrain.vert"
-#define TERRAIN_FSH "res/shaders/terrain.frag"
-
-namespace gameplay
-{
-
-/**
- * @script{ignore}
- */
-float calculateHeight(float* heights, unsigned int width, unsigned int height, unsigned int x, unsigned int z);
-
-/**
- * @script{ignore}
- */
-template <class T> T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); }
-
-TerrainPatch::TerrainPatch() :
-    _terrain(NULL), _row(0), _column(0), _materialDirty(true)
-{
-}
-
-TerrainPatch::~TerrainPatch()
-{
-    for (size_t i = 0, count = _levels.size(); i < count; ++i)
-    {
-        Level* level = _levels[i];
-
-        SAFE_RELEASE(level->model);
-        SAFE_DELETE(level);
-    }
-
-    while (_layers.size() > 0)
-    {
-        deleteLayer(*_layers.begin());
-    }
-}
-
-TerrainPatch* TerrainPatch::create(Terrain* terrain,
-    unsigned int row, unsigned int column,
-    float* heights, unsigned int width, unsigned int height,
-    unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
-    float xOffset, float zOffset,
-    unsigned int maxStep, float verticalSkirtSize)
-{
-    // Create patch
-    TerrainPatch* patch = new TerrainPatch();
-    patch->_terrain = terrain;
-    patch->_row = row;
-    patch->_column = column;
-
-    // Add patch lods
-    for (unsigned int step = 1; step <= maxStep; step *= 2)
-    {
-        patch->addLOD(heights, width, height, x1, z1, x2, z2, xOffset, zOffset, step, verticalSkirtSize);
-    }
-
-    // Set our bounding box using the base LOD mesh
-    BoundingBox& bounds = patch->_boundingBox;
-    bounds.set(patch->_levels[0]->model->getMesh()->getBoundingBox());
-
-    // Apply the terrain's local scale to our bounds
-    const Vector3& localScale = terrain->_localScale;
-    if (!localScale.isOne())
-    {
-        bounds.min.set(bounds.min.x * localScale.x, bounds.min.y * localScale.y, bounds.min.z * localScale.z);
-        bounds.max.set(bounds.max.x * localScale.x, bounds.max.y * localScale.y, bounds.max.z * localScale.z);
-    }
-
-    return patch;
-}
-
-void TerrainPatch::addLOD(float* heights, unsigned int width, unsigned int height,
-    unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
-    float xOffset, float zOffset,
-    unsigned int step, float verticalSkirtSize)
-{
-    // Allocate vertex data for this patch
-    unsigned int patchWidth;
-    unsigned int patchHeight;
-    if (step == 1)
-    {
-        patchWidth = (x2 - x1) + 1;
-        patchHeight = (z2 - z1) + 1;
-    }
-    else
-    {
-        patchWidth = (x2 - x1) / step + ((x2 - x1) %step == 0 ? 0 : 1) + 1;
-        patchHeight = (z2 - z1) / step + ((z2 - z1) % step == 0 ? 0 : 1) + 1;
-    }
-
-    if (patchWidth < 2 || patchHeight < 2)
-        return; // ignore this level, not enough geometry
-
-    if (verticalSkirtSize > 0.0f)
-    {
-        patchWidth += 2;
-        patchHeight += 2;
-    }
-
-    unsigned int vertexCount = patchHeight * patchWidth;
-    unsigned int vertexElements = _terrain->_normalMap ? 5 : 8; //<x,y,z>[i,j,k]<u,v>
-    float* vertices = new float[vertexCount * vertexElements];
-    unsigned int index = 0;
-    Vector3 min(FLT_MAX, FLT_MAX, FLT_MAX);
-    Vector3 max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-    bool zskirt = verticalSkirtSize > 0 ? true : false;
-    for (unsigned int z = z1; ; )
-    {
-        bool xskirt = verticalSkirtSize > 0 ? true : false;
-        for (unsigned int x = x1; ; )
-        {
-            GP_ASSERT(index < vertexCount);
-
-            float* v = vertices + (index * vertexElements);
-            index++;
-
-            // Compute position
-            v[0] = x + xOffset;
-            v[1] = calculateHeight(heights, width, height, x, z);
-            if (xskirt || zskirt)
-                v[1] -= verticalSkirtSize;
-            v[2] = z + zOffset;
-
-            // Update bounding box min/max (don't include vertical skirt vertices in bounding box)
-            if (!(xskirt || zskirt))
-            {
-                if (v[0] < min.x)
-                    min.x = v[0];
-                if (v[1] < min.y)
-                    min.y = v[1];
-                if (v[2] < min.z)
-                    min.z = v[2];
-                if (v[0] > max.x)
-                    max.x = v[0];
-                if (v[1] > max.y)
-                    max.y = v[1];
-                if (v[2] > max.z)
-                    max.z = v[2];
-            }
-            v += 3;
-
-            // Compute normal
-            if (!_terrain->_normalMap)
-            {
-                Vector3 p(x, calculateHeight(heights, width, height, x, z), z);
-                Vector3 w(Vector3(x>=step ? x-step : x, calculateHeight(heights, width, height, x>=step ? x-step : x, z), z), p);
-                Vector3 e(Vector3(x<width-step ? x+step : x, calculateHeight(heights, width, height, x<width-step ? x+step : x, z), z), p);
-                Vector3 s(Vector3(x, calculateHeight(heights, width, height, x, z>=step ? z-step : z), z>=step ? z-step : z), p);
-                Vector3 n(Vector3(x, calculateHeight(heights, width, height, x, z<height-step ? z+step : z), z<height-step ? z+step : z), p);
-                Vector3 normals[4];
-                Vector3::cross(n, w, &normals[0]);
-                Vector3::cross(w, s, &normals[1]);
-                Vector3::cross(e, n, &normals[2]);
-                Vector3::cross(s, e, &normals[3]);
-                Vector3 normal = -(normals[0] + normals[1] + normals[2] + normals[3]);
-                normal.normalize();
-                v[0] = normal.x;
-                v[1] = normal.y;
-                v[2] = normal.z;
-                v += 3;
-            }
-
-            // Compute texture coord
-            v[0] = (float)x / width;
-            v[1] = 1.0f - (float)z / height;
-            if (xskirt)
-            {
-                float offset = verticalSkirtSize / width;
-                v[0] = x == x1 ? v[0]-offset : v[0]+offset;
-            }
-            else if (zskirt)
-            {
-                float offset = verticalSkirtSize / height;
-                v[1] = z == z1 ? v[1]-offset : v[1]+offset;
-            }
-
-            if (x == x2)
-            {
-                if ((verticalSkirtSize == 0) || xskirt)
-                    break;
-                else
-                    xskirt = true;
-            }
-            else if (xskirt)
-            {
-                xskirt = false;
-            }
-            else
-            {
-                x = std::min(x + step, x2);
-            }
-        }
-
-        if (z == z2)
-        {
-            if ((verticalSkirtSize == 0) || zskirt)
-                break;
-            else
-                zskirt = true;
-        }
-        else if (zskirt)
-        {
-            zskirt = false;
-        }
-        else
-        {
-            z = std::min(z + step, z2);
-        }
-    }
-    GP_ASSERT(index == vertexCount);
-
-    Vector3 center(min + ((max - min) * 0.5f));
-
-    // Create mesh
-    VertexFormat::Element elements[3];
-    elements[0] = VertexFormat::Element(VertexFormat::POSITION, 3);
-    if (_terrain->_normalMap)
-    {
-        elements[1] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
-    }
-    else
-    {
-        elements[1] = VertexFormat::Element(VertexFormat::NORMAL, 3);
-        elements[2] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
-    }
-    VertexFormat format(elements, _terrain->_normalMap ? 2 : 3);
-    Mesh* mesh = Mesh::createMesh(format, vertexCount);
-    mesh->setVertexData(vertices);
-    mesh->setBoundingBox(BoundingBox(min, max));
-    mesh->setBoundingSphere(BoundingSphere(center, center.distance(max)));
-
-    // Add mesh part for indices
-    unsigned int indexCount =
-        (patchWidth * 2) *      // # indices per row of tris
-        (patchHeight - 1) +     // # rows of tris
-        (patchHeight-2) * 2;    // # degenerate tris
-
-    // Support a maximum number of indices of USHRT_MAX. Any more indices we will require breaking up the
-    // terrain into smaller patches.
-    if (indexCount > USHRT_MAX)
-    {
-        GP_WARN("Index count of %d for terrain patch exceeds the limit of 65535. Please specifiy a smaller patch size.", indexCount);
-        GP_ASSERT(indexCount <= USHRT_MAX);
-    }
-
-    MeshPart* part = mesh->addPart(Mesh::TRIANGLE_STRIP, Mesh::INDEX16, indexCount);
-    unsigned short* indices = new unsigned short[indexCount];
-    index = 0;
-    for (unsigned int z = 0; z < patchHeight-1; ++z)
-    {
-        unsigned int i1 = z * patchWidth;
-        unsigned int i2 = (z+1) * patchWidth;
-
-        // Move left to right for even rows and right to left for odd rows.
-        // Note that this results in two degenerate triangles between rows
-        // for stitching purposes, but actually does not require any extra
-        // indices to achieve this.
-        if (z % 2 == 0)
-        {
-            if (z > 0)
-            {
-                // Add degenerate indices to connect strips
-                indices[index] = indices[index-1];
-                ++index;
-                indices[index++] = i1;
-            }
-
-            // Add row strip
-            for (unsigned int x = 0; x < patchWidth; ++x)
-            {
-                indices[index++] = i1 + x;
-                indices[index++] = i2 + x;
-            }
-        }
-        else
-        {
-            // Add degenerate indices to connect strips
-            if (z > 0)
-            {
-                indices[index] = indices[index-1];
-                ++index;
-                indices[index++] = i2 + ((int)patchWidth-1);
-            }
-
-            // Add row strip
-            for (int x = (int)patchWidth-1; x >= 0; --x)
-            {
-                indices[index++] = i2 + x;
-                indices[index++] = i1 + x;
-            }
-        }
-    }
-    GP_ASSERT(index == indexCount);
-    part->setIndexData(indices, 0, indexCount);
-
-    SAFE_DELETE_ARRAY(vertices);
-    SAFE_DELETE_ARRAY(indices);
-
-    // Create model
-    Model* model = Model::create(mesh);
-    mesh->release();
-
-    // Add this level
-    Level* level = new Level();
-    level->model = model;
-    _levels.push_back(level);
-}
-
-void TerrainPatch::deleteLayer(Layer* layer)
-{
-    // Release layer samplers
-    if (layer->textureIndex != -1)
-    {
-        if (_samplers[layer->textureIndex]->getRefCount() == 1)
-        {
-            SAFE_RELEASE(_samplers[layer->textureIndex]);
-        }
-        else
-        {
-            _samplers[layer->textureIndex]->release();
-        }
-    }
-
-    if (layer->blendIndex != -1)
-    {
-        if (_samplers[layer->blendIndex]->getRefCount() == 1)
-        {
-            SAFE_RELEASE(_samplers[layer->blendIndex]);
-        }
-        else
-        {
-            _samplers[layer->blendIndex]->release();
-        }
-    }
-
-    _layers.erase(layer);
-    SAFE_DELETE(layer);
-}
-
-int TerrainPatch::addSampler(const char* path)
-{
-    // TODO: Support shared samplers stored in Terrain class for layers that span all patches
-    // on the terrain (row == col == -1).
-
-    // Load the texture. If this texture is already loaded, it will return
-    // a pointer to the same one, with its ref count incremented.
-    Texture* texture = Texture::create(path, true);
-    if (!texture)
-        return -1;
-
-    int firstAvailableIndex = -1;
-    for (size_t i = 0, count = _samplers.size(); i < count; ++i)
-    {
-        Texture::Sampler* sampler = _samplers[i];
-
-        if (sampler == NULL && firstAvailableIndex == -1)
-        {
-            firstAvailableIndex = (int)i;
-        }
-        else if (sampler->getTexture() == texture)
-        {
-            // A sampler was already added for this texture.
-            // Increase the ref count for the sampler to indicate that a new
-            // layer will be referencing it.
-            texture->release();
-            sampler->addRef();
-            return (int)i;
-        }
-    }
-
-    // Add a new sampler to the list
-    Texture::Sampler* sampler = Texture::Sampler::create(texture);
-    texture->release();
-    sampler->setWrapMode(Texture::REPEAT, Texture::REPEAT);
-    sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
-    if (firstAvailableIndex != -1)
-    {
-        _samplers[firstAvailableIndex] = sampler;
-        return firstAvailableIndex;
-    }
-
-    _samplers.push_back(sampler);
-    return (int)(_samplers.size()-1);
-}
-
-bool TerrainPatch::setLayer(int index, const char* texturePath, const Vector2& textureRepeat, const char* blendPath, int blendChannel)
-{
-    // If there is an existing layer at this index, delete it
-    for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr)
-    {
-        Layer* layer = *itr;
-        if (layer->index == index)
-        {
-            deleteLayer(layer);
-            break;
-        }
-    }
-
-    // Load texture sampler
-    int textureIndex = addSampler(texturePath);
-    if (textureIndex == -1)
-        return false;
-
-    // Load blend sampler
-    int blendIndex = -1;
-    if (blendPath)
-    {
-        blendIndex = addSampler(blendPath);
-    }
-
-    // Create the layer
-    Layer* layer = new Layer();
-    layer->index = index;
-    layer->textureIndex = textureIndex;
-    layer->textureRepeat = textureRepeat;
-    layer->blendIndex = blendIndex;
-    layer->blendChannel = blendChannel;
-
-    _layers.insert(layer);
-
-    _materialDirty = true;
-
-    return true;
-}
-
-bool TerrainPatch::updateMaterial()
-{
-    if (!_materialDirty)
-        return true;
-
-    _materialDirty = false;
-
-    for (size_t i = 0, count = _levels.size(); i < count; ++i)
-    {
-        // Build preprocessor string to pass to shader.
-        // NOTE: I make heavy use of preprocessor definitions, rather than passing in arrays and doing
-        // non-constant array access in the shader. This is due to the fact that non-constant array access
-        // in GLES is very slow on some GLES 2.x hardware.
-        std::ostringstream defines;
-        defines << "LAYER_COUNT " << _layers.size();
-        defines << ";SAMPLER_COUNT " << _samplers.size();
-        if (_terrain->isFlagSet(Terrain::DEBUG_PATCHES))
-            defines << ";DEBUG_PATCHES";
-        if (_terrain->_normalMap)
-            defines << ";NORMAL_MAP";
-
-        // Append texture and blend index constants to preprocessor definition.
-        // We need to do this since older versions of GLSL only allow sampler arrays
-        // to be indexed using constant expressions (otherwise we could simply pass an
-        // array of indices to use for sampler lookup).
-        //
-        // Rebuild layer lists while we're at it.
-        //
-        int layerIndex = 0;
-        for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr, ++layerIndex)
-        {
-            Layer* layer = *itr;
-
-            defines << ";TEXTURE_INDEX_" << layerIndex << " " << layer->textureIndex;
-            defines << ";TEXTURE_REPEAT_" << layerIndex << " vec2(" << layer->textureRepeat.x << "," << layer->textureRepeat.y << ")";
-
-            if (layerIndex > 0)
-            {
-                defines << ";BLEND_INDEX_" << layerIndex << " " << layer->blendIndex;
-                defines << ";BLEND_CHANNEL_" << layerIndex << " " << layer->blendChannel;
-            }
-        }
-
-        Material* material = Material::create(TERRAIN_VSH, TERRAIN_FSH, defines.str().c_str());
-        if (!material)
-            return false;
-        material->getStateBlock()->setCullFace(true);
-        material->getStateBlock()->setDepthTest(true);
-
-        // Set material parameter bindings
-        material->getParameter("u_worldViewProjectionMatrix")->bindValue(_terrain, &Terrain::getWorldViewProjectionMatrix);
-        if (!_terrain->_normalMap)
-            material->getParameter("u_normalMatrix")->bindValue(_terrain, &Terrain::getNormalMatrix);
-        material->getParameter("u_ambientColor")->bindValue(this, &TerrainPatch::getAmbientColor);
-        material->getParameter("u_lightColor")->bindValue(this, &TerrainPatch::getLightColor);
-        material->getParameter("u_lightDirection")->bindValue(this, &TerrainPatch::getLightDirection);
-        if (_layers.size() > 0)
-        {
-            material->getParameter("u_samplers")->setValue((const Texture::Sampler**)&_samplers[0], (unsigned int)_samplers.size());
-            if (_terrain->_normalMap)
-                material->getParameter("u_normalMap")->setValue(_terrain->_normalMap);
-        }
-
-        if (_terrain->isFlagSet(Terrain::DEBUG_PATCHES))
-        {
-            material->getParameter("u_row")->setValue((float)_row);
-            material->getParameter("u_column")->setValue((float)_column);
-        }
-
-        // Set material on this lod level
-        _levels[i]->model->setMaterial(material);
-
-        material->release();
-    }
-
-    return true;
-}
-
-void TerrainPatch::draw(bool wireframe)
-{
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    Camera* camera = scene ? scene->getActiveCamera() : NULL;
-    if (!camera)
-        return;
-
-    // Get our world-space bounding box
-    BoundingBox bounds = getBoundingBox(true);
-
-    // If the box does not intersect the view frustum, cull it
-    if (_terrain->isFlagSet(Terrain::ENABLE_FRUSTUM_CULLING) && !camera->getFrustum().intersects(bounds))
-        return;
-
-    if (!updateMaterial())
-        return;
-
-    // Compute the LOD level from the camera's perspective
-    size_t lod = computeLOD(camera, bounds);
-
-    // Draw the model for the current LOD
-    _levels[lod]->model->draw(wireframe);
-}
-
-bool TerrainPatch::isVisible() const
-{
-    // If frustum culling is disabled, assume the patch is always visible
-    if ((_terrain->_flags & Terrain::ENABLE_FRUSTUM_CULLING) == 0)
-        return true;
-
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    Camera* camera = scene ? scene->getActiveCamera() : NULL;
-    if (!camera)
-        return false;
-
-    // Does the current camera view frustum intersect our world bounds?
-    return camera->getFrustum().intersects(getBoundingBox(true));
-}
-
-unsigned int TerrainPatch::getTriangleCount() const
-{
-    // Patches are made up of a single mesh part using triangle strips
-    return _levels[0]->model->getMesh()->getPart(0)->getIndexCount() - 2;
-}
-
-unsigned int TerrainPatch::getVisibleTriangleCount() const
-{
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    Camera* camera = scene ? scene->getActiveCamera() : NULL;
-    if (!camera)
-        return 0;
-
-    // Does the current camera intersect this patch at all?
-    BoundingBox bounds = getBoundingBox(true);
-    if (!camera->getFrustum().intersects(bounds))
-        return 0;
-
-    // Return the triangle count of the LOD level depending on the camera
-    size_t lod = computeLOD(camera, bounds);
-    return _levels[lod]->model->getMesh()->getPart(0)->getIndexCount() - 2;
-}
-
-BoundingBox TerrainPatch::getBoundingBox(bool worldSpace) const
-{
-    if (!worldSpace)
-        return _boundingBox;
-
-    // Apply a world-space transformation to our bounding box
-    BoundingBox bounds(_boundingBox);
-
-    // Transform the bounding box by the terrain node's world transform.
-    // We don't use Terrain::getWorldMatrix because that returns a matrix
-    // that has terrain->_localScale factored in - and our patche's bounding
-    // box already has local scale factored in.
-    if (_terrain->_node)
-        bounds.transform(_terrain->_node->getWorldMatrix());
-
-    return bounds;
-}
-
-const Vector3& TerrainPatch::getAmbientColor() const
-{
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    return scene ? scene->getAmbientColor() : Vector3::zero();
-}
-
-const Vector3& TerrainPatch::getLightColor() const
-{
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    return scene ? scene->getLightColor() : Vector3::one();
-}
-
-const Vector3& TerrainPatch::getLightDirection() const
-{
-    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
-    if (!scene)
-    {
-        static Vector3 down(0, -1, 0);
-        return down;
-    }
-
-    return scene->getLightDirection();
-}
-
-size_t TerrainPatch::computeLOD(Camera* camera, const BoundingBox& worldBounds) const
-{
-    if (!_terrain->isFlagSet(Terrain::ENABLE_LEVEL_OF_DETAIL) || _levels.size() == 0)
-        return 0; // base level
-
-    // Compute LOD to use based on very simple distance metric.
-    // TODO: Optimize this.
-    Game* game = Game::getInstance();
-    Rectangle vp(0, 0, game->getWidth(), game->getHeight());
-    Vector3 corners[8];
-    Vector2 min(FLT_MAX, FLT_MAX);
-    Vector2 max(-FLT_MAX, -FLT_MAX);
-    worldBounds.getCorners(corners);
-    for (unsigned int i = 0; i < 8; ++i)
-    {
-        const Vector3& corner = corners[i];
-        float x, y;
-        camera->project(vp, corners[i], &x, &y);
-        if (x < min.x)
-            min.x = x;
-        if (y < min.y)
-            min.y = y;
-        if (x > max.x)
-            max.x = x;
-        if (y > max.y)
-            max.y = y;
-    }
-    float area = (max.x - min.x) * (max.y - min.y);
-    float screenArea = game->getWidth() * game->getHeight() / 10.0f;
-    float error = screenArea / area;
-
-    // Level LOD based on distance from camera
-    size_t maxLod = _levels.size()-1;
-    size_t lod = (size_t)error;
-    lod = std::max(lod, (size_t)0);
-    lod = std::min(lod, maxLod);
-    return lod;
-}
-
-float calculateHeight(float* heights, unsigned int width, unsigned int height, unsigned int x, unsigned int z)
-{
-    return heights[z * width + x];
-}
-
-TerrainPatch::Layer::Layer() :
-    index(0), row(-1), column(-1), textureIndex(-1), blendIndex(-1)
-{
-}
-
-TerrainPatch::Layer::~Layer()
-{
-}
-
-bool TerrainPatch::LayerCompare::operator() (const Layer* lhs, const Layer* rhs) const
-{
-    return (lhs->index < rhs->index);
-}
-
-}
+#define TERRAIN_FSH "res/shaders/terrain.frag"
+
+namespace gameplay
+{
+
+/**
+ * @script{ignore}
+ */
+float calculateHeight(float* heights, unsigned int width, unsigned int height, unsigned int x, unsigned int z);
+
+/**
+ * @script{ignore}
+ */
+template <class T> T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); }
+
+TerrainPatch::TerrainPatch() :
+    _terrain(NULL), _row(0), _column(0), _materialDirty(true)
+{
+}
+
+TerrainPatch::~TerrainPatch()
+{
+    for (size_t i = 0, count = _levels.size(); i < count; ++i)
+    {
+        Level* level = _levels[i];
+
+        SAFE_RELEASE(level->model);
+        SAFE_DELETE(level);
+    }
+
+    while (_layers.size() > 0)
+    {
+        deleteLayer(*_layers.begin());
+    }
+}
+
+TerrainPatch* TerrainPatch::create(Terrain* terrain,
+    unsigned int row, unsigned int column,
+    float* heights, unsigned int width, unsigned int height,
+    unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
+    float xOffset, float zOffset,
+    unsigned int maxStep, float verticalSkirtSize)
+{
+    // Create patch
+    TerrainPatch* patch = new TerrainPatch();
+    patch->_terrain = terrain;
+    patch->_row = row;
+    patch->_column = column;
+
+    // Add patch lods
+    for (unsigned int step = 1; step <= maxStep; step *= 2)
+    {
+        patch->addLOD(heights, width, height, x1, z1, x2, z2, xOffset, zOffset, step, verticalSkirtSize);
+    }
+
+    // Set our bounding box using the base LOD mesh
+    BoundingBox& bounds = patch->_boundingBox;
+    bounds.set(patch->_levels[0]->model->getMesh()->getBoundingBox());
+
+    // Apply the terrain's local scale to our bounds
+    const Vector3& localScale = terrain->_localScale;
+    if (!localScale.isOne())
+    {
+        bounds.min.set(bounds.min.x * localScale.x, bounds.min.y * localScale.y, bounds.min.z * localScale.z);
+        bounds.max.set(bounds.max.x * localScale.x, bounds.max.y * localScale.y, bounds.max.z * localScale.z);
+    }
+
+    return patch;
+}
+
+void TerrainPatch::addLOD(float* heights, unsigned int width, unsigned int height,
+    unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
+    float xOffset, float zOffset,
+    unsigned int step, float verticalSkirtSize)
+{
+    // Allocate vertex data for this patch
+    unsigned int patchWidth;
+    unsigned int patchHeight;
+    if (step == 1)
+    {
+        patchWidth = (x2 - x1) + 1;
+        patchHeight = (z2 - z1) + 1;
+    }
+    else
+    {
+        patchWidth = (x2 - x1) / step + ((x2 - x1) %step == 0 ? 0 : 1) + 1;
+        patchHeight = (z2 - z1) / step + ((z2 - z1) % step == 0 ? 0 : 1) + 1;
+    }
+
+    if (patchWidth < 2 || patchHeight < 2)
+        return; // ignore this level, not enough geometry
+
+    if (verticalSkirtSize > 0.0f)
+    {
+        patchWidth += 2;
+        patchHeight += 2;
+    }
+
+    unsigned int vertexCount = patchHeight * patchWidth;
+    unsigned int vertexElements = _terrain->_normalMap ? 5 : 8; //<x,y,z>[i,j,k]<u,v>
+    float* vertices = new float[vertexCount * vertexElements];
+    unsigned int index = 0;
+    Vector3 min(FLT_MAX, FLT_MAX, FLT_MAX);
+    Vector3 max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+    bool zskirt = verticalSkirtSize > 0 ? true : false;
+    for (unsigned int z = z1; ; )
+    {
+        bool xskirt = verticalSkirtSize > 0 ? true : false;
+        for (unsigned int x = x1; ; )
+        {
+            GP_ASSERT(index < vertexCount);
+
+            float* v = vertices + (index * vertexElements);
+            index++;
+
+            // Compute position
+            v[0] = x + xOffset;
+            v[1] = calculateHeight(heights, width, height, x, z);
+            if (xskirt || zskirt)
+                v[1] -= verticalSkirtSize;
+            v[2] = z + zOffset;
+
+            // Update bounding box min/max (don't include vertical skirt vertices in bounding box)
+            if (!(xskirt || zskirt))
+            {
+                if (v[0] < min.x)
+                    min.x = v[0];
+                if (v[1] < min.y)
+                    min.y = v[1];
+                if (v[2] < min.z)
+                    min.z = v[2];
+                if (v[0] > max.x)
+                    max.x = v[0];
+                if (v[1] > max.y)
+                    max.y = v[1];
+                if (v[2] > max.z)
+                    max.z = v[2];
+            }
+            v += 3;
+
+            // Compute normal
+            if (!_terrain->_normalMap)
+            {
+                Vector3 p(x, calculateHeight(heights, width, height, x, z), z);
+                Vector3 w(Vector3(x>=step ? x-step : x, calculateHeight(heights, width, height, x>=step ? x-step : x, z), z), p);
+                Vector3 e(Vector3(x<width-step ? x+step : x, calculateHeight(heights, width, height, x<width-step ? x+step : x, z), z), p);
+                Vector3 s(Vector3(x, calculateHeight(heights, width, height, x, z>=step ? z-step : z), z>=step ? z-step : z), p);
+                Vector3 n(Vector3(x, calculateHeight(heights, width, height, x, z<height-step ? z+step : z), z<height-step ? z+step : z), p);
+                Vector3 normals[4];
+                Vector3::cross(n, w, &normals[0]);
+                Vector3::cross(w, s, &normals[1]);
+                Vector3::cross(e, n, &normals[2]);
+                Vector3::cross(s, e, &normals[3]);
+                Vector3 normal = -(normals[0] + normals[1] + normals[2] + normals[3]);
+                normal.normalize();
+                v[0] = normal.x;
+                v[1] = normal.y;
+                v[2] = normal.z;
+                v += 3;
+            }
+
+            // Compute texture coord
+            v[0] = (float)x / width;
+            v[1] = 1.0f - (float)z / height;
+            if (xskirt)
+            {
+                float offset = verticalSkirtSize / width;
+                v[0] = x == x1 ? v[0]-offset : v[0]+offset;
+            }
+            else if (zskirt)
+            {
+                float offset = verticalSkirtSize / height;
+                v[1] = z == z1 ? v[1]-offset : v[1]+offset;
+            }
+
+            if (x == x2)
+            {
+                if ((verticalSkirtSize == 0) || xskirt)
+                    break;
+                else
+                    xskirt = true;
+            }
+            else if (xskirt)
+            {
+                xskirt = false;
+            }
+            else
+            {
+                x = std::min(x + step, x2);
+            }
+        }
+
+        if (z == z2)
+        {
+            if ((verticalSkirtSize == 0) || zskirt)
+                break;
+            else
+                zskirt = true;
+        }
+        else if (zskirt)
+        {
+            zskirt = false;
+        }
+        else
+        {
+            z = std::min(z + step, z2);
+        }
+    }
+    GP_ASSERT(index == vertexCount);
+
+    Vector3 center(min + ((max - min) * 0.5f));
+
+    // Create mesh
+    VertexFormat::Element elements[3];
+    elements[0] = VertexFormat::Element(VertexFormat::POSITION, 3);
+    if (_terrain->_normalMap)
+    {
+        elements[1] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
+    }
+    else
+    {
+        elements[1] = VertexFormat::Element(VertexFormat::NORMAL, 3);
+        elements[2] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
+    }
+    VertexFormat format(elements, _terrain->_normalMap ? 2 : 3);
+    Mesh* mesh = Mesh::createMesh(format, vertexCount);
+    mesh->setVertexData(vertices);
+    mesh->setBoundingBox(BoundingBox(min, max));
+    mesh->setBoundingSphere(BoundingSphere(center, center.distance(max)));
+
+    // Add mesh part for indices
+    unsigned int indexCount =
+        (patchWidth * 2) *      // # indices per row of tris
+        (patchHeight - 1) +     // # rows of tris
+        (patchHeight-2) * 2;    // # degenerate tris
+
+    // Support a maximum number of indices of USHRT_MAX. Any more indices we will require breaking up the
+    // terrain into smaller patches.
+    if (indexCount > USHRT_MAX)
+    {
+        GP_WARN("Index count of %d for terrain patch exceeds the limit of 65535. Please specifiy a smaller patch size.", indexCount);
+        GP_ASSERT(indexCount <= USHRT_MAX);
+    }
+
+    MeshPart* part = mesh->addPart(Mesh::TRIANGLE_STRIP, Mesh::INDEX16, indexCount);
+    unsigned short* indices = new unsigned short[indexCount];
+    index = 0;
+    for (unsigned int z = 0; z < patchHeight-1; ++z)
+    {
+        unsigned int i1 = z * patchWidth;
+        unsigned int i2 = (z+1) * patchWidth;
+
+        // Move left to right for even rows and right to left for odd rows.
+        // Note that this results in two degenerate triangles between rows
+        // for stitching purposes, but actually does not require any extra
+        // indices to achieve this.
+        if (z % 2 == 0)
+        {
+            if (z > 0)
+            {
+                // Add degenerate indices to connect strips
+                indices[index] = indices[index-1];
+                ++index;
+                indices[index++] = i1;
+            }
+
+            // Add row strip
+            for (unsigned int x = 0; x < patchWidth; ++x)
+            {
+                indices[index++] = i1 + x;
+                indices[index++] = i2 + x;
+            }
+        }
+        else
+        {
+            // Add degenerate indices to connect strips
+            if (z > 0)
+            {
+                indices[index] = indices[index-1];
+                ++index;
+                indices[index++] = i2 + ((int)patchWidth-1);
+            }
+
+            // Add row strip
+            for (int x = (int)patchWidth-1; x >= 0; --x)
+            {
+                indices[index++] = i2 + x;
+                indices[index++] = i1 + x;
+            }
+        }
+    }
+    GP_ASSERT(index == indexCount);
+    part->setIndexData(indices, 0, indexCount);
+
+    SAFE_DELETE_ARRAY(vertices);
+    SAFE_DELETE_ARRAY(indices);
+
+    // Create model
+    Model* model = Model::create(mesh);
+    mesh->release();
+
+    // Add this level
+    Level* level = new Level();
+    level->model = model;
+    _levels.push_back(level);
+}
+
+void TerrainPatch::deleteLayer(Layer* layer)
+{
+    // Release layer samplers
+    if (layer->textureIndex != -1)
+    {
+        if (_samplers[layer->textureIndex]->getRefCount() == 1)
+        {
+            SAFE_RELEASE(_samplers[layer->textureIndex]);
+        }
+        else
+        {
+            _samplers[layer->textureIndex]->release();
+        }
+    }
+
+    if (layer->blendIndex != -1)
+    {
+        if (_samplers[layer->blendIndex]->getRefCount() == 1)
+        {
+            SAFE_RELEASE(_samplers[layer->blendIndex]);
+        }
+        else
+        {
+            _samplers[layer->blendIndex]->release();
+        }
+    }
+
+    _layers.erase(layer);
+    SAFE_DELETE(layer);
+}
+
+int TerrainPatch::addSampler(const char* path)
+{
+    // TODO: Support shared samplers stored in Terrain class for layers that span all patches
+    // on the terrain (row == col == -1).
+
+    // Load the texture. If this texture is already loaded, it will return
+    // a pointer to the same one, with its ref count incremented.
+    Texture* texture = Texture::create(path, true);
+    if (!texture)
+        return -1;
+
+    int firstAvailableIndex = -1;
+    for (size_t i = 0, count = _samplers.size(); i < count; ++i)
+    {
+        Texture::Sampler* sampler = _samplers[i];
+
+        if (sampler == NULL && firstAvailableIndex == -1)
+        {
+            firstAvailableIndex = (int)i;
+        }
+        else if (sampler->getTexture() == texture)
+        {
+            // A sampler was already added for this texture.
+            // Increase the ref count for the sampler to indicate that a new
+            // layer will be referencing it.
+            texture->release();
+            sampler->addRef();
+            return (int)i;
+        }
+    }
+
+    // Add a new sampler to the list
+    Texture::Sampler* sampler = Texture::Sampler::create(texture);
+    texture->release();
+    sampler->setWrapMode(Texture::REPEAT, Texture::REPEAT);
+    sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
+    if (firstAvailableIndex != -1)
+    {
+        _samplers[firstAvailableIndex] = sampler;
+        return firstAvailableIndex;
+    }
+
+    _samplers.push_back(sampler);
+    return (int)(_samplers.size()-1);
+}
+
+bool TerrainPatch::setLayer(int index, const char* texturePath, const Vector2& textureRepeat, const char* blendPath, int blendChannel)
+{
+    // If there is an existing layer at this index, delete it
+    for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr)
+    {
+        Layer* layer = *itr;
+        if (layer->index == index)
+        {
+            deleteLayer(layer);
+            break;
+        }
+    }
+
+    // Load texture sampler
+    int textureIndex = addSampler(texturePath);
+    if (textureIndex == -1)
+        return false;
+
+    // Load blend sampler
+    int blendIndex = -1;
+    if (blendPath)
+    {
+        blendIndex = addSampler(blendPath);
+    }
+
+    // Create the layer
+    Layer* layer = new Layer();
+    layer->index = index;
+    layer->textureIndex = textureIndex;
+    layer->textureRepeat = textureRepeat;
+    layer->blendIndex = blendIndex;
+    layer->blendChannel = blendChannel;
+
+    _layers.insert(layer);
+
+    _materialDirty = true;
+
+    return true;
+}
+
+bool TerrainPatch::updateMaterial()
+{
+    if (!_materialDirty)
+        return true;
+
+    _materialDirty = false;
+
+    for (size_t i = 0, count = _levels.size(); i < count; ++i)
+    {
+        // Build preprocessor string to pass to shader.
+        // NOTE: I make heavy use of preprocessor definitions, rather than passing in arrays and doing
+        // non-constant array access in the shader. This is due to the fact that non-constant array access
+        // in GLES is very slow on some GLES 2.x hardware.
+        std::ostringstream defines;
+        defines << "LAYER_COUNT " << _layers.size();
+        defines << ";SAMPLER_COUNT " << _samplers.size();
+        if (_terrain->isFlagSet(Terrain::DEBUG_PATCHES))
+            defines << ";DEBUG_PATCHES";
+        if (_terrain->_normalMap)
+            defines << ";NORMAL_MAP";
+
+        // Append texture and blend index constants to preprocessor definition.
+        // We need to do this since older versions of GLSL only allow sampler arrays
+        // to be indexed using constant expressions (otherwise we could simply pass an
+        // array of indices to use for sampler lookup).
+        //
+        // Rebuild layer lists while we're at it.
+        //
+        int layerIndex = 0;
+        for (std::set<Layer*, LayerCompare>::iterator itr = _layers.begin(); itr != _layers.end(); ++itr, ++layerIndex)
+        {
+            Layer* layer = *itr;
+
+            defines << ";TEXTURE_INDEX_" << layerIndex << " " << layer->textureIndex;
+            defines << ";TEXTURE_REPEAT_" << layerIndex << " vec2(" << layer->textureRepeat.x << "," << layer->textureRepeat.y << ")";
+
+            if (layerIndex > 0)
+            {
+                defines << ";BLEND_INDEX_" << layerIndex << " " << layer->blendIndex;
+                defines << ";BLEND_CHANNEL_" << layerIndex << " " << layer->blendChannel;
+            }
+        }
+
+        Material* material = Material::create(TERRAIN_VSH, TERRAIN_FSH, defines.str().c_str());
+        if (!material)
+            return false;
+        material->getStateBlock()->setCullFace(true);
+        material->getStateBlock()->setDepthTest(true);
+
+        // Set material parameter bindings
+        material->getParameter("u_worldViewProjectionMatrix")->bindValue(_terrain, &Terrain::getWorldViewProjectionMatrix);
+        if (!_terrain->_normalMap)
+            material->getParameter("u_normalMatrix")->bindValue(_terrain, &Terrain::getNormalMatrix);
+        material->getParameter("u_ambientColor")->bindValue(this, &TerrainPatch::getAmbientColor);
+        material->getParameter("u_lightColor")->bindValue(this, &TerrainPatch::getLightColor);
+        material->getParameter("u_lightDirection")->bindValue(this, &TerrainPatch::getLightDirection);
+        if (_layers.size() > 0)
+            material->getParameter("u_samplers")->setValue((const Texture::Sampler**)&_samplers[0], (unsigned int)_samplers.size());
+        if (_terrain->_normalMap)
+            material->getParameter("u_normalMap")->setValue(_terrain->_normalMap);
+
+        if (_terrain->isFlagSet(Terrain::DEBUG_PATCHES))
+        {
+            material->getParameter("u_row")->setValue((float)_row);
+            material->getParameter("u_column")->setValue((float)_column);
+        }
+
+        // Set material on this lod level
+        _levels[i]->model->setMaterial(material);
+
+        material->release();
+    }
+
+    return true;
+}
+
+void TerrainPatch::draw(bool wireframe)
+{
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    Camera* camera = scene ? scene->getActiveCamera() : NULL;
+    if (!camera)
+        return;
+
+    // Get our world-space bounding box
+    BoundingBox bounds = getBoundingBox(true);
+
+    // If the box does not intersect the view frustum, cull it
+    if (_terrain->isFlagSet(Terrain::FRUSTUM_CULLING) && !camera->getFrustum().intersects(bounds))
+        return;
+
+    if (!updateMaterial())
+        return;
+
+    // Compute the LOD level from the camera's perspective
+    size_t lod = computeLOD(camera, bounds);
+
+    // Draw the model for the current LOD
+    _levels[lod]->model->draw(wireframe);
+}
+
+bool TerrainPatch::isVisible() const
+{
+    // If frustum culling is disabled, assume the patch is always visible
+    if ((_terrain->_flags & Terrain::FRUSTUM_CULLING) == 0)
+        return true;
+
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    Camera* camera = scene ? scene->getActiveCamera() : NULL;
+    if (!camera)
+        return false;
+
+    // Does the current camera view frustum intersect our world bounds?
+    return camera->getFrustum().intersects(getBoundingBox(true));
+}
+
+unsigned int TerrainPatch::getTriangleCount() const
+{
+    // Patches are made up of a single mesh part using triangle strips
+    return _levels[0]->model->getMesh()->getPart(0)->getIndexCount() - 2;
+}
+
+unsigned int TerrainPatch::getVisibleTriangleCount() const
+{
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    Camera* camera = scene ? scene->getActiveCamera() : NULL;
+    if (!camera)
+        return 0;
+
+    // Does the current camera intersect this patch at all?
+    BoundingBox bounds = getBoundingBox(true);
+    if (!camera->getFrustum().intersects(bounds))
+        return 0;
+
+    // Return the triangle count of the LOD level depending on the camera
+    size_t lod = computeLOD(camera, bounds);
+    return _levels[lod]->model->getMesh()->getPart(0)->getIndexCount() - 2;
+}
+
+BoundingBox TerrainPatch::getBoundingBox(bool worldSpace) const
+{
+    if (!worldSpace)
+        return _boundingBox;
+
+    // Apply a world-space transformation to our bounding box
+    BoundingBox bounds(_boundingBox);
+
+    // Transform the bounding box by the terrain node's world transform.
+    // We don't use Terrain::getWorldMatrix because that returns a matrix
+    // that has terrain->_localScale factored in - and our patche's bounding
+    // box already has local scale factored in.
+    if (_terrain->_node)
+        bounds.transform(_terrain->_node->getWorldMatrix());
+
+    return bounds;
+}
+
+const Vector3& TerrainPatch::getAmbientColor() const
+{
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    return scene ? scene->getAmbientColor() : Vector3::zero();
+}
+
+const Vector3& TerrainPatch::getLightColor() const
+{
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    return scene ? scene->getLightColor() : Vector3::one();
+}
+
+const Vector3& TerrainPatch::getLightDirection() const
+{
+    Scene* scene = _terrain->_node ? _terrain->_node->getScene() : NULL;
+    if (!scene)
+    {
+        static Vector3 down(0, -1, 0);
+        return down;
+    }
+
+    return scene->getLightDirection();
+}
+
+size_t TerrainPatch::computeLOD(Camera* camera, const BoundingBox& worldBounds) const
+{
+    if (!_terrain->isFlagSet(Terrain::LEVEL_OF_DETAIL) || _levels.size() == 0)
+        return 0; // base level
+
+    // Compute LOD to use based on very simple distance metric.
+    // TODO: Optimize this.
+    Game* game = Game::getInstance();
+    Rectangle vp(0, 0, game->getWidth(), game->getHeight());
+    Vector3 corners[8];
+    Vector2 min(FLT_MAX, FLT_MAX);
+    Vector2 max(-FLT_MAX, -FLT_MAX);
+    worldBounds.getCorners(corners);
+    for (unsigned int i = 0; i < 8; ++i)
+    {
+        const Vector3& corner = corners[i];
+        float x, y;
+        camera->project(vp, corners[i], &x, &y);
+        if (x < min.x)
+            min.x = x;
+        if (y < min.y)
+            min.y = y;
+        if (x > max.x)
+            max.x = x;
+        if (y > max.y)
+            max.y = y;
+    }
+    float area = (max.x - min.x) * (max.y - min.y);
+    float screenArea = game->getWidth() * game->getHeight() / 10.0f;
+    float error = screenArea / area;
+
+    // Level LOD based on distance from camera
+    size_t maxLod = _levels.size()-1;
+    size_t lod = (size_t)error;
+    lod = std::max(lod, (size_t)0);
+    lod = std::min(lod, maxLod);
+    return lod;
+}
+
+float calculateHeight(float* heights, unsigned int width, unsigned int height, unsigned int x, unsigned int z)
+{
+    return heights[z * width + x];
+}
+
+TerrainPatch::Layer::Layer() :
+    index(0), row(-1), column(-1), textureIndex(-1), blendIndex(-1)
+{
+}
+
+TerrainPatch::Layer::~Layer()
+{
+}
+
+bool TerrainPatch::LayerCompare::operator() (const Layer* lhs, const Layer* rhs) const
+{
+    return (lhs->index < rhs->index);
+}
+
+}

+ 7 - 14
gameplay/src/TerrainPatch.h

@@ -71,31 +71,24 @@ private:
     /**
      * Internal method to create new terrain patch.
      */
-    static TerrainPatch* create(Terrain* terrain,
-        unsigned int row, unsigned int column,
-        float* heights, unsigned int width, unsigned int height,
-        unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
-        float xOffset, float zOffset,
-        unsigned int maxStep, float verticalSkirtSize);
+    static TerrainPatch* create(Terrain* terrain, 
+                                unsigned int row, unsigned int column,
+                                float* heights, unsigned int width, unsigned int height,
+                                unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
+                                float xOffset, float zOffset, unsigned int maxStep, float verticalSkirtSize);
 
     /**
      * Adds a single LOD level to the terrain patch.
      */
     void addLOD(float* heights, unsigned int width, unsigned int height,
-        unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
-        float xOffset, float zOffset,
-        unsigned int step, float verticalSkirtSize);
+                unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2,
+                float xOffset, float zOffset, unsigned int step, float verticalSkirtSize);
 
     /**
      * Sets details for a layer of this patch.
      */
     bool setLayer(int index, const char* texturePath, const Vector2& textureRepeat, const char* blendPath, int blendChannel);
 
-    /**
-     * Sets the level of detail for the terrain patch.
-     */
-    void setLod(unsigned int lod);
-
     /**
      * Adds a sampler to the patch.
      */

+ 1 - 1
gameplay/src/TextBox.h

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

+ 1 - 1
gameplay/src/Texture.cpp

@@ -477,7 +477,7 @@ GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GL
     return data;
 }
 
-int getMaskByteIndex(unsigned int mask)
+int Texture::getMaskByteIndex(unsigned int mask)
 {
     switch (mask)
     {

+ 2 - 0
gameplay/src/Texture.h

@@ -297,6 +297,8 @@ private:
 
     static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
 
+    static int getMaskByteIndex(unsigned int mask);
+
     std::string _path;
     TextureHandle _handle;
     Format _format;

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

@@ -74,7 +74,7 @@ void luaRegister_lua_Global()
     ScriptUtil::setGlobalHierarchyPair("Ref", "Font");
     ScriptUtil::setGlobalHierarchyPair("Ref", "Form");
     ScriptUtil::setGlobalHierarchyPair("Ref", "FrameBuffer");
-    ScriptUtil::setGlobalHierarchyPair("Ref", "HeightField");
+    ScriptUtil::setGlobalHierarchyPair("Ref", "HeightField");
     ScriptUtil::setGlobalHierarchyPair("Ref", "Image");
     ScriptUtil::setGlobalHierarchyPair("Ref", "Joint");
     ScriptUtil::setGlobalHierarchyPair("Ref", "Joystick");
@@ -769,8 +769,8 @@ void luaRegister_lua_Global()
         std::vector<std::string> scopePath;
         scopePath.push_back("Terrain");
         ScriptUtil::registerConstantString("DEBUG_PATCHES", "DEBUG_PATCHES", scopePath);
-        ScriptUtil::registerConstantString("ENABLE_FRUSTUM_CULLING", "ENABLE_FRUSTUM_CULLING", scopePath);
-        ScriptUtil::registerConstantString("ENABLE_LEVEL_OF_DETAIL", "ENABLE_LEVEL_OF_DETAIL", scopePath);
+        ScriptUtil::registerConstantString("FRUSTUM_CULLING", "FRUSTUM_CULLING", scopePath);
+        ScriptUtil::registerConstantString("LEVEL_OF_DETAIL", "LEVEL_OF_DETAIL", scopePath);
     }
 
     // Register enumeration Texture::Filter.

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

@@ -9,6 +9,7 @@
 #include "Ref.h"
 #include "Scene.h"
 #include "SceneLoader.h"
+#include "Terrain.h"
 
 namespace gameplay
 {

+ 219 - 0
gameplay/src/lua/lua_Slider.cpp

@@ -71,12 +71,15 @@ void luaRegister_Slider()
         {"getTextRightToLeft", lua_Slider_getTextRightToLeft},
         {"getType", lua_Slider_getType},
         {"getValue", lua_Slider_getValue},
+        {"getValueTextAlignment", lua_Slider_getValueTextAlignment},
+        {"getValueTextPrecision", lua_Slider_getValueTextPrecision},
         {"getWidth", lua_Slider_getWidth},
         {"getX", lua_Slider_getX},
         {"getY", lua_Slider_getY},
         {"getZIndex", lua_Slider_getZIndex},
         {"isContainer", lua_Slider_isContainer},
         {"isEnabled", lua_Slider_isEnabled},
+        {"isValueTextVisible", lua_Slider_isValueTextVisible},
         {"isVisible", lua_Slider_isVisible},
         {"release", lua_Slider_release},
         {"removeListener", lua_Slider_removeListener},
@@ -114,6 +117,9 @@ void luaRegister_Slider()
         {"setTextColor", lua_Slider_setTextColor},
         {"setTextRightToLeft", lua_Slider_setTextRightToLeft},
         {"setValue", lua_Slider_setValue},
+        {"setValueTextAlignment", lua_Slider_setValueTextAlignment},
+        {"setValueTextPrecision", lua_Slider_setValueTextPrecision},
+        {"setValueTextVisible", lua_Slider_setValueTextVisible},
         {"setVisible", lua_Slider_setVisible},
         {"setWidth", lua_Slider_setWidth},
         {"setZIndex", lua_Slider_setZIndex},
@@ -2530,6 +2536,76 @@ int lua_Slider_getValue(lua_State* state)
     return 0;
 }
 
+int lua_Slider_getValueTextAlignment(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))
+            {
+                Slider* instance = getInstance(state);
+                Font::Justify result = instance->getValueTextAlignment();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_FontJustify(result));
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_getValueTextAlignment - 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_Slider_getValueTextPrecision(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))
+            {
+                Slider* instance = getInstance(state);
+                unsigned int result = instance->getValueTextPrecision();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_getValueTextPrecision - 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_Slider_getWidth(lua_State* state)
 {
     // Get the number of parameters.
@@ -2740,6 +2816,41 @@ int lua_Slider_isEnabled(lua_State* state)
     return 0;
 }
 
+int lua_Slider_isValueTextVisible(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))
+            {
+                Slider* instance = getInstance(state);
+                bool result = instance->isValueTextVisible();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Slider_isValueTextVisible - 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_Slider_isVisible(lua_State* state)
 {
     // Get the number of parameters.
@@ -4537,6 +4648,114 @@ int lua_Slider_setValue(lua_State* state)
     return 0;
 }
 
+int lua_Slider_setValueTextAlignment(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.
+                Font::Justify param1 = (Font::Justify)lua_enumFromString_FontJustify(luaL_checkstring(state, 2));
+
+                Slider* instance = getInstance(state);
+                instance->setValueTextAlignment(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Slider_setValueTextAlignment - 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_Slider_setValueTextPrecision(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);
+
+                Slider* instance = getInstance(state);
+                instance->setValueTextPrecision(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Slider_setValueTextPrecision - 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_Slider_setValueTextVisible(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = ScriptUtil::luaCheckBool(state, 2);
+
+                Slider* instance = getInstance(state);
+                instance->setValueTextVisible(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Slider_setValueTextVisible - 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_Slider_setVisible(lua_State* state)
 {
     // Get the number of parameters.

+ 6 - 0
gameplay/src/lua/lua_Slider.h

@@ -52,12 +52,15 @@ int lua_Slider_getTextColor(lua_State* state);
 int lua_Slider_getTextRightToLeft(lua_State* state);
 int lua_Slider_getType(lua_State* state);
 int lua_Slider_getValue(lua_State* state);
+int lua_Slider_getValueTextAlignment(lua_State* state);
+int lua_Slider_getValueTextPrecision(lua_State* state);
 int lua_Slider_getWidth(lua_State* state);
 int lua_Slider_getX(lua_State* state);
 int lua_Slider_getY(lua_State* state);
 int lua_Slider_getZIndex(lua_State* state);
 int lua_Slider_isContainer(lua_State* state);
 int lua_Slider_isEnabled(lua_State* state);
+int lua_Slider_isValueTextVisible(lua_State* state);
 int lua_Slider_isVisible(lua_State* state);
 int lua_Slider_release(lua_State* state);
 int lua_Slider_removeListener(lua_State* state);
@@ -95,6 +98,9 @@ int lua_Slider_setTextAlignment(lua_State* state);
 int lua_Slider_setTextColor(lua_State* state);
 int lua_Slider_setTextRightToLeft(lua_State* state);
 int lua_Slider_setValue(lua_State* state);
+int lua_Slider_setValueTextAlignment(lua_State* state);
+int lua_Slider_setValueTextPrecision(lua_State* state);
+int lua_Slider_setValueTextVisible(lua_State* state);
 int lua_Slider_setVisible(lua_State* state);
 int lua_Slider_setWidth(lua_State* state);
 int lua_Slider_setZIndex(lua_State* state);

+ 991 - 991
gameplay/src/lua/lua_Terrain.cpp

@@ -1,991 +1,991 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "lua_Terrain.h"
-#include "Animation.h"
-#include "AnimationTarget.h"
-#include "Base.h"
-#include "FileSystem.h"
-#include "Game.h"
-#include "Node.h"
-#include "Ref.h"
-#include "ScriptController.h"
-#include "ScriptTarget.h"
-#include "Terrain.h"
-#include "Transform.h"
-#include "lua_CurveInterpolationType.h"
-#include "lua_TerrainFlags.h"
-
-namespace gameplay
-{
-
-void luaRegister_Terrain()
-{
-    const luaL_Reg lua_members[] = 
-    {
-        {"addRef", lua_Terrain_addRef},
-        {"draw", lua_Terrain_draw},
-        {"getBoundingBox", lua_Terrain_getBoundingBox},
-        {"getHeight", lua_Terrain_getHeight},
-        {"getNode", lua_Terrain_getNode},
-        {"getPatchCount", lua_Terrain_getPatchCount},
-        {"getRefCount", lua_Terrain_getRefCount},
-        {"getTriangleCount", lua_Terrain_getTriangleCount},
-        {"getVisiblePatchCount", lua_Terrain_getVisiblePatchCount},
-        {"getVisibleTriangleCount", lua_Terrain_getVisibleTriangleCount},
-        {"isFlagSet", lua_Terrain_isFlagSet},
-        {"release", lua_Terrain_release},
-        {"setFlag", lua_Terrain_setFlag},
-        {"transformChanged", lua_Terrain_transformChanged},
-        {NULL, NULL}
-    };
-    const luaL_Reg lua_statics[] = 
-    {
-        {"create", lua_Terrain_static_create},
-        {NULL, NULL}
-    };
-    std::vector<std::string> scopePath;
-
-    ScriptUtil::registerClass("Terrain", lua_members, NULL, lua_Terrain__gc, lua_statics, scopePath);
-}
-
-static Terrain* getInstance(lua_State* state)
-{
-    void* userdata = luaL_checkudata(state, 1, "Terrain");
-    luaL_argcheck(state, userdata != NULL, 1, "'Terrain' expected.");
-    return (Terrain*)((ScriptUtil::LuaObject*)userdata)->instance;
-}
-
-int lua_Terrain__gc(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))
-            {
-                void* userdata = luaL_checkudata(state, 1, "Terrain");
-                luaL_argcheck(state, userdata != NULL, 1, "'Terrain' expected.");
-                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
-                if (object->owns)
-                {
-                    Terrain* instance = (Terrain*)object->instance;
-                    SAFE_RELEASE(instance);
-                }
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain__gc - 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_Terrain_addRef(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))
-            {
-                Terrain* instance = getInstance(state);
-                instance->addRef();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_addRef - 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_Terrain_draw(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))
-            {
-                Terrain* instance = getInstance(state);
-                instance->draw();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_draw - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 2:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                bool param1 = ScriptUtil::luaCheckBool(state, 2);
-
-                Terrain* instance = getInstance(state);
-                instance->draw(param1);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_draw - 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 or 2).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Terrain_getBoundingBox(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))
-            {
-                Terrain* instance = getInstance(state);
-                void* returnPtr = (void*)&(instance->getBoundingBox());
-                if (returnPtr)
-                {
-                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "BoundingBox");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getBoundingBox - 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_Terrain_getHeight(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TNUMBER &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                float param1 = (float)luaL_checknumber(state, 2);
-
-                // Get parameter 2 off the stack.
-                float param2 = (float)luaL_checknumber(state, 3);
-
-                Terrain* instance = getInstance(state);
-                float result = instance->getHeight(param1, param2);
-
-                // Push the return value onto the stack.
-                lua_pushnumber(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getHeight - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Terrain_getNode(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))
-            {
-                Terrain* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getNode();
-                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;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getNode - 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_Terrain_getPatchCount(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))
-            {
-                Terrain* instance = getInstance(state);
-                unsigned int result = instance->getPatchCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getPatchCount - 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_Terrain_getRefCount(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))
-            {
-                Terrain* instance = getInstance(state);
-                unsigned int result = instance->getRefCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getRefCount - 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_Terrain_getTriangleCount(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))
-            {
-                Terrain* instance = getInstance(state);
-                unsigned int result = instance->getTriangleCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getTriangleCount - 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_Terrain_getVisiblePatchCount(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))
-            {
-                Terrain* instance = getInstance(state);
-                unsigned int result = instance->getVisiblePatchCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getVisiblePatchCount - 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_Terrain_getVisibleTriangleCount(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))
-            {
-                Terrain* instance = getInstance(state);
-                unsigned int result = instance->getVisibleTriangleCount();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_getVisibleTriangleCount - 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_Terrain_isFlagSet(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.
-                Terrain::Flags param1 = (Terrain::Flags)lua_enumFromString_TerrainFlags(luaL_checkstring(state, 2));
-
-                Terrain* instance = getInstance(state);
-                bool result = instance->isFlagSet(param1);
-
-                // Push the return value onto the stack.
-                lua_pushboolean(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Terrain_isFlagSet - 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_Terrain_release(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))
-            {
-                Terrain* instance = getInstance(state);
-                instance->release();
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_release - 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_Terrain_setFlag(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TBOOLEAN)
-            {
-                // Get parameter 1 off the stack.
-                Terrain::Flags param1 = (Terrain::Flags)lua_enumFromString_TerrainFlags(luaL_checkstring(state, 2));
-
-                // Get parameter 2 off the stack.
-                bool param2 = ScriptUtil::luaCheckBool(state, 3);
-
-                Terrain* instance = getInstance(state);
-                instance->setFlag(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_setFlag - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Terrain_static_create(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:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    const char* param1 = ScriptUtil::getString(1, false);
-
-                    void* returnPtr = (void*)Terrain::create(param1);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<Properties> param1 = ScriptUtil::getObjectPointer<Properties>(1, "Properties", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    void* returnPtr = (void*)Terrain::create(param1);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    void* returnPtr = (void*)Terrain::create(param1);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 2:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
-                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    void* returnPtr = (void*)Terrain::create(param1, *param2);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 3:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
-                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
-                    lua_type(state, 3) == LUA_TNUMBER)
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    // Get parameter 3 off the stack.
-                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 4:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
-                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
-                    lua_type(state, 3) == LUA_TNUMBER &&
-                    lua_type(state, 4) == LUA_TNUMBER)
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    // Get parameter 3 off the stack.
-                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                    // Get parameter 4 off the stack.
-                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
-
-                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3, param4);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 5:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
-                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
-                    lua_type(state, 3) == LUA_TNUMBER &&
-                    lua_type(state, 4) == LUA_TNUMBER &&
-                    lua_type(state, 5) == LUA_TNUMBER)
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    // Get parameter 3 off the stack.
-                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                    // Get parameter 4 off the stack.
-                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
-
-                    // Get parameter 5 off the stack.
-                    float param5 = (float)luaL_checknumber(state, 5);
-
-                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3, param4, param5);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        case 6:
-        {
-            do
-            {
-                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
-                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
-                    lua_type(state, 3) == LUA_TNUMBER &&
-                    lua_type(state, 4) == LUA_TNUMBER &&
-                    lua_type(state, 5) == LUA_TNUMBER &&
-                    (lua_type(state, 6) == LUA_TSTRING || lua_type(state, 6) == LUA_TNIL))
-                {
-                    // Get parameter 1 off the stack.
-                    bool param1Valid;
-                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
-                    if (!param1Valid)
-                        break;
-
-                    // Get parameter 2 off the stack.
-                    bool param2Valid;
-                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
-                    if (!param2Valid)
-                        break;
-
-                    // Get parameter 3 off the stack.
-                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                    // Get parameter 4 off the stack.
-                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
-
-                    // Get parameter 5 off the stack.
-                    float param5 = (float)luaL_checknumber(state, 5);
-
-                    // Get parameter 6 off the stack.
-                    const char* param6 = ScriptUtil::getString(6, false);
-
-                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3, param4, param5, param6);
-                    if (returnPtr)
-                    {
-                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                        object->instance = returnPtr;
-                        object->owns = false;
-                        luaL_getmetatable(state, "Terrain");
-                        lua_setmetatable(state, -2);
-                    }
-                    else
-                    {
-                        lua_pushnil(state);
-                    }
-
-                    return 1;
-                }
-            } while (0);
-
-            lua_pushstring(state, "lua_Terrain_static_create - 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, 2, 3, 4, 5 or 6).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Terrain_transformChanged(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 3:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
-            {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                ScriptUtil::LuaArray<Transform> param1 = ScriptUtil::getObjectPointer<Transform>(2, "Transform", false, &param1Valid);
-                if (!param1Valid)
-                {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Transform'.");
-                    lua_error(state);
-                }
-
-                // Get parameter 2 off the stack.
-                long param2 = (long)luaL_checklong(state, 3);
-
-                Terrain* instance = getInstance(state);
-                instance->transformChanged(param1, param2);
-                
-                return 0;
-            }
-
-            lua_pushstring(state, "lua_Terrain_transformChanged - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-}
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_Terrain.h"
+#include "Animation.h"
+#include "AnimationTarget.h"
+#include "Base.h"
+#include "FileSystem.h"
+#include "Game.h"
+#include "Node.h"
+#include "Ref.h"
+#include "ScriptController.h"
+#include "ScriptTarget.h"
+#include "Terrain.h"
+#include "Transform.h"
+#include "lua_CurveInterpolationType.h"
+#include "lua_TerrainFlags.h"
+
+namespace gameplay
+{
+
+void luaRegister_Terrain()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"addRef", lua_Terrain_addRef},
+        {"draw", lua_Terrain_draw},
+        {"getBoundingBox", lua_Terrain_getBoundingBox},
+        {"getHeight", lua_Terrain_getHeight},
+        {"getNode", lua_Terrain_getNode},
+        {"getPatchCount", lua_Terrain_getPatchCount},
+        {"getRefCount", lua_Terrain_getRefCount},
+        {"getTriangleCount", lua_Terrain_getTriangleCount},
+        {"getVisiblePatchCount", lua_Terrain_getVisiblePatchCount},
+        {"getVisibleTriangleCount", lua_Terrain_getVisibleTriangleCount},
+        {"isFlagSet", lua_Terrain_isFlagSet},
+        {"release", lua_Terrain_release},
+        {"setFlag", lua_Terrain_setFlag},
+        {"transformChanged", lua_Terrain_transformChanged},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_Terrain_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("Terrain", lua_members, NULL, lua_Terrain__gc, lua_statics, scopePath);
+}
+
+static Terrain* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "Terrain");
+    luaL_argcheck(state, userdata != NULL, 1, "'Terrain' expected.");
+    return (Terrain*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_Terrain__gc(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))
+            {
+                void* userdata = luaL_checkudata(state, 1, "Terrain");
+                luaL_argcheck(state, userdata != NULL, 1, "'Terrain' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    Terrain* instance = (Terrain*)object->instance;
+                    SAFE_RELEASE(instance);
+                }
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain__gc - 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_Terrain_addRef(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))
+            {
+                Terrain* instance = getInstance(state);
+                instance->addRef();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_addRef - 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_Terrain_draw(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))
+            {
+                Terrain* instance = getInstance(state);
+                instance->draw();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_draw - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = ScriptUtil::luaCheckBool(state, 2);
+
+                Terrain* instance = getInstance(state);
+                instance->draw(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_draw - 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 or 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Terrain_getBoundingBox(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))
+            {
+                Terrain* instance = getInstance(state);
+                void* returnPtr = (void*)&(instance->getBoundingBox());
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "BoundingBox");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getBoundingBox - 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_Terrain_getHeight(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 3);
+
+                Terrain* instance = getInstance(state);
+                float result = instance->getHeight(param1, param2);
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Terrain_getNode(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))
+            {
+                Terrain* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getNode();
+                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;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getNode - 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_Terrain_getPatchCount(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))
+            {
+                Terrain* instance = getInstance(state);
+                unsigned int result = instance->getPatchCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getPatchCount - 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_Terrain_getRefCount(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))
+            {
+                Terrain* instance = getInstance(state);
+                unsigned int result = instance->getRefCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getRefCount - 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_Terrain_getTriangleCount(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))
+            {
+                Terrain* instance = getInstance(state);
+                unsigned int result = instance->getTriangleCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getTriangleCount - 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_Terrain_getVisiblePatchCount(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))
+            {
+                Terrain* instance = getInstance(state);
+                unsigned int result = instance->getVisiblePatchCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getVisiblePatchCount - 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_Terrain_getVisibleTriangleCount(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))
+            {
+                Terrain* instance = getInstance(state);
+                unsigned int result = instance->getVisibleTriangleCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_getVisibleTriangleCount - 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_Terrain_isFlagSet(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.
+                Terrain::Flags param1 = (Terrain::Flags)lua_enumFromString_TerrainFlags(luaL_checkstring(state, 2));
+
+                Terrain* instance = getInstance(state);
+                bool result = instance->isFlagSet(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Terrain_isFlagSet - 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_Terrain_release(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))
+            {
+                Terrain* instance = getInstance(state);
+                instance->release();
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_release - 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_Terrain_setFlag(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                Terrain::Flags param1 = (Terrain::Flags)lua_enumFromString_TerrainFlags(luaL_checkstring(state, 2));
+
+                // Get parameter 2 off the stack.
+                bool param2 = ScriptUtil::luaCheckBool(state, 3);
+
+                Terrain* instance = getInstance(state);
+                instance->setFlag(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_setFlag - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Terrain_static_create(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:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    const char* param1 = ScriptUtil::getString(1, false);
+
+                    void* returnPtr = (void*)Terrain::create(param1);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<Properties> param1 = ScriptUtil::getObjectPointer<Properties>(1, "Properties", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    void* returnPtr = (void*)Terrain::create(param1);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    void* returnPtr = (void*)Terrain::create(param1);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 2:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    void* returnPtr = (void*)Terrain::create(param1, *param2);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 4:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    lua_type(state, 4) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    // Get parameter 4 off the stack.
+                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                    void* returnPtr = (void*)Terrain::create(param1, *param2, param3, param4);
+                    if (returnPtr)
+                    {
+                        ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 5:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    lua_type(state, 4) == LUA_TNUMBER &&
+                    lua_type(state, 5) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    // Get parameter 4 off the stack.
+                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                    // Get parameter 5 off the stack.
+                    float param5 = (float)luaL_checknumber(state, 5);
+
+                    void* returnPtr = (void*)Terrain::create(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, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 6:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    lua_type(state, 4) == LUA_TNUMBER &&
+                    lua_type(state, 5) == LUA_TNUMBER &&
+                    (lua_type(state, 6) == LUA_TSTRING || lua_type(state, 6) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    ScriptUtil::LuaArray<HeightField> param1 = ScriptUtil::getObjectPointer<HeightField>(1, "HeightField", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    bool param2Valid;
+                    ScriptUtil::LuaArray<Vector3> param2 = ScriptUtil::getObjectPointer<Vector3>(2, "Vector3", true, &param2Valid);
+                    if (!param2Valid)
+                        break;
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    // Get parameter 4 off the stack.
+                    unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                    // Get parameter 5 off the stack.
+                    float param5 = (float)luaL_checknumber(state, 5);
+
+                    // Get parameter 6 off the stack.
+                    const char* param6 = ScriptUtil::getString(6, false);
+
+                    void* returnPtr = (void*)Terrain::create(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, "Terrain");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Terrain_static_create - 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, 2, 3, 4, 5 or 6).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Terrain_transformChanged(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                ScriptUtil::LuaArray<Transform> param1 = ScriptUtil::getObjectPointer<Transform>(2, "Transform", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Transform'.");
+                    lua_error(state);
+                }
+
+                // Get parameter 2 off the stack.
+                long param2 = (long)luaL_checklong(state, 3);
+
+                Terrain* instance = getInstance(state);
+                instance->transformChanged(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Terrain_transformChanged - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 10 - 10
gameplay/src/lua/lua_TerrainFlags.cpp

@@ -7,17 +7,17 @@ namespace gameplay
 static const char* enumStringEmpty = "";
 
 static const char* luaEnumString_TerrainFlags_DEBUG_PATCHES = "DEBUG_PATCHES";
-static const char* luaEnumString_TerrainFlags_ENABLE_FRUSTUM_CULLING = "ENABLE_FRUSTUM_CULLING";
-static const char* luaEnumString_TerrainFlags_ENABLE_LEVEL_OF_DETAIL = "ENABLE_LEVEL_OF_DETAIL";
+static const char* luaEnumString_TerrainFlags_FRUSTUM_CULLING = "FRUSTUM_CULLING";
+static const char* luaEnumString_TerrainFlags_LEVEL_OF_DETAIL = "LEVEL_OF_DETAIL";
 
 Terrain::Flags lua_enumFromString_TerrainFlags(const char* s)
 {
     if (strcmp(s, luaEnumString_TerrainFlags_DEBUG_PATCHES) == 0)
         return Terrain::DEBUG_PATCHES;
-    if (strcmp(s, luaEnumString_TerrainFlags_ENABLE_FRUSTUM_CULLING) == 0)
-        return Terrain::ENABLE_FRUSTUM_CULLING;
-    if (strcmp(s, luaEnumString_TerrainFlags_ENABLE_LEVEL_OF_DETAIL) == 0)
-        return Terrain::ENABLE_LEVEL_OF_DETAIL;
+    if (strcmp(s, luaEnumString_TerrainFlags_FRUSTUM_CULLING) == 0)
+        return Terrain::FRUSTUM_CULLING;
+    if (strcmp(s, luaEnumString_TerrainFlags_LEVEL_OF_DETAIL) == 0)
+        return Terrain::LEVEL_OF_DETAIL;
     GP_ERROR("Invalid enumeration value '%s' for enumeration Terrain::Flags.", s);
     return Terrain::DEBUG_PATCHES;
 }
@@ -26,10 +26,10 @@ const char* lua_stringFromEnum_TerrainFlags(Terrain::Flags e)
 {
     if (e == Terrain::DEBUG_PATCHES)
         return luaEnumString_TerrainFlags_DEBUG_PATCHES;
-    if (e == Terrain::ENABLE_FRUSTUM_CULLING)
-        return luaEnumString_TerrainFlags_ENABLE_FRUSTUM_CULLING;
-    if (e == Terrain::ENABLE_LEVEL_OF_DETAIL)
-        return luaEnumString_TerrainFlags_ENABLE_LEVEL_OF_DETAIL;
+    if (e == Terrain::FRUSTUM_CULLING)
+        return luaEnumString_TerrainFlags_FRUSTUM_CULLING;
+    if (e == Terrain::LEVEL_OF_DETAIL)
+        return luaEnumString_TerrainFlags_LEVEL_OF_DETAIL;
     GP_ERROR("Invalid enumeration value '%d' for enumeration Terrain::Flags.", e);
     return enumStringEmpty;
 }