Browse Source

Add Lua binding for Model's SetVertexBuffer() and SetIndexBuffer().
Related to #1638.

Yao Wei Tjong 姚伟忠 9 years ago
parent
commit
c13084b962

+ 38 - 2
Source/Urho3D/LuaScript/ToluaUtils.cpp

@@ -22,6 +22,8 @@
 
 #include "../Precompiled.h"
 
+#include "../Graphics/IndexBuffer.h"
+#include "../Graphics/VertexBuffer.h"
 #include "../IO/VectorBuffer.h"
 
 #include <toluapp/tolua++.h>
@@ -57,7 +59,7 @@ Context* GetContext(lua_State* L)
     return tolua_isusertype(L, -1, "Context", 0, &error) ? static_cast<Context*>(tolua_tousertype(L, -1, 0)) : 0;
 }
 
-// Explicit template specialization only required for StringVector
+// Explicit template specialization for StringVector
 
 template <> int ToluaIsVector<String>(lua_State* L, int lo, const char* /*type*/, int def, tolua_Error* err)
 {
@@ -92,7 +94,7 @@ template <> int ToluaPushVector<String>(lua_State* L, void* data, const char* /*
     return 1;
 }
 
-// Explicit template specialization only required for boolean
+// Explicit template specialization for boolean
 
 template <> int ToluaIsPODVector<bool>(double /*overload*/, lua_State* L, int lo, const char* /*type*/, int def, tolua_Error* err)
 {
@@ -127,6 +129,40 @@ template <> int ToluaPushPODVector<bool>(double /*overload*/, lua_State* L, void
     return 1;
 }
 
+// Explicit template specialization for Vector<SharedPtr<IndexBuffer> > and Vector<SharedPtr<VertexBuffer> >
+
+template <> void* ToluaToVector<SharedPtr<IndexBuffer> >(lua_State* L, int narg, void* def)
+{
+    if (!lua_istable(L, narg))
+        return 0;
+    static Vector<SharedPtr<IndexBuffer> > result;
+    result.Clear();
+    result.Resize((unsigned)lua_objlen(L, narg));
+    for (unsigned i = 0; i < result.Size(); ++i)
+    {
+        lua_rawgeti(L, narg, i + 1);    // Lua index starts from 1
+        result[i] = SharedPtr<IndexBuffer>(static_cast<IndexBuffer*>(tolua_tousertype(L, -1, def)));
+        lua_pop(L, 1);
+    }
+    return &result;
+}
+
+template <> void* ToluaToVector<SharedPtr<VertexBuffer> >(lua_State* L, int narg, void* def)
+{
+    if (!lua_istable(L, narg))
+        return 0;
+    static Vector<SharedPtr<VertexBuffer> > result;
+    result.Clear();
+    result.Resize((unsigned)lua_objlen(L, narg));
+    for (unsigned i = 0; i < result.Size(); ++i)
+    {
+        lua_rawgeti(L, narg, i + 1);    // Lua index starts from 1
+        result[i] = SharedPtr<VertexBuffer>(static_cast<VertexBuffer*>(tolua_tousertype(L, -1, def)));
+        lua_pop(L, 1);
+    }
+    return &result;
+}
+
 namespace Urho3D
 {
 

+ 2 - 2
Source/Urho3D/LuaScript/ToluaUtils.h

@@ -175,8 +175,7 @@ template <typename T> int ToluaPushPODVector(double /*overload*/, lua_State* L,
 //   both compilers are able to avoid the multiple definitions of template instantiation symbol during linking by using weak symbol
 // MSVC and MinGW, however, follow the standard strictly, hence we need to declare all the explicit template specializations below
 //   to keep these two compilers happy
-// We do not use #ifdef MSVC/MINGW here because GCC and Clang are happy to comply with the C++ standard too
-
+#ifdef _WIN32
 template <> int ToluaIsVector<String>(lua_State* L, int lo, const char* type, int def, tolua_Error* err);
 template <> void* ToluaToVector<String>(lua_State* L, int narg, void* def);
 template <> int ToluaPushVector<String>(lua_State* L, void* data, const char* type);
@@ -184,6 +183,7 @@ template <> int ToluaPushVector<String>(lua_State* L, void* data, const char* ty
 template <> int ToluaIsPODVector<bool>(double /*overload*/, lua_State* L, int lo, const char* type, int def, tolua_Error* err);
 template <> void* ToluaToPODVector<bool>(double /*overload*/, lua_State* L, int narg, void* def);
 template <> int ToluaPushPODVector<bool>(double /*overload*/, lua_State* L, void* data, const char* type);
+#endif
 
 /// Convert object at the given index and store it in Variant. This function is not thread-safe.
 void ToluaToVariant(lua_State* L, int narg, void* def, Variant& variant);

+ 3 - 0
Source/Urho3D/LuaScript/pkgs/Graphics/Model.pkg

@@ -9,6 +9,9 @@ class Model : public Resource
     tolua_outside Model* ModelClone @ Clone(const String cloneName = String::EMPTY) const;
 
     void SetBoundingBox(const BoundingBox& box);
+    bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& morphRangeStarts,
+        const PODVector<unsigned>& morphRangeCounts);
+    bool SetIndexBuffers(const Vector<SharedPtr<IndexBuffer> >& buffers);
     void SetNumGeometries(unsigned num);
     bool SetNumGeometryLodLevels(unsigned index, unsigned num);
     bool SetGeometry(unsigned index, unsigned lodLevel, Geometry* geometry);

+ 13 - 0
bin/Data/LuaScripts/34_DynamicGeometry.lua

@@ -200,6 +200,19 @@ function CreateScene()
     fromScratchModel:SetGeometry(0, 0, geom)
     fromScratchModel.boundingBox = BoundingBox(Vector3(-0.5, -0.5, -0.5), Vector3(0.5, 0.5, 0.5))
 
+    -- Though not necessary to render, the vertex & index buffers must be listed in the model so that it can be saved properly
+    local vertexBuffers = {}
+    local indexBuffers = {}
+    table.insert(vertexBuffers, vb)
+    table.insert(indexBuffers, ib)
+    -- Morph ranges could also be not defined. Here we simply define a zero range (no morphing) for the vertex buffer
+    local morphRangeStarts = {}
+    local morphRangeCounts = {}
+    table.insert(morphRangeStarts, 0)
+    table.insert(morphRangeCounts, 0)
+    fromScratchModel:SetVertexBuffers(vertexBuffers, morphRangeStarts, morphRangeCounts)
+    fromScratchModel:SetIndexBuffers(indexBuffers)
+
     local node = scene_:CreateChild("FromScratchObject")
     node.position = Vector3(0.0, 3.0, 0.0)
     local object = node:CreateComponent("StaticModel")