diff --git a/SDK/include/NDK/LuaAPI.hpp b/SDK/include/NDK/LuaAPI.hpp index 3a420707b..2f3000034 100644 --- a/SDK/include/NDK/LuaAPI.hpp +++ b/SDK/include/NDK/LuaAPI.hpp @@ -28,6 +28,7 @@ namespace Ndk static void Register_Math(Nz::LuaInstance& instance); static void Register_Network(Nz::LuaInstance& instance); static void Register_Renderer(Nz::LuaInstance& instance); + static void Register_SDK(Nz::LuaInstance& instance); static void Register_Utility(Nz::LuaInstance& instance); }; } diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 4599d3f16..5b78a7e21 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -2,13 +2,222 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp -#include #include +#include +#include #include +#include +#include +#include +#include #include +#ifndef NDK_SERVER +#include +#include +#endif + namespace Nz { + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Table: + angles->Set(instance.CheckField("pitch", index), instance.CheckField("yaw", index), instance.CheckField("roll", index)); + return 1; + + default: + { + if (instance.IsOfType(index, "EulerAngles")) + angles->Set(*(*static_cast(instance.ToUserdata(index)))); + else + angles->Set(*(*static_cast(instance.CheckUserdata(index, "Quaternion")))); + + return 1; + } + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag) + { + EulerAnglesd anglesDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &anglesDouble, TypeTag()); + + angles->Set(anglesDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Table: + quat->Set(instance.CheckField("w", index), instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + return 1; + + default: + { + if (instance.IsOfType(index, "EulerAngles")) + quat->Set(*(*static_cast(instance.ToUserdata(index)))); + else + quat->Set(*(*static_cast(instance.CheckUserdata(index, "Quaternion")))); + + return 1; + } + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag) + { + Quaterniond quatDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &quatDouble, TypeTag()); + + quat->Set(quatDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_String: + address->BuildFromAddress(instance.CheckString(index)); + return 1; + + default: + *address = *(*static_cast(instance.CheckUserdata(index, "IpAddress"))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Number: + if (index < 0 && index > -2) + instance.Error("Vector2 expected, two numbers are required to convert it"); + + vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1)); + return 2; + + case Nz::LuaType_Table: + vec->Set(instance.CheckField("x", index), instance.CheckField("y", index)); + return 1; + + default: + vec->Set(*(*static_cast(instance.CheckUserdata(index, "Vector2")))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag) + { + Vector2d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag) + { + Vector2d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag) + { + switch (instance.GetType(index)) + { + case Nz::LuaType_Number: + if (index < 0 && index > -3) + instance.Error("Vector3 expected, three numbers are required to convert it"); + + vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2)); + return 3; + + case Nz::LuaType_Table: + vec->Set(instance.CheckField("x", index), instance.CheckField("y", index), instance.CheckField("z", index)); + return 1; + + default: + vec->Set(*(*static_cast(instance.CheckUserdata(index, "Vector3")))); + return 1; + } + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag) + { + Vector3d vecDouble; + unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag()); + + vec->Set(vecDouble); + return ret; + } + +#ifndef NDK_SERVER + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag) + { + if (instance.IsOfType(index, "InstancedRenderable")) + *renderable = *(*static_cast(instance.CheckUserdata(index, "InstancedRenderable"))); + else + *renderable = *(*static_cast(instance.CheckUserdata(index, "Model"))); + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->loadAlphaMap = instance.CheckField("LoadAlphaMap", params->loadAlphaMap); + params->loadDiffuseMap = instance.CheckField("LoadDiffuseMap", params->loadDiffuseMap); + params->loadEmissiveMap = instance.CheckField("LoadEmissiveMap", params->loadEmissiveMap); + params->loadHeightMap = instance.CheckField("LoadHeightMap", params->loadHeightMap); + params->loadNormalMap = instance.CheckField("LoadNormalMap", params->loadNormalMap); + params->loadSpecularMap = instance.CheckField("LoadSpecularMap", params->loadSpecularMap); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->animated = instance.CheckField("Animated", params->animated); + params->center = instance.CheckField("Center", params->center); + params->flipUVs = instance.CheckField("FlipUVs", params->flipUVs); + params->optimizeIndexBuffers = instance.CheckField("OptimizeIndexBuffers", params->optimizeIndexBuffers); + params->scale = instance.CheckField("Scale", params->scale); + + return 1; + } + + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag) + { + instance.CheckType(index, Nz::LuaType_Table); + + params->loadMaterials = instance.CheckField("LoadMaterials", params->loadMaterials); + + LuaImplQueryArg(instance, -1, ¶ms->material, TypeTag()); + LuaImplQueryArg(instance, -1, ¶ms->mesh, TypeTag()); + + return 1; + } + inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag) { instance.CheckType(index, Nz::LuaType_Table); @@ -17,50 +226,31 @@ namespace Nz return 1; } +#endif - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3d* vec, TypeTag) + + + inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd val, TypeTag) { - switch (lua.GetType(index)) - { - case Nz::LuaType_Number: - if (index < 0 && index > -3) - lua.Error("Vector3 expected, three numbers are required to convert it"); - - vec->Set(lua.CheckNumber(index), lua.CheckNumber(index + 1), lua.CheckNumber(index + 2)); - return 3; - - case Nz::LuaType_Table: - vec->Set(lua.CheckField("x", index), lua.CheckField("y", index), lua.CheckField("z", index)); - return 3; - - default: - vec->Set(*(*static_cast(lua.CheckUserdata(index, "Vector3")))); - return 1; - } + instance.PushInstance("EulerAngles", val); + return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3f* vec, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf val, TypeTag) { - Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); - - vec->Set(vecDouble); - return ret; + instance.PushInstance("EulerAngles", val); + return 1; } - inline unsigned int LuaImplQueryArg(const LuaInstance& lua, int index, Vector3ui* vec, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond val, TypeTag) { - Vector3d vecDouble; - unsigned int ret = LuaImplQueryArg(lua, index, &vecDouble, TypeTag()); - - vec->Set(vecDouble); - return ret; + instance.PushInstance("Quaternion", val); + return 1; } - - inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf val, TypeTag) { - instance.PushInstance("SoundBuffer", val); + instance.PushInstance("Quaternion", val); return 1; } @@ -87,4 +277,48 @@ namespace Nz instance.PushInstance("Vector3", val); return 1; } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag) + { + instance.PushInstance("Entity", ptr); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle handle, TypeTag) + { + instance.PushInstance("Entity", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle handle, TypeTag) + { + instance.PushInstance("NodeComponent", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag) + { + instance.PushInstance("World", ptr); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle handle, TypeTag) + { + instance.PushInstance("World", handle); + return 1; + } + +#ifndef NDK_SERVER + inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle handle, TypeTag) + { + instance.PushInstance("GraphicsComponent", handle); + return 1; + } + + inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag) + { + instance.PushInstance("SoundBuffer", val); + return 1; + } +#endif } diff --git a/SDK/src/NDK/LuaAPI_Graphics.cpp b/SDK/src/NDK/LuaAPI_Graphics.cpp index 08b68e853..5440b05a3 100644 --- a/SDK/src/NDK/LuaAPI_Graphics.cpp +++ b/SDK/src/NDK/LuaAPI_Graphics.cpp @@ -10,5 +10,37 @@ namespace Ndk { void LuaAPI::Register_Graphics(Nz::LuaInstance& instance) { + Nz::LuaClass instancedRenderable("InstancedRenderable"); + + Nz::LuaClass modelClass("Model"); + modelClass.Inherit(instancedRenderable, [] (Nz::ModelRef* model) -> Nz::InstancedRenderableRef* + { + return reinterpret_cast(model); //TODO: Make a ObjectRefCast + }); + + modelClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::ModelRef* + { + return new Nz::ModelRef(new Nz::Model); + }); + + //modelClass.SetMethod("GetMaterial", &Nz::Model::GetMaterial); + modelClass.SetMethod("GetMaterialCount", &Nz::Model::GetMaterialCount); + //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); + modelClass.SetMethod("GetSkin", &Nz::Model::GetSkin); + modelClass.SetMethod("GetSkinCount", &Nz::Model::GetSkinCount); + + modelClass.SetMethod("IsAnimated", &Nz::Model::IsAnimated); + modelClass.SetMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); + + modelClass.SetMethod("Reset", &Nz::Model::Reset); + + //modelClass.SetMethod("SetMaterial", &Nz::Model::SetMaterial); + //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); + //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); + modelClass.SetMethod("SetSkin", &Nz::Model::SetSkin); + modelClass.SetMethod("SetSkinCount", &Nz::Model::SetSkinCount); + + instancedRenderable.Register(instance); + modelClass.Register(instance); } } \ No newline at end of file diff --git a/SDK/src/NDK/LuaAPI_Math.cpp b/SDK/src/NDK/LuaAPI_Math.cpp index 399610ee7..5887b7e83 100644 --- a/SDK/src/NDK/LuaAPI_Math.cpp +++ b/SDK/src/NDK/LuaAPI_Math.cpp @@ -8,6 +8,243 @@ namespace Ndk { void LuaAPI::Register_Math(Nz::LuaInstance& instance) { + /*********************************** Nz::EulerAngles **********************************/ + Nz::LuaClass eulerAnglesClass("EulerAngles"); + + eulerAnglesClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::EulerAnglesd* + { + unsigned int argCount = std::min(lua.GetStackTop(), 3U); + switch (argCount) + { + case 0: + return new Nz::EulerAnglesd(0.0, 0.0, 0.0); + + case 1: + return new Nz::EulerAnglesd(*(*static_cast(lua.CheckUserdata(1, "EulerAngles")))); + + case 3: + return new Nz::EulerAnglesd(lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3)); + } + + lua.Error("No matching overload for EulerAngles constructor"); + return nullptr; + }); + + eulerAnglesClass.SetMethod("__tostring", &Nz::EulerAnglesd::ToString); + + eulerAnglesClass.SetGetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + { + std::size_t length; + const char* ypr = lua.CheckString(1, &length); + + switch (length) + { + case 1: + { + switch (ypr[0]) + { + case 'p': + lua.Push(instance.pitch); + return true; + + case 'y': + lua.Push(instance.yaw); + return true; + + case 'r': + lua.Push(instance.roll); + return true; + } + break; + } + + case 3: + { + if (std::memcmp(ypr, "yaw", 3) != 0) + break; + + lua.Push(instance.yaw); + return true; + } + + case 4: + { + if (std::memcmp(ypr, "roll", 4) != 0) + break; + + lua.Push(instance.roll); + return true; + } + + case 5: + { + if (std::memcmp(ypr, "pitch", 5) != 0) + break; + + lua.Push(instance.pitch); + return true; + } + } + + return false; + }); + + eulerAnglesClass.SetSetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance) + { + std::size_t length; + const char* ypr = lua.CheckString(1, &length); + double value = lua.CheckNumber(2); + + switch (length) + { + case 1: + { + switch (ypr[0]) + { + case 'p': + instance.pitch = value; + return true; + + case 'y': + instance.yaw = value; + return true; + + case 'r': + instance.roll = value; + return true; + } + break; + } + + case 3: + { + if (std::memcmp(ypr, "yaw", 3) != 0) + break; + + instance.yaw = value; + return true; + } + + case 4: + { + if (std::memcmp(ypr, "roll", 4) != 0) + break; + + instance.roll = value; + return true; + } + + case 5: + { + if (std::memcmp(ypr, "pitch", 5) != 0) + break; + + instance.pitch = value; + return true; + } + } + + return false; + }); + + eulerAnglesClass.Register(instance); + + /*********************************** Nz::Quaternion **********************************/ + Nz::LuaClass quaternionClass("Quaternion"); + + quaternionClass.SetConstructor([] (Nz::LuaInstance& lua) -> Nz::Quaterniond* + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + switch (argCount) + { + case 0: + return new Nz::Quaterniond(1.0, 0.0, 0.0, 0.0); + + case 1: + { + if (lua.IsOfType(1, "EulerAngles")) + return new Nz::Quaterniond(*(*static_cast(lua.ToUserdata(1)))); + else if (lua.IsOfType(1, "Quaternion")) + return new Nz::Quaterniond(*(*static_cast(lua.ToUserdata(1)))); + } + + case 2: + return new Nz::Quaterniond(lua.CheckNumber(1), *(*static_cast(lua.CheckUserdata(2, "Vector3")))); + + case 4: + return new Nz::Quaterniond(lua.CheckNumber(1), lua.CheckNumber(2), lua.CheckNumber(3), lua.CheckNumber(4)); + } + + lua.Error("No matching overload for Quaternion constructor"); + return nullptr; + }); + + quaternionClass.SetMethod("__tostring", &Nz::Quaterniond::ToString); + + quaternionClass.SetGetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + { + std::size_t length; + const char* wxyz = lua.CheckString(1, &length); + + if (length != 1) + return false; + + switch (wxyz[0]) + { + case 'w': + lua.Push(instance.w); + return true; + + case 'x': + lua.Push(instance.x); + return true; + + case 'y': + lua.Push(instance.y); + return true; + + case 'z': + lua.Push(instance.z); + return true; + } + + return false; + }); + + quaternionClass.SetSetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance) + { + std::size_t length; + const char* wxyz = lua.CheckString(1, &length); + + if (length != 1) + return false; + + double value = lua.CheckNumber(2); + + switch (wxyz[0]) + { + case 'w': + instance.w = value; + return true; + + case 'x': + instance.x = value; + return true; + + case 'y': + instance.y = value; + return true; + + case 'z': + instance.z = value; + return true; + } + + return false; + }); + + quaternionClass.Register(instance); + /*********************************** Nz::Vector2 **********************************/ Nz::LuaClass vector2dClass("Vector2"); @@ -25,7 +262,7 @@ namespace Ndk if (lua.IsOfType(1, Nz::LuaType_Number)) return new Nz::Vector2d(lua.CheckNumber(1)); else if (lua.IsOfType(1, "Vector2")) - return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector2d(*(*static_cast(lua.ToUserdata(1)))); break; } @@ -42,8 +279,14 @@ namespace Ndk switch (lua.GetType(1)) { case Nz::LuaType_Number: - lua.Push(instance[lua.CheckInteger(1)]); + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 2) + return false; + + lua.Push(instance[index - 1]); return true; + } case Nz::LuaType_String: { @@ -80,7 +323,7 @@ namespace Ndk if (index < 1 || index > 2) return false; - instance[index] = lua.CheckNumber(2); + instance[index - 1] = lua.CheckNumber(2); return true; } @@ -128,11 +371,11 @@ namespace Ndk case 1: { if (lua.IsOfType(1, Nz::LuaType_Number)) - return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.ToUserdata(1))); + return new Nz::Vector3d(lua.CheckNumber(1), *(*static_cast(lua.ToUserdata(1)))); else if (lua.IsOfType(1, "Vector2")) - return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); else if (lua.IsOfType(1, "Vector3")) - return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); + return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1)))); break; } @@ -140,7 +383,7 @@ namespace Ndk case 2: { if (lua.IsOfType(1, Nz::LuaType_Number)) - return new Nz::Vector3d(lua.CheckNumber(1), *static_cast(lua.CheckUserdata(1, "Vector2"))); + return new Nz::Vector3d(lua.CheckNumber(1), *(*static_cast(lua.CheckUserdata(1, "Vector2")))); else if (lua.IsOfType(1, "Vector2")) return new Nz::Vector3d(*(*static_cast(lua.ToUserdata(1))), lua.CheckNumber(2)); @@ -159,8 +402,14 @@ namespace Ndk switch (lua.GetType(1)) { case Nz::LuaType_Number: - lua.Push(instance[lua.CheckInteger(1)]); + { + long long index = lua.CheckInteger(1); + if (index < 1 || index > 3) + return false; + + lua.Push(instance[index - 1]); return true; + } case Nz::LuaType_String: { @@ -201,7 +450,7 @@ namespace Ndk if (index < 1 || index > 3) return false; - instance[index] = lua.CheckNumber(2); + instance[index - 1] = lua.CheckNumber(2); return true; } diff --git a/SDK/src/NDK/LuaAPI_SDK.cpp b/SDK/src/NDK/LuaAPI_SDK.cpp new file mode 100644 index 000000000..50bd66005 --- /dev/null +++ b/SDK/src/NDK/LuaAPI_SDK.cpp @@ -0,0 +1,313 @@ +// Copyright (C) 2016 Jérôme Leclercq, Arnaud Cadot +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + + +#include +#include +#include +#include +#include +#include + +namespace Ndk +{ + namespace + { + int AddNilComponent(Nz::LuaInstance& lua, EntityHandle&) + { + lua.PushNil(); + return 1; + } + + template + int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& component = handle->AddComponent(); + lua.Push(component.CreateHandle()); + return 1; + } + + int AddComponent(Nz::LuaInstance& lua, EntityHandle& handle, ComponentIndex index) + { + std::vector componentAdder(BaseComponent::GetMaxComponentIndex(), AddNilComponent); + componentAdder[GraphicsComponent::componentIndex] = &AddComponentOfType; + componentAdder[NodeComponent::componentIndex] = &AddComponentOfType; + + if (index > componentAdder.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + return componentAdder[index](lua, handle); + } + + int PushNilComponent(Nz::LuaInstance& lua, BaseComponent&) + { + lua.PushNil(); + return 1; + } + + template + int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component) + { + static_assert(std::is_base_of::value, "ComponentType must inherit BaseComponent"); + + T& rightComponent = static_cast(component); + lua.Push(rightComponent.CreateHandle()); + return 1; + } + + int PushComponent(Nz::LuaInstance& lua, BaseComponent& component) + { + std::vector componentConverter(BaseComponent::GetMaxComponentIndex(), PushNilComponent); + componentConverter[GraphicsComponent::componentIndex] = &PushComponentOfType; + componentConverter[NodeComponent::componentIndex] = &PushComponentOfType; + + ComponentIndex index = component.GetIndex(); + + if (index > componentConverter.size()) + { + lua.Error("Invalid component index"); + return 0; + } + + return componentConverter[index](lua, component); + } + } + + void LuaAPI::Register_SDK(Nz::LuaInstance& instance) + { + Nz::LuaClass graphicsComponent("GraphicsComponent"); + + graphicsComponent.SetMethod("Attach", &GraphicsComponent::Attach, 0); + + graphicsComponent.Register(instance); + + Nz::LuaClass nodeClass("Node"); //< TODO: Move to Utility + + nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); + //nodeClass.SetMethod("GetChilds", &Nz::Node::GetChilds); + nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); + nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); + nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + //nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); + nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); + //nodeClass.SetMethod("GetParent", &Nz::Node::GetParent); + nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); + //nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); + nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + //nodeClass.SetMethod("GetTransformMatrix", &Nz::Node::GetTransformMatrix); + nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + + nodeClass.SetMethod("HasChilds", &Nz::Node::HasChilds); + + nodeClass.SetMethod("GetBackward", &Nz::Node::GetBackward); + nodeClass.SetMethod("GetDown", &Nz::Node::GetDown); + nodeClass.SetMethod("GetForward", &Nz::Node::GetForward); + nodeClass.SetMethod("GetInheritPosition", &Nz::Node::GetInheritPosition); + nodeClass.SetMethod("GetInheritRotation", &Nz::Node::GetInheritRotation); + nodeClass.SetMethod("GetInheritScale", &Nz::Node::GetInheritScale); + nodeClass.SetMethod("GetInitialPosition", &Nz::Node::GetInitialPosition); + nodeClass.SetMethod("GetInitialRotation", &Nz::Node::GetInitialRotation); + nodeClass.SetMethod("GetInitialScale", &Nz::Node::GetInitialScale); + nodeClass.SetMethod("GetLeft", &Nz::Node::GetLeft); + nodeClass.SetMethod("GetNodeType", &Nz::Node::GetNodeType); + nodeClass.SetMethod("GetPosition", &Nz::Node::GetPosition, Nz::CoordSys_Global); + nodeClass.SetMethod("GetRight", &Nz::Node::GetRight); + nodeClass.SetMethod("GetRotation", &Nz::Node::GetRotation, Nz::CoordSys_Global); + nodeClass.SetMethod("GetScale", &Nz::Node::GetScale, Nz::CoordSys_Global); + nodeClass.SetMethod("GetUp", &Nz::Node::GetUp); + + nodeClass.SetMethod("SetInitialPosition", (void(Nz::Node::*)(const Nz::Vector3f&)) &Nz::Node::SetInitialPosition); + nodeClass.SetMethod("SetInitialRotation", (void(Nz::Node::*)(const Nz::Quaternionf&)) &Nz::Node::SetInitialRotation); + + nodeClass.SetMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local); + nodeClass.SetMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local); + + nodeClass.SetMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + int argIndex = 1; + + Nz::Vector3f offset = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.Move(offset, coordSys); + + return 0; + }); + + nodeClass.SetMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + int argIndex = 1; + + Nz::Quaternionf rotation = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.Rotate(rotation, coordSys); + + return 0; + }); + + nodeClass.SetMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + node.Scale(lua.Check(&argIndex)); + else + node.Scale(lua.Check(&argIndex)); + + return 0; + } + + case 3: + node.Scale(lua.Check(&argIndex)); + return 0; + } + + lua.Error("No matching overload for method Scale"); + return 0; + }); + + nodeClass.SetMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + case 2: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + { + float scale = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + node.SetScale(scale, coordSys); + } + else + node.SetScale(lua.Check(&argIndex)); + + return 0; + } + + case 3: + case 4: + { + Nz::Vector3f scale = lua.Check(&argIndex); + Nz::CoordSys coordSys = lua.Check(&argIndex, Nz::CoordSys_Local); + + node.SetScale(scale, coordSys); + return 0; + } + } + + lua.Error("No matching overload for method SetScale"); + return 0; + }); + + nodeClass.SetMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& node) -> int + { + unsigned int argCount = std::min(lua.GetStackTop(), 4U); + + int argIndex = 1; + switch (argCount) + { + case 1: + { + if (lua.IsOfType(argIndex, Nz::LuaType_Number)) + node.SetInitialScale(lua.Check(&argIndex)); + else + node.SetInitialScale(lua.Check(&argIndex)); + + return 0; + } + + case 2: + case 3: + node.SetInitialScale(lua.Check(&argIndex)); + return 0; + } + + lua.Error("No matching overload for method SetInitialScale"); + return 0; + }); + + nodeClass.Register(instance); + + Nz::LuaClass nodeComponent("NodeComponent"); + nodeComponent.Inherit(nodeClass, [] (NodeComponentHandle* handle) -> Nz::Node* + { + return handle->GetObject(); + }); + + nodeComponent.Register(instance); + + Nz::LuaClass entityClass("Entity"); + + entityClass.SetMethod("Enable", &Entity::Enable); + entityClass.SetMethod("GetId", &Entity::GetId); + entityClass.SetMethod("GetWorld", &Entity::GetWorld); + entityClass.SetMethod("Kill", &Entity::Kill); + entityClass.SetMethod("IsEnabled", &Entity::IsEnabled); + entityClass.SetMethod("IsValid", &Entity::IsValid); + entityClass.SetMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); + entityClass.SetMethod("RemoveAllComponents", &Entity::RemoveAllComponents); + entityClass.SetMethod("__tostring", &EntityHandle::ToString); + + entityClass.SetMethod("AddComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + return AddComponent(lua, handle, componentIndex); + }); + + entityClass.SetMethod("GetComponent", [] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + { + int index = 1; + ComponentIndex componentIndex = lua.Check(&index); + + if (!handle->HasComponent(componentIndex)) + { + lua.PushNil(); + return 1; + } + + return PushComponent(lua, handle->GetComponent(componentIndex)); + }); + + entityClass.Register(instance); + + Nz::LuaClass worldClass("World"); + + worldClass.SetMethod("CreateEntity", &World::CreateEntity); + worldClass.SetMethod("CreateEntities", &World::CreateEntities); + worldClass.SetMethod("Clear", &World::Clear); + + worldClass.Register(instance); + + instance.PushTable(0, 2); + { + instance.PushInteger(GraphicsComponent::componentIndex); + instance.SetField("Graphics"); + + instance.PushInteger(NodeComponent::componentIndex); + instance.SetField("Node"); + } + instance.SetGlobal("ComponentType"); + } +} \ No newline at end of file