Kaynağa Gözat

Adds support for setting up material parameter bindings to Node methods from Lua scripts.

Chris Culy 13 yıl önce
ebeveyn
işleme
ea822b6aa3

+ 2 - 3
gameplay-luagen/TODO.txt

@@ -11,12 +11,11 @@ Normal Priority List:
 - Add "@script{create}" to the appropriate gameplay functions.
 - Fix memory leaks in gameplay-luagen and in generated code.
 
-- Add support for passing function pointers (i.e. for material parameter binding) (using the same string mechanism that was used for enums?).
-- Add support for function callback parameters using Lua functions (i.e. scene->visit("myLuaFunction")).
 - Add support for touch/key/mouse event callbacks.
 - Add support for listener callbacks.
 
 Low Priority List:
 ==================
+- Reduce compilation dependencies (remove Global.h from lua_XXX.cpp?)
 - Add support for std::vector.
-- Separate threads?
+- Separate threads?

+ 91 - 0
gameplay/src/MaterialParameter.cpp

@@ -1,5 +1,6 @@
 #include "Base.h"
 #include "MaterialParameter.h"
+#include "Node.h"
 
 namespace gameplay
 {
@@ -295,6 +296,96 @@ void MaterialParameter::bind(Effect* effect)
     }
 }
 
+void MaterialParameter::bindValue(Node* node, const char* binding)
+{
+    GP_ASSERT(binding);
+
+    if (strcmp(binding, "&Node::getBackVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getBackVector);
+    }
+    else if (strcmp(binding, "&Node::getDownVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getDownVector);
+    }
+    else if (strcmp(binding, "&Node::getTranslationWorld") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getTranslationWorld);
+    }
+    else if (strcmp(binding, "&Node::getTranslationView") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getTranslationView);
+    }
+    else if (strcmp(binding, "&Node::getForwardVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getForwardVector);
+    }
+    else if (strcmp(binding, "&Node::getForwardVectorWorld") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getForwardVectorWorld);
+    }
+    else if (strcmp(binding, "&Node::getForwardVectorView") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getForwardVectorView);
+    }
+    else if (strcmp(binding, "&Node::getLeftVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getLeftVector);
+    }
+    else if (strcmp(binding, "&Node::getRightVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getRightVector);
+    }
+    else if (strcmp(binding, "&Node::getRightVectorWorld") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getRightVectorWorld);
+    }
+    else if (strcmp(binding, "&Node::getUpVector") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getUpVector);
+    }
+    else if (strcmp(binding, "&Node::getUpVectorWorld") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getUpVectorWorld);
+    }
+    else if (strcmp(binding, "&Node::getActiveCameraTranslationWorld") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getActiveCameraTranslationWorld);
+    }
+    else if (strcmp(binding, "&Node::getActiveCameraTranslationView") == 0)
+    {
+        bindValue<Node, Vector3>(node, &Node::getActiveCameraTranslationView);
+    }
+    else if (strcmp(binding, "&Node::getScaleX") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getScaleX);
+    }
+    else if (strcmp(binding, "&Node::getScaleY") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getScaleY);
+    }
+    else if (strcmp(binding, "&Node::getScaleZ") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getScaleZ);
+    }
+    else if (strcmp(binding, "&Node::getTranslationX") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getTranslationX);
+    }
+    else if (strcmp(binding, "&Node::getTranslationY") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getTranslationY);
+    }
+    else if (strcmp(binding, "&Node::getTranslationZ") == 0)
+    {
+        bindValue<Node, float>(node, &Node::getTranslationZ);
+    }
+    else
+    {
+        GP_ERROR("Unsupported material parameter binding '%s'.", binding);
+    }
+}
+
 unsigned int MaterialParameter::getAnimationPropertyComponentCount(int propertyId) const
 {
     switch (propertyId)

+ 32 - 0
gameplay/src/MaterialParameter.h

@@ -11,6 +11,7 @@
 
 namespace gameplay
 {
+    class Node;
 
 /**
  * Defines a material parameter.
@@ -151,6 +152,37 @@ public:
     template <class ClassType, class ParameterType>
     void bindValue(ClassType* classInstance, ParameterType (ClassType::*valueMethod)() const, unsigned int (ClassType::*countMethod)() const);
 
+    /**
+     * Binds the return value of the supported class method for the given node to this material parameter.
+     * 
+     * Note: intended for use from Lua scripts.
+     * 
+     * @param node The node containing the the member method to bind.
+     * @param binding The name of the class method to bind (in the format '&class::method').
+     *      Note: this name must be one of the following supported methods:
+     *      - "&Node::getBackVector"
+     *      - "&Node::getDownVector"
+     *      - "&Node::getTranslationWorld"
+     *      - "&Node::getTranslationView"
+     *      - "&Node::getForwardVector"
+     *      - "&Node::getForwardVectorWorld"
+     *      - "&Node::getForwardVectorView"
+     *      - "&Node::getLeftVector"
+     *      - "&Node::getRightVector"
+     *      - "&Node::getRightVectorWorld"
+     *      - "&Node::getUpVector"
+     *      - "&Node::getUpVectorWorld"
+     *      - "&Node::getActiveCameraTranslationWorld"
+     *      - "&Node::getActiveCameraTranslationView"
+     *      - "&Node::getScaleX"
+     *      - "&Node::getScaleY"
+     *      - "&Node::getScaleZ"
+     *      - "&Node::getTranslationX"
+     *      - "&Node::getTranslationY"
+     *      - "&Node::getTranslationZ"
+     */
+    void bindValue(Node* node, const char* binding);
+
     /**
      * @see AnimationTarget#getAnimationPropertyComponentCount
      */

+ 1 - 1
gameplay/src/ScriptController.h

@@ -451,7 +451,7 @@ public:
      * @param v The pointer variable.
      * @script{ignore}
      */
-    template<typename T>void setPointer(const char* type, const char* name, T* v);
+    template<typename T>void setObjectPointer(const char* type, const char* name, T* v);
 
     /**
      * Registers the given library with Lua.

+ 1 - 1
gameplay/src/ScriptController.inl

@@ -167,7 +167,7 @@ template<typename T>T* ScriptController::getObjectPointer(const char* type, cons
     return (T*)((ScriptController::LuaObject*)userdata)->instance;
 }
 
-template<typename T>void ScriptController::setPointer(const char* type, const char* name, T* v)
+template<typename T>void ScriptController::setObjectPointer(const char* type, const char* name, T* v)
 {
     ScriptController::LuaObject* object = (ScriptController::LuaObject*)lua_newuserdata(state, sizeof(ScriptController::LuaObject));
     object->instance = (void*)v;

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

@@ -14,6 +14,7 @@ void luaRegister_MaterialParameter()
     const luaL_Reg lua_members[] = 
     {
         {"addRef", lua_MaterialParameter_addRef},
+        {"bindValue", lua_MaterialParameter_bindValue},
         {"createAnimation", lua_MaterialParameter_createAnimation},
         {"createAnimationFromBy", lua_MaterialParameter_createAnimationFromBy},
         {"createAnimationFromTo", lua_MaterialParameter_createAnimationFromTo},
@@ -119,6 +120,48 @@ int lua_MaterialParameter_addRef(lua_State* state)
     return 0;
 }
 
+int lua_MaterialParameter_bindValue(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, 1) == LUA_TNIL) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                Node* param1 = ScriptController::getInstance()->getObjectPointer<Node>(2, "Node", false);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = ScriptController::getInstance()->getString(3, false);
+
+                MaterialParameter* instance = getInstance(state);
+                instance->bindValue(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "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_MaterialParameter_createAnimation(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -7,6 +7,7 @@ namespace gameplay
 // Lua bindings for MaterialParameter.
 int lua_MaterialParameter__gc(lua_State* state);
 int lua_MaterialParameter_addRef(lua_State* state);
+int lua_MaterialParameter_bindValue(lua_State* state);
 int lua_MaterialParameter_createAnimation(lua_State* state);
 int lua_MaterialParameter_createAnimationFromBy(lua_State* state);
 int lua_MaterialParameter_createAnimationFromTo(lua_State* state);