Browse Source

Added new Logger class to handle info, warning and error logging throughout the framework.
By default logging behaves exactly as it did before, but it can now be customized to register log callbacks (C or Lua) for logging to custom outputs.
The GP_WARN and GP_ERROR macros now call Logger::log.

Steve Grenier 13 years ago
parent
commit
9b7650fd7b

+ 9 - 6
gameplay/android/jni/Android.mk

@@ -59,6 +59,7 @@ LOCAL_SRC_FILES := \
     Label.cpp \
     Layout.cpp \
     Light.cpp \
+    Logger.cpp \
     Material.cpp \
     MaterialParameter.cpp \
     MathUtil.cpp \
@@ -83,8 +84,8 @@ LOCAL_SRC_FILES := \
     PhysicsRigidBody.cpp \
     PhysicsSocketConstraint.cpp \
     PhysicsSpringConstraint.cpp \
-	PhysicsVehicle.cpp \
-	PhysicsVehicleWheel.cpp \
+    PhysicsVehicle.cpp \
+    PhysicsVehicleWheel.cpp \
     Plane.cpp \
     PlatformAndroid.cpp \
     Properties.cpp \
@@ -170,8 +171,8 @@ LOCAL_SRC_FILES := \
     lua/lua_GamepadButtonState.cpp \
     lua/lua_GamepadGamepadEvent.cpp \
     lua/lua_GameState.cpp \
-	lua/lua_Gesture.cpp \
-	lua/lua_GestureGestureEvent.cpp \
+    lua/lua_Gesture.cpp \
+    lua/lua_GestureGestureEvent.cpp \
     lua/lua_Global.cpp \
     lua/lua_Image.cpp \
     lua/lua_ImageFormat.cpp \
@@ -185,6 +186,8 @@ LOCAL_SRC_FILES := \
     lua/lua_LayoutType.cpp \
     lua/lua_Light.cpp \
     lua/lua_LightType.cpp \
+    lua/lua_Logger.cpp \
+    lua/lua_LoggerLevel.cpp \
     lua/lua_Material.cpp \
     lua/lua_MaterialParameter.cpp \
     lua/lua_MathUtil.cpp \
@@ -227,8 +230,8 @@ LOCAL_SRC_FILES := \
     lua/lua_PhysicsRigidBodyParameters.cpp \
     lua/lua_PhysicsSocketConstraint.cpp \
     lua/lua_PhysicsSpringConstraint.cpp \
-	lua/lua_PhysicsVehicle.cpp \
-	lua/lua_PhysicsVehicleWheel.cpp \
+    lua/lua_PhysicsVehicle.cpp \
+    lua/lua_PhysicsVehicleWheel.cpp \
     lua/lua_Plane.cpp \
     lua/lua_Platform.cpp \
     lua/lua_Properties.cpp \

+ 6 - 0
gameplay/gameplay.vcxproj

@@ -82,6 +82,7 @@
     <ClCompile Include="src\Label.cpp" />
     <ClCompile Include="src\Layout.cpp" />
     <ClCompile Include="src\Light.cpp" />
+    <ClCompile Include="src\Logger.cpp" />
     <ClCompile Include="src\lua\lua_AbsoluteLayout.cpp" />
     <ClCompile Include="src\lua\lua_AIAgent.cpp" />
     <ClCompile Include="src\lua\lua_AIAgentListener.cpp" />
@@ -153,6 +154,8 @@
     <ClCompile Include="src\lua\lua_LayoutType.cpp" />
     <ClCompile Include="src\lua\lua_Light.cpp" />
     <ClCompile Include="src\lua\lua_LightType.cpp" />
+    <ClCompile Include="src\lua\lua_Logger.cpp" />
+    <ClCompile Include="src\lua\lua_LoggerLevel.cpp" />
     <ClCompile Include="src\lua\lua_Material.cpp" />
     <ClCompile Include="src\lua\lua_MaterialParameter.cpp" />
     <ClCompile Include="src\lua\lua_MathUtil.cpp" />
@@ -348,6 +351,7 @@
     <ClInclude Include="src\Label.h" />
     <ClInclude Include="src\Layout.h" />
     <ClInclude Include="src\Light.h" />
+    <ClInclude Include="src\Logger.h" />
     <ClInclude Include="src\lua\lua_AbsoluteLayout.h" />
     <ClInclude Include="src\lua\lua_AIAgent.h" />
     <ClInclude Include="src\lua\lua_AIAgentListener.h" />
@@ -419,6 +423,8 @@
     <ClInclude Include="src\lua\lua_LayoutType.h" />
     <ClInclude Include="src\lua\lua_Light.h" />
     <ClInclude Include="src\lua\lua_LightType.h" />
+    <ClInclude Include="src\lua\lua_Logger.h" />
+    <ClInclude Include="src\lua\lua_LoggerLevel.h" />
     <ClInclude Include="src\lua\lua_Material.h" />
     <ClInclude Include="src\lua\lua_MaterialParameter.h" />
     <ClInclude Include="src\lua\lua_MathUtil.h" />

+ 18 - 0
gameplay/gameplay.vcxproj.filters

@@ -807,6 +807,15 @@
     <ClCompile Include="src\MathUtil.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\Logger.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_LoggerLevel.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_Logger.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
@@ -1601,6 +1610,15 @@
     <ClInclude Include="src\lua\lua_PhysicsVehicleWheel.h">
       <Filter>lua</Filter>
     </ClInclude>
+    <ClInclude Include="src\Logger.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_Logger.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_LoggerLevel.h">
+      <Filter>lua</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\gameplay-main-macosx.mm">

+ 7 - 7
gameplay/src/Base.h

@@ -25,6 +25,7 @@
 #include <limits>
 #include <functional>
 #include <bitset>
+#include "Logger.h"
 
 // Bring common functions from C into global namespace
 using std::memcpy;
@@ -42,7 +43,6 @@ using std::min;
 using std::max;
 using std::modf;
 
-
 // Common
 #ifndef NULL
 #define NULL     0
@@ -77,9 +77,9 @@ extern void print(const char* format, ...);
 #else
 #define GP_ERROR(...) do \
     { \
-        gameplay::print("%s -- ", __current__func__); \
-        gameplay::print(__VA_ARGS__); \
-        gameplay::print("\n"); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, "%s -- ", __current__func__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, __VA_ARGS__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_ERROR, "\n"); \
         assert(0); \
         std::exit(-1); \
     } while (0)
@@ -88,9 +88,9 @@ extern void print(const char* format, ...);
 // Warning macro.
 #define GP_WARN(...) do \
     { \
-        gameplay::print("%s -- ", __current__func__); \
-        gameplay::print(__VA_ARGS__); \
-        gameplay::print("\n"); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "%s -- ", __current__func__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, __VA_ARGS__); \
+        gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "\n"); \
     } while (0)
 
 // Bullet Physics

+ 99 - 0
gameplay/src/Logger.cpp

@@ -0,0 +1,99 @@
+#include "Base.h"
+#include "Game.h"
+#include "ScriptController.h"
+
+namespace gameplay
+{
+
+Logger::State Logger::_state[3];
+
+Logger::State::State() : logFunctionC(NULL), logFunctionLua(NULL), enabled(true)
+{
+}
+
+Logger::Logger()
+{
+}
+
+Logger::~Logger()
+{
+}
+
+void Logger::log(Level level, const char* message, ...)
+{
+    State& state = _state[level];
+    if (!state.enabled)
+        return;
+
+    va_list args;
+    va_start(args, message);
+
+    // Declare a moderately sized buffer on the stack that should be
+    // large enough to accomodate most log requests.
+    int size = 1024;
+    char stackBuffer[1024];
+    std::vector<char> dynamicBuffer;
+    char* str = stackBuffer;
+    for ( ; ; )
+    {
+        // Pass one less than size to leave room for NULL terminator
+        int needed = vsnprintf(str, size-1, message, args);
+
+        // NOTE: Some platforms return -1 when vsnprintf runs out of room, while others return
+        // the number of characters actually needed to fill the buffer.
+        if (needed >= 0 && needed < size)
+        {
+            // Successfully wrote buffer. Added a NULL terminator in case it wasn't written.
+            str[needed] = '\0';
+            break;
+        }
+
+        size = needed > 0 ? (needed + 1) : (size * 2);
+        dynamicBuffer.resize(size);
+        str = &dynamicBuffer[0];
+    }
+
+    if (state.logFunctionC)
+    {
+        // Pass call to registered C log function
+        (*state.logFunctionC)(level, str);
+    }
+    else if (state.logFunctionLua)
+    {
+        // Pass call to registered Lua log function
+        Game::getInstance()->getScriptController()->executeFunction<void>(state.logFunctionLua, "[Logger::Level]s", level, str);
+    }
+    else
+    {
+        // Log to the default output
+        gameplay::print(str);
+    }
+
+    va_end(args);
+}
+
+bool Logger::isEnabled(Level level)
+{
+    return _state[level].enabled;
+}
+
+void Logger::setEnabled(Level level, bool enabled)
+{
+    _state[level].enabled = enabled;
+}
+
+void Logger::set(Level level, void (*logFunction) (Level, const char*))
+{
+    State& state = _state[level];
+    state.logFunctionC = logFunction;
+    state.logFunctionLua = NULL;
+}
+
+void Logger::set(Level level, const char* logFunction)
+{
+    State& state = _state[level];
+    state.logFunctionLua = logFunction;
+    state.logFunctionC = NULL;
+}
+
+}

+ 124 - 0
gameplay/src/Logger.h

@@ -0,0 +1,124 @@
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+namespace gameplay
+{
+
+/**
+ * Provides a basic logging system for the game.
+ *
+ * By default, this class logs messages using the gameplay::print function, which
+ * is implemented in a platform dependent manner and typically prints to stderr
+ * as well as to other possibly platform specific locations. Logging behavior
+ * can be modified for a specific log level by passing a custom C or Lua logging
+ * function to the Logger::set method. Logging can also be toggled using the
+ * setEnabled method.
+ */
+class Logger
+{
+public:
+
+    /** 
+     * Enumeration of valid log levels.
+     */
+    enum Level
+    {
+        LEVEL_INFO = 0,
+        LEVEL_WARN = 1,
+        LEVEL_ERROR = 2
+    };
+
+    /**
+     * Logs a message at the specified log level.
+     *
+     * This method accepts a variable argument list with the same formatting specification
+     * as printf. Therefore, the message parameter can include any format specifiers that
+     * are supported by printf.
+     *
+     * @param level Log level.
+     * @param message Log message.
+     */
+    static void log(Level level, const char* message, ...);
+
+    /**
+     * Determines if logging is currently enabled for the given level.
+     *
+     * @param level Log level.
+     *
+     * @return True if logging is enabled for this level, or false if it is disabled.
+     */
+    static bool isEnabled(Level level);
+
+    /**
+     * Enables or disables logging at the given level.
+     *
+     * @param level Log level to enable or disable.
+     * @param enabled True to enable the logger for the given level, false to disable it.
+     */
+    static void setEnabled(Level level, bool enabled);
+
+    /**
+     * Sets a C callback function to handle logging requests for the specified
+     * log level.
+     *
+     * When a call to log is made with the given level, the specified C function will
+     * be called to handle the request.
+     *
+     * Passing NULL for logFunction restores the default log behavior for this level.
+     *
+     * @param level Log level to set logging callback for.
+     * @param logFunction Pointer to a C function to call for each log request at the given log level.
+     * @script{ignore}
+     */
+    static void set(Level level, void (*logFunction) (Level, const char*));
+
+    /**
+     * Sets a Lua function as the log handler for the specified log level.
+     *
+     * When a call to log is made with the given level, the specified 
+     * Lua function will be called to handle the request.
+     *
+     * Passing NULL for logFunction restores the default log behavior for this level.
+     *
+     * @param level Log level.
+     * @param logFunction The Lua function to call for each log request at the given log level.
+     */
+    static void set(Level level, const char* logFunction);
+
+private:
+
+    struct State
+    {
+        State();
+        void (*logFunctionC) (Level, const char*);
+        const char* logFunctionLua;
+        bool enabled;
+    };
+
+    /**
+     * Hidden constructor.
+     */
+    Logger();
+
+    /**
+     * Hidden destructor.
+     */
+    ~Logger();
+
+    /**
+     * Hidden copy constructor.
+     */
+    Logger(const Logger& copy);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    Logger& operator=(const Logger&);
+
+    static State _state[3];
+
+};
+
+}
+
+#endif

+ 1 - 0
gameplay/src/gameplay.h

@@ -10,6 +10,7 @@
 #include "FileSystem.h"
 #include "Bundle.h"
 #include "MathUtil.h"
+#include "Logger.h"
 
 // Math
 #include "Rectangle.h"

+ 11 - 0
gameplay/src/lua/lua_Global.cpp

@@ -565,6 +565,15 @@ void luaRegister_lua_Global()
         ScriptUtil::registerConstantString("SPOT", "SPOT", scopePath);
     }
 
+    // Register enumeration Logger::Level.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("Logger");
+        ScriptUtil::registerConstantString("INFO", "INFO", scopePath);
+        ScriptUtil::registerConstantString("WARN", "WARN", scopePath);
+        ScriptUtil::registerConstantString("ERROR", "ERROR", scopePath);
+    }
+
     // Register enumeration Mesh::IndexFormat.
     {
         std::vector<std::string> scopePath;
@@ -824,6 +833,8 @@ const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value)
         return lua_stringFromEnum_LayoutType((Layout::Type)value);
     if (enumname == "Light::Type")
         return lua_stringFromEnum_LightType((Light::Type)value);
+    if (enumname == "Logger::Level")
+        return lua_stringFromEnum_LoggerLevel((Logger::Level)value);
     if (enumname == "Mesh::IndexFormat")
         return lua_stringFromEnum_MeshIndexFormat((Mesh::IndexFormat)value);
     if (enumname == "Mesh::PrimitiveType")

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

@@ -23,6 +23,7 @@
 #include "lua_KeyboardKeyEvent.h"
 #include "lua_LayoutType.h"
 #include "lua_LightType.h"
+#include "lua_LoggerLevel.h"
 #include "lua_MeshIndexFormat.h"
 #include "lua_MeshPrimitiveType.h"
 #include "lua_MouseMouseEvent.h"

+ 195 - 0
gameplay/src/lua/lua_Logger.cpp

@@ -0,0 +1,195 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_Logger.h"
+#include "Base.h"
+#include "Game.h"
+#include "Logger.h"
+#include "ScriptController.h"
+#include "lua_LoggerLevel.h"
+
+namespace gameplay
+{
+
+void luaRegister_Logger()
+{
+    const luaL_Reg* lua_members = NULL;
+    const luaL_Reg lua_statics[] = 
+    {
+        {"isEnabled", lua_Logger_static_isEnabled},
+        {"log", lua_Logger_static_log},
+        {"set", lua_Logger_static_set},
+        {"setEnabled", lua_Logger_static_setEnabled},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("Logger", lua_members, NULL, NULL, lua_statics, scopePath);
+}
+
+static Logger* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "Logger");
+    luaL_argcheck(state, userdata != NULL, 1, "'Logger' expected.");
+    return (Logger*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_Logger_static_isEnabled(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_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Logger::Level param1 = (Logger::Level)lua_enumFromString_LoggerLevel(luaL_checkstring(state, 1));
+
+                bool result = Logger::isEnabled(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Logger_static_isEnabled - 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_Logger_static_log(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_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Logger::Level param1 = (Logger::Level)lua_enumFromString_LoggerLevel(luaL_checkstring(state, 1));
+
+                // Get parameter 2 off the stack.
+                ScriptUtil::LuaArray<const char> param2 = ScriptUtil::getString(2, false);
+
+                Logger::log(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Logger_static_log - 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_Logger_static_set(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_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Logger::Level param1 = (Logger::Level)lua_enumFromString_LoggerLevel(luaL_checkstring(state, 1));
+
+                // Get parameter 2 off the stack.
+                ScriptUtil::LuaArray<const char> param2 = ScriptUtil::getString(2, false);
+
+                Logger::set(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Logger_static_set - 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_Logger_static_setEnabled(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_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                Logger::Level param1 = (Logger::Level)lua_enumFromString_LoggerLevel(luaL_checkstring(state, 1));
+
+                // Get parameter 2 off the stack.
+                bool param2 = ScriptUtil::luaCheckBool(state, 2);
+
+                Logger::setEnabled(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Logger_static_setEnabled - 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;
+}
+
+}

+ 17 - 0
gameplay/src/lua/lua_Logger.h

@@ -0,0 +1,17 @@
+#ifndef LUA_LOGGER_H_
+#define LUA_LOGGER_H_
+
+namespace gameplay
+{
+
+// Lua bindings for Logger.
+int lua_Logger_static_isEnabled(lua_State* state);
+int lua_Logger_static_log(lua_State* state);
+int lua_Logger_static_set(lua_State* state);
+int lua_Logger_static_setEnabled(lua_State* state);
+
+void luaRegister_Logger();
+
+}
+
+#endif

+ 38 - 0
gameplay/src/lua/lua_LoggerLevel.cpp

@@ -0,0 +1,38 @@
+#include "Base.h"
+#include "lua_LoggerLevel.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_LoggerLevel_LEVEL_INFO = "LEVEL_INFO";
+static const char* luaEnumString_LoggerLevel_LEVEL_WARN = "LEVEL_WARN";
+static const char* luaEnumString_LoggerLevel_LEVEL_ERROR = "LEVEL_ERROR";
+
+Logger::Level lua_enumFromString_LoggerLevel(const char* s)
+{
+    if (strcmp(s, luaEnumString_LoggerLevel_LEVEL_INFO) == 0)
+        return Logger::LEVEL_INFO;
+    if (strcmp(s, luaEnumString_LoggerLevel_LEVEL_WARN) == 0)
+        return Logger::LEVEL_WARN;
+    if (strcmp(s, luaEnumString_LoggerLevel_LEVEL_ERROR) == 0)
+        return Logger::LEVEL_ERROR;
+    GP_ERROR("Invalid enumeration value '%s' for enumeration Logger::Level.", s);
+    return Logger::LEVEL_INFO;
+}
+
+const char* lua_stringFromEnum_LoggerLevel(Logger::Level e)
+{
+    if (e == Logger::LEVEL_INFO)
+        return luaEnumString_LoggerLevel_LEVEL_INFO;
+    if (e == Logger::LEVEL_WARN)
+        return luaEnumString_LoggerLevel_LEVEL_WARN;
+    if (e == Logger::LEVEL_ERROR)
+        return luaEnumString_LoggerLevel_LEVEL_ERROR;
+    GP_ERROR("Invalid enumeration value '%d' for enumeration Logger::Level.", e);
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_LoggerLevel.h

@@ -0,0 +1,15 @@
+#ifndef LUA_LOGGERLEVEL_H_
+#define LUA_LOGGERLEVEL_H_
+
+#include "Logger.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for Logger::Level.
+Logger::Level lua_enumFromString_LoggerLevel(const char* s);
+const char* lua_stringFromEnum_LoggerLevel(Logger::Level e);
+
+}
+
+#endif

+ 654 - 27
gameplay/src/lua/lua_PhysicsVehicle.cpp

@@ -3,6 +3,7 @@
 #include "lua_PhysicsVehicle.h"
 #include "Base.h"
 #include "Game.h"
+#include "MathUtil.h"
 #include "Node.h"
 #include "PhysicsCollisionObject.h"
 #include "PhysicsController.h"
@@ -23,14 +24,24 @@ void luaRegister_PhysicsVehicle()
         {"addCollisionListener", lua_PhysicsVehicle_addCollisionListener},
         {"addWheel", lua_PhysicsVehicle_addWheel},
         {"collidesWith", lua_PhysicsVehicle_collidesWith},
+        {"getBoostGain", lua_PhysicsVehicle_getBoostGain},
+        {"getBoostSpeed", lua_PhysicsVehicle_getBoostSpeed},
+        {"getBrakedownFull", lua_PhysicsVehicle_getBrakedownFull},
+        {"getBrakedownStart", lua_PhysicsVehicle_getBrakedownStart},
         {"getBrakingForce", lua_PhysicsVehicle_getBrakingForce},
         {"getCollisionShape", lua_PhysicsVehicle_getCollisionShape},
+        {"getDownforce", lua_PhysicsVehicle_getDownforce},
+        {"getDrivedownFull", lua_PhysicsVehicle_getDrivedownFull},
+        {"getDrivedownStart", lua_PhysicsVehicle_getDrivedownStart},
         {"getDrivingForce", lua_PhysicsVehicle_getDrivingForce},
         {"getNode", lua_PhysicsVehicle_getNode},
         {"getNumWheels", lua_PhysicsVehicle_getNumWheels},
         {"getRigidBody", lua_PhysicsVehicle_getRigidBody},
         {"getShapeType", lua_PhysicsVehicle_getShapeType},
         {"getSpeedKph", lua_PhysicsVehicle_getSpeedKph},
+        {"getSpeedSmoothKph", lua_PhysicsVehicle_getSpeedSmoothKph},
+        {"getSteerdownGain", lua_PhysicsVehicle_getSteerdownGain},
+        {"getSteerdownSpeed", lua_PhysicsVehicle_getSteerdownSpeed},
         {"getSteeringGain", lua_PhysicsVehicle_getSteeringGain},
         {"getType", lua_PhysicsVehicle_getType},
         {"getWheel", lua_PhysicsVehicle_getWheel},
@@ -38,9 +49,15 @@ void luaRegister_PhysicsVehicle()
         {"isEnabled", lua_PhysicsVehicle_isEnabled},
         {"isKinematic", lua_PhysicsVehicle_isKinematic},
         {"removeCollisionListener", lua_PhysicsVehicle_removeCollisionListener},
+        {"reset", lua_PhysicsVehicle_reset},
+        {"setBoost", lua_PhysicsVehicle_setBoost},
+        {"setBrakedown", lua_PhysicsVehicle_setBrakedown},
         {"setBrakingForce", lua_PhysicsVehicle_setBrakingForce},
+        {"setDownforce", lua_PhysicsVehicle_setDownforce},
+        {"setDrivedown", lua_PhysicsVehicle_setDrivedown},
         {"setDrivingForce", lua_PhysicsVehicle_setDrivingForce},
         {"setEnabled", lua_PhysicsVehicle_setEnabled},
+        {"setSteerdown", lua_PhysicsVehicle_setSteerdown},
         {"setSteeringGain", lua_PhysicsVehicle_setSteeringGain},
         {"update", lua_PhysicsVehicle_update},
         {NULL, NULL}
@@ -225,6 +242,154 @@ int lua_PhysicsVehicle_collidesWith(lua_State* state)
     return 0;
 }
 
+int lua_PhysicsVehicle_getBoostGain(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getBoostGain();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getBoostGain - 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_PhysicsVehicle_getBoostSpeed(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getBoostSpeed();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getBoostSpeed - 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_PhysicsVehicle_getBrakedownFull(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getBrakedownFull();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getBrakedownFull - 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_PhysicsVehicle_getBrakedownStart(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getBrakedownStart();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getBrakedownStart - 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_PhysicsVehicle_getBrakingForce(lua_State* state)
 {
     // Get the number of parameters.
@@ -308,6 +473,117 @@ int lua_PhysicsVehicle_getCollisionShape(lua_State* state)
     return 0;
 }
 
+int lua_PhysicsVehicle_getDownforce(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getDownforce();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getDownforce - 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_PhysicsVehicle_getDrivedownFull(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getDrivedownFull();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getDrivedownFull - 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_PhysicsVehicle_getDrivedownStart(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                float result = instance->getDrivedownStart();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getDrivedownStart - 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_PhysicsVehicle_getDrivingForce(lua_State* state)
 {
     // Get the number of parameters.
@@ -376,7 +652,127 @@ int lua_PhysicsVehicle_getNode(lua_State* state)
             }
             else
             {
-                lua_pushstring(state, "lua_PhysicsVehicle_getNode - Failed to match the given parameters to a valid function signature.");
+                lua_pushstring(state, "lua_PhysicsVehicle_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_PhysicsVehicle_getNumWheels(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                unsigned int result = instance->getNumWheels();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getNumWheels - 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_PhysicsVehicle_getRigidBody(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getRigidBody();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "PhysicsRigidBody");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getRigidBody - 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_PhysicsVehicle_getShapeType(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                PhysicsCollisionShape::Type result = instance->getShapeType();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_PhysicsCollisionShapeType(result));
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_getShapeType - Failed to match the given parameters to a valid function signature.");
                 lua_error(state);
             }
             break;
@@ -391,7 +787,7 @@ int lua_PhysicsVehicle_getNode(lua_State* state)
     return 0;
 }
 
-int lua_PhysicsVehicle_getNumWheels(lua_State* state)
+int lua_PhysicsVehicle_getSpeedKph(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -404,16 +800,16 @@ int lua_PhysicsVehicle_getNumWheels(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 PhysicsVehicle* instance = getInstance(state);
-                unsigned int result = instance->getNumWheels();
+                float result = instance->getSpeedKph();
 
                 // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
+                lua_pushnumber(state, result);
 
                 return 1;
             }
             else
             {
-                lua_pushstring(state, "lua_PhysicsVehicle_getNumWheels - Failed to match the given parameters to a valid function signature.");
+                lua_pushstring(state, "lua_PhysicsVehicle_getSpeedKph - Failed to match the given parameters to a valid function signature.");
                 lua_error(state);
             }
             break;
@@ -428,7 +824,7 @@ int lua_PhysicsVehicle_getNumWheels(lua_State* state)
     return 0;
 }
 
-int lua_PhysicsVehicle_getRigidBody(lua_State* state)
+int lua_PhysicsVehicle_getSpeedSmoothKph(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -441,25 +837,16 @@ int lua_PhysicsVehicle_getRigidBody(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 PhysicsVehicle* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getRigidBody();
-                if (returnPtr)
-                {
-                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "PhysicsRigidBody");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
+                float result = instance->getSpeedSmoothKph();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
 
                 return 1;
             }
             else
             {
-                lua_pushstring(state, "lua_PhysicsVehicle_getRigidBody - Failed to match the given parameters to a valid function signature.");
+                lua_pushstring(state, "lua_PhysicsVehicle_getSpeedSmoothKph - Failed to match the given parameters to a valid function signature.");
                 lua_error(state);
             }
             break;
@@ -474,7 +861,7 @@ int lua_PhysicsVehicle_getRigidBody(lua_State* state)
     return 0;
 }
 
-int lua_PhysicsVehicle_getShapeType(lua_State* state)
+int lua_PhysicsVehicle_getSteerdownGain(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -487,16 +874,16 @@ int lua_PhysicsVehicle_getShapeType(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 PhysicsVehicle* instance = getInstance(state);
-                PhysicsCollisionShape::Type result = instance->getShapeType();
+                float result = instance->getSteerdownGain();
 
                 // Push the return value onto the stack.
-                lua_pushstring(state, lua_stringFromEnum_PhysicsCollisionShapeType(result));
+                lua_pushnumber(state, result);
 
                 return 1;
             }
             else
             {
-                lua_pushstring(state, "lua_PhysicsVehicle_getShapeType - Failed to match the given parameters to a valid function signature.");
+                lua_pushstring(state, "lua_PhysicsVehicle_getSteerdownGain - Failed to match the given parameters to a valid function signature.");
                 lua_error(state);
             }
             break;
@@ -511,7 +898,7 @@ int lua_PhysicsVehicle_getShapeType(lua_State* state)
     return 0;
 }
 
-int lua_PhysicsVehicle_getSpeedKph(lua_State* state)
+int lua_PhysicsVehicle_getSteerdownSpeed(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -524,7 +911,7 @@ int lua_PhysicsVehicle_getSpeedKph(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 PhysicsVehicle* instance = getInstance(state);
-                float result = instance->getSpeedKph();
+                float result = instance->getSteerdownSpeed();
 
                 // Push the return value onto the stack.
                 lua_pushnumber(state, result);
@@ -533,7 +920,7 @@ int lua_PhysicsVehicle_getSpeedKph(lua_State* state)
             }
             else
             {
-                lua_pushstring(state, "lua_PhysicsVehicle_getSpeedKph - Failed to match the given parameters to a valid function signature.");
+                lua_pushstring(state, "lua_PhysicsVehicle_getSteerdownSpeed - Failed to match the given parameters to a valid function signature.");
                 lua_error(state);
             }
             break;
@@ -871,6 +1258,124 @@ int lua_PhysicsVehicle_removeCollisionListener(lua_State* state)
     return 0;
 }
 
+int lua_PhysicsVehicle_reset(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))
+            {
+                PhysicsVehicle* instance = getInstance(state);
+                instance->reset();
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_reset - 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_PhysicsVehicle_setBoost(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);
+
+                PhysicsVehicle* instance = getInstance(state);
+                instance->setBoost(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_setBoost - 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_PhysicsVehicle_setBrakedown(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);
+
+                PhysicsVehicle* instance = getInstance(state);
+                instance->setBrakedown(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_setBrakedown - 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_PhysicsVehicle_setBrakingForce(lua_State* state)
 {
     // Get the number of parameters.
@@ -909,6 +1414,86 @@ int lua_PhysicsVehicle_setBrakingForce(lua_State* state)
     return 0;
 }
 
+int lua_PhysicsVehicle_setDownforce(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.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                PhysicsVehicle* instance = getInstance(state);
+                instance->setDownforce(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_setDownforce - 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_PhysicsVehicle_setDrivedown(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);
+
+                PhysicsVehicle* instance = getInstance(state);
+                instance->setDrivedown(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_setDrivedown - 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_PhysicsVehicle_setDrivingForce(lua_State* state)
 {
     // Get the number of parameters.
@@ -985,6 +1570,48 @@ int lua_PhysicsVehicle_setEnabled(lua_State* state)
     return 0;
 }
 
+int lua_PhysicsVehicle_setSteerdown(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);
+
+                PhysicsVehicle* instance = getInstance(state);
+                instance->setSteerdown(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_PhysicsVehicle_setSteerdown - 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_PhysicsVehicle_setSteeringGain(lua_State* state)
 {
     // Get the number of parameters.

+ 16 - 0
gameplay/src/lua/lua_PhysicsVehicle.h

@@ -8,14 +8,24 @@ namespace gameplay
 int lua_PhysicsVehicle_addCollisionListener(lua_State* state);
 int lua_PhysicsVehicle_addWheel(lua_State* state);
 int lua_PhysicsVehicle_collidesWith(lua_State* state);
+int lua_PhysicsVehicle_getBoostGain(lua_State* state);
+int lua_PhysicsVehicle_getBoostSpeed(lua_State* state);
+int lua_PhysicsVehicle_getBrakedownFull(lua_State* state);
+int lua_PhysicsVehicle_getBrakedownStart(lua_State* state);
 int lua_PhysicsVehicle_getBrakingForce(lua_State* state);
 int lua_PhysicsVehicle_getCollisionShape(lua_State* state);
+int lua_PhysicsVehicle_getDownforce(lua_State* state);
+int lua_PhysicsVehicle_getDrivedownFull(lua_State* state);
+int lua_PhysicsVehicle_getDrivedownStart(lua_State* state);
 int lua_PhysicsVehicle_getDrivingForce(lua_State* state);
 int lua_PhysicsVehicle_getNode(lua_State* state);
 int lua_PhysicsVehicle_getNumWheels(lua_State* state);
 int lua_PhysicsVehicle_getRigidBody(lua_State* state);
 int lua_PhysicsVehicle_getShapeType(lua_State* state);
 int lua_PhysicsVehicle_getSpeedKph(lua_State* state);
+int lua_PhysicsVehicle_getSpeedSmoothKph(lua_State* state);
+int lua_PhysicsVehicle_getSteerdownGain(lua_State* state);
+int lua_PhysicsVehicle_getSteerdownSpeed(lua_State* state);
 int lua_PhysicsVehicle_getSteeringGain(lua_State* state);
 int lua_PhysicsVehicle_getType(lua_State* state);
 int lua_PhysicsVehicle_getWheel(lua_State* state);
@@ -23,9 +33,15 @@ int lua_PhysicsVehicle_isDynamic(lua_State* state);
 int lua_PhysicsVehicle_isEnabled(lua_State* state);
 int lua_PhysicsVehicle_isKinematic(lua_State* state);
 int lua_PhysicsVehicle_removeCollisionListener(lua_State* state);
+int lua_PhysicsVehicle_reset(lua_State* state);
+int lua_PhysicsVehicle_setBoost(lua_State* state);
+int lua_PhysicsVehicle_setBrakedown(lua_State* state);
 int lua_PhysicsVehicle_setBrakingForce(lua_State* state);
+int lua_PhysicsVehicle_setDownforce(lua_State* state);
+int lua_PhysicsVehicle_setDrivedown(lua_State* state);
 int lua_PhysicsVehicle_setDrivingForce(lua_State* state);
 int lua_PhysicsVehicle_setEnabled(lua_State* state);
+int lua_PhysicsVehicle_setSteerdown(lua_State* state);
 int lua_PhysicsVehicle_setSteeringGain(lua_State* state);
 int lua_PhysicsVehicle_update(lua_State* state);
 

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

@@ -53,6 +53,7 @@ void lua_RegisterAllBindings()
     luaRegister_Label();
     luaRegister_Layout();
     luaRegister_Light();
+    luaRegister_Logger();
     luaRegister_Material();
     luaRegister_MaterialParameter();
     luaRegister_MathUtil();

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

@@ -48,6 +48,7 @@
 #include "lua_Label.h"
 #include "lua_Layout.h"
 #include "lua_Light.h"
+#include "lua_Logger.h"
 #include "lua_Material.h"
 #include "lua_MaterialParameter.h"
 #include "lua_MathUtil.h"