From 5192e0503e2fcadf85f6cabc38fa4b02d1b67f15 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Tue, 29 May 2018 17:50:47 +0100 Subject: [PATCH] system + scripting API updates --- Documentation/ScriptingAPI-Documentation.md | 4 +- WickedEngine/wiLoader_BindLua.cpp | 46 +++++- WickedEngine/wiLoader_BindLua.h | 2 + WickedEngine/wiRenderer.cpp | 162 ++++++++------------ WickedEngine/wiRenderer.h | 6 +- WickedEngine/wiRenderer_BindLua.cpp | 17 +- WickedEngine/wiTransform.cpp | 18 +-- WickedEngine/wiTransform.h | 6 +- WickedEngine/wiVersion.cpp | 2 +- 9 files changed, 139 insertions(+), 124 deletions(-) diff --git a/Documentation/ScriptingAPI-Documentation.md b/Documentation/ScriptingAPI-Documentation.md index bae51aae8..e0b78e6b0 100644 --- a/Documentation/ScriptingAPI-Documentation.md +++ b/Documentation/ScriptingAPI-Documentation.md @@ -131,7 +131,7 @@ You can use the Renderer with the following functions, all of which are in the g - SetVSyncEnabled(opt bool enabled) - SetOcclusionCullingEnabled(bool enabled) - SetPhysicsParams(opt bool rigidBodyPhysicsEnabled, opt bool softBodyPhysicsEnabled, opt int softBodyIterationCount) -- Pick(Ray ray, opt PICKTYPE pickType, opt string id="", opt string disableID="") : Object? object, Vector position,normal, float distance +- Pick(Ray ray, opt PICKTYPE pickType, opt uint layerMask) : Object? object, Vector position,normal, float distance - DrawLine(Vector origin,end, opt Vector color) - PutWaterRipple(String imagename, Vector position) - PutDecal(Decal decal) @@ -317,6 +317,8 @@ The basic entity in the scene. It has a name. - [constructor]Node() - GetName() : string - SetName(string name) +- SetLayerMask(uint value) +- GetLayerMask() : uint result #### Transform Everything in the scene is a transform. It defines a point in the space by location, size, and rotation. diff --git a/WickedEngine/wiLoader_BindLua.cpp b/WickedEngine/wiLoader_BindLua.cpp index d5cca21e8..fa86ef251 100644 --- a/WickedEngine/wiLoader_BindLua.cpp +++ b/WickedEngine/wiLoader_BindLua.cpp @@ -34,6 +34,8 @@ const char Node_BindLua::className[] = "Node"; Luna::FunctionType Node_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), { NULL, NULL } }; Luna::PropertyType Node_BindLua::properties[] = { @@ -80,6 +82,36 @@ int Node_BindLua::SetName(lua_State* L) } return 0; } +int Node_BindLua::SetLayerMask(lua_State *L) +{ + if (node == nullptr) + { + wiLua::SError(L, "SetLayerMask(uint value) object is null!"); + return 0; + } + int argc = wiLua::SGetArgCount(L); + if (argc > 0) + { + int mask = wiLua::SGetInt(L, 1); + node->SetLayerMask(*reinterpret_cast(&mask)); + } + else + { + wiLua::SError(L, "SetLayerMask(uint value) not enough arguments!"); + } + return 0; +} +int Node_BindLua::GetLayerMask(lua_State *L) +{ + if (node == nullptr) + { + wiLua::SError(L, "GetLayerMask() object is null!"); + return 0; + } + uint32_t mask = node->GetLayerMask(); + wiLua::SSetInt(L, *reinterpret_cast(&mask)); + return 1; +} void Node_BindLua::Bind() { @@ -98,6 +130,8 @@ const char Transform_BindLua::className[] = "Transform"; Luna::FunctionType Transform_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Transform_BindLua, AttachTo), lunamethod(Transform_BindLua, Detach), @@ -561,6 +595,8 @@ const char Object_BindLua::className[] = "Object"; Luna::FunctionType Object_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Cullable_BindLua, Intersects), lunamethod(Cullable_BindLua, GetAABB), @@ -736,7 +772,7 @@ int Object_BindLua::SetColor(lua_State *L) return 0; } int argc = wiLua::SGetArgCount(L); - if (argc > 2) + if (argc > 0) { Vector_BindLua* vec = Luna::lightcheck(L, 1); if (vec != nullptr) @@ -808,6 +844,8 @@ const char Armature_BindLua::className[] = "Armature"; Luna::FunctionType Armature_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Transform_BindLua, AttachTo), lunamethod(Transform_BindLua, Detach), @@ -1174,6 +1212,8 @@ const char Decal_BindLua::className[] = "Decal"; Luna::FunctionType Decal_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Cullable_BindLua, Intersects), lunamethod(Cullable_BindLua, GetAABB), @@ -1751,6 +1791,8 @@ const char Camera_BindLua::className[] = "Camera"; Luna::FunctionType Camera_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Transform_BindLua, AttachTo), lunamethod(Transform_BindLua, Detach), @@ -1956,6 +1998,8 @@ const char Model_BindLua::className[] = "Model"; Luna::FunctionType Model_BindLua::methods[] = { lunamethod(Node_BindLua, GetName), lunamethod(Node_BindLua, SetName), + lunamethod(Node_BindLua, SetLayerMask), + lunamethod(Node_BindLua, GetLayerMask), lunamethod(Transform_BindLua, AttachTo), lunamethod(Transform_BindLua, Detach), diff --git a/WickedEngine/wiLoader_BindLua.h b/WickedEngine/wiLoader_BindLua.h index 678655ccc..5b1799148 100644 --- a/WickedEngine/wiLoader_BindLua.h +++ b/WickedEngine/wiLoader_BindLua.h @@ -23,6 +23,8 @@ public: int GetName(lua_State* L); int SetName(lua_State* L); + int SetLayerMask(lua_State *L); + int GetLayerMask(lua_State *L); static void Bind(); }; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 235649513..202f37f00 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -6605,10 +6605,6 @@ void wiRenderer::UpdateDepthBuffer(Texture2D* depth, Texture2D* linearDepth, GRA GetDevice()->BindResource(CS, linearDepth, TEXSLOT_LINEARDEPTH, threadID); } -void wiRenderer::FinishLoading() -{ - // Kept for backwards compatibility -} Texture2D* wiRenderer::GetLuminance(Texture2D* sourceImage, GRAPHICSTHREAD threadID) { @@ -6696,8 +6692,7 @@ wiWaterPlane wiRenderer::GetWaterPlane() return waterPlane; } -wiRenderer::Picked wiRenderer::Pick(RAY& ray, int pickType, const std::string& layer, - const std::string& layerDisable) +wiRenderer::Picked wiRenderer::Pick(RAY& ray, int pickType, uint32_t layerMask) { std::vector pickPoints; @@ -6709,7 +6704,7 @@ wiRenderer::Picked wiRenderer::Pick(RAY& ray, int pickType, const std::string& l { searchTree->getVisible(ray, culledObjects); - RayIntersectMeshes(ray, culledObjects, pickPoints, pickType, true, layer, layerDisable, true); + RayIntersectMeshes(ray, culledObjects, pickPoints, pickType, true, true, layerMask); } // pick other... @@ -6860,12 +6855,11 @@ wiRenderer::Picked wiRenderer::Pick(RAY& ray, int pickType, const std::string& l return Picked(); } -wiRenderer::Picked wiRenderer::Pick(long cursorX, long cursorY, int pickType, const std::string& layer, - const std::string& layerDisable) +wiRenderer::Picked wiRenderer::Pick(long cursorX, long cursorY, int pickType, uint32_t layerMask) { RAY ray = getPickRay(cursorX, cursorY); - return Pick(ray, pickType, layer, layerDisable); + return Pick(ray, pickType, layerMask); } RAY wiRenderer::getPickRay(long cursorX, long cursorY){ @@ -6880,24 +6874,13 @@ RAY wiRenderer::getPickRay(long cursorX, long cursorY){ } void wiRenderer::RayIntersectMeshes(const RAY& ray, const CulledList& culledObjects, std::vector& points, - int pickType, bool dynamicObjects, const std::string& layer, const std::string& layerDisable, bool onlyVisible) + int pickType, bool dynamicObjects, bool onlyVisible, uint32_t layerMask) { if (culledObjects.empty()) { return; } - bool checkLayers = false; - if (layer.length() > 0) - { - checkLayers = true; - } - bool dontcheckLayers = false; - if (layerDisable.length() > 0) - { - dontcheckLayers = true; - } - XMVECTOR& rayOrigin = XMLoadFloat3(&ray.origin); XMVECTOR& rayDirection = XMVector3Normalize(XMLoadFloat3(&ray.direction)); @@ -6909,91 +6892,82 @@ void wiRenderer::RayIntersectMeshes(const RAY& ray, const CulledList& culledObje { Object* object = (Object*)culled; - if (!(pickType & object->GetRenderTypes())) + uint32_t objectLayerMask = object->GetLayerMask(); + if (objectLayerMask & layerMask) { - continue; - } - if (!dynamicObjects && object->isDynamic()) - { - continue; - } - if (onlyVisible && object->IsOccluded() && GetOcclusionCullingEnabled()) - { - continue; - } - // layer support - if (checkLayers || dontcheckLayers) - { - string id = object->GetLayerID(); - - if (checkLayers && layer.find(id) == string::npos) + if (!(pickType & object->GetRenderTypes())) { continue; } - if (dontcheckLayers && layerDisable.find(id) != string::npos) + if (!dynamicObjects && object->isDynamic()) { continue; } - } - - Mesh* mesh = object->mesh; - if (mesh->vertices_POS.size() >= _arraySize) - { - // grow preallocated vector helper array - _mm_free(_vertices); - _arraySize = (mesh->vertices_POS.size() + 1) * 2; - _vertices = (XMVECTOR*)_mm_malloc(sizeof(XMVECTOR)*_arraySize, 16); - } - - XMMATRIX objectMat = object->getMatrix(); - XMMATRIX objectMat_Inverse = XMMatrixInverse(nullptr, objectMat); - - XMVECTOR rayOrigin_local = XMVector3Transform(rayOrigin, objectMat_Inverse); - XMVECTOR rayDirection_local = XMVector3Normalize(XMVector3TransformNormal(rayDirection, objectMat_Inverse)); - - Mesh::Vertex_FULL _tmpvert; - - if (object->isArmatureDeformed() && !object->mesh->armature->boneCollection.empty()) - { - for (size_t i = 0; i < mesh->vertices_POS.size(); ++i) + if (onlyVisible && object->IsOccluded() && GetOcclusionCullingEnabled()) { - _tmpvert = TransformVertex(mesh, (int)i); - _vertices[i] = XMLoadFloat4(&_tmpvert.pos); + continue; } - } - else if (mesh->hasDynamicVB()) - { - for (size_t i = 0; i < mesh->vertices_Transformed_POS.size(); ++i) - { - _vertices[i] = mesh->vertices_Transformed_POS[i].LoadPOS(); - } - } - else - { - for (size_t i = 0; i < mesh->vertices_POS.size(); ++i) - { - _vertices[i] = mesh->vertices_POS[i].LoadPOS(); - } - } - for (size_t i = 0; i < mesh->indices.size(); i += 3) - { - int i0 = mesh->indices[i], i1 = mesh->indices[i + 1], i2 = mesh->indices[i + 2]; - float distance; - if (TriangleTests::Intersects(rayOrigin_local, rayDirection_local, _vertices[i0], _vertices[i1], _vertices[i2], distance)) + Mesh* mesh = object->mesh; + if (mesh->vertices_POS.size() >= _arraySize) { - XMVECTOR& pos = XMVector3Transform(XMVectorAdd(rayOrigin_local, rayDirection_local*distance), objectMat); - XMVECTOR& nor = XMVector3TransformNormal(XMVector3Normalize(XMVector3Cross(XMVectorSubtract(_vertices[i2], _vertices[i1]), XMVectorSubtract(_vertices[i1], _vertices[i0]))), objectMat); - Picked picked = Picked(); - picked.transform = object; - picked.object = object; - XMStoreFloat3(&picked.position, pos); - XMStoreFloat3(&picked.normal, nor); - picked.distance = wiMath::Distance(pos, rayOrigin); - picked.subsetIndex = (int)mesh->vertices_FULL[i0].tex.z; - points.push_back(picked); + // grow preallocated vector helper array + _mm_free(_vertices); + _arraySize = (mesh->vertices_POS.size() + 1) * 2; + _vertices = (XMVECTOR*)_mm_malloc(sizeof(XMVECTOR)*_arraySize, 16); } + + XMMATRIX objectMat = object->getMatrix(); + XMMATRIX objectMat_Inverse = XMMatrixInverse(nullptr, objectMat); + + XMVECTOR rayOrigin_local = XMVector3Transform(rayOrigin, objectMat_Inverse); + XMVECTOR rayDirection_local = XMVector3Normalize(XMVector3TransformNormal(rayDirection, objectMat_Inverse)); + + Mesh::Vertex_FULL _tmpvert; + + if (object->isArmatureDeformed() && !object->mesh->armature->boneCollection.empty()) + { + for (size_t i = 0; i < mesh->vertices_POS.size(); ++i) + { + _tmpvert = TransformVertex(mesh, (int)i); + _vertices[i] = XMLoadFloat4(&_tmpvert.pos); + } + } + else if (mesh->hasDynamicVB()) + { + for (size_t i = 0; i < mesh->vertices_Transformed_POS.size(); ++i) + { + _vertices[i] = mesh->vertices_Transformed_POS[i].LoadPOS(); + } + } + else + { + for (size_t i = 0; i < mesh->vertices_POS.size(); ++i) + { + _vertices[i] = mesh->vertices_POS[i].LoadPOS(); + } + } + + for (size_t i = 0; i < mesh->indices.size(); i += 3) + { + int i0 = mesh->indices[i], i1 = mesh->indices[i + 1], i2 = mesh->indices[i + 2]; + float distance; + if (TriangleTests::Intersects(rayOrigin_local, rayDirection_local, _vertices[i0], _vertices[i1], _vertices[i2], distance)) + { + XMVECTOR& pos = XMVector3Transform(XMVectorAdd(rayOrigin_local, rayDirection_local*distance), objectMat); + XMVECTOR& nor = XMVector3Normalize(XMVector3TransformNormal(XMVector3Normalize(XMVector3Cross(XMVectorSubtract(_vertices[i2], _vertices[i1]), XMVectorSubtract(_vertices[i1], _vertices[i0]))), objectMat)); + Picked picked = Picked(); + picked.transform = object; + picked.object = object; + XMStoreFloat3(&picked.position, pos); + XMStoreFloat3(&picked.normal, nor); + picked.distance = wiMath::Distance(pos, rayOrigin); + picked.subsetIndex = (int)mesh->vertices_FULL[i0].tex.z; + points.push_back(picked); + } + } + } } diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index c94b89902..2193bf44c 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -595,11 +595,11 @@ public: // pickType: PICKTYPE enum values concatenated with | operator // layer : concatenated string of layers to check against, empty string : all layers will be checked // layerDisable : concatenated string of layers to NOT check against - static Picked Pick(long cursorX, long cursorY, int pickType = PICK_OPAQUE, const std::string& layer = "", const std::string& layerDisable = ""); - static Picked Pick(RAY& ray, int pickType = PICK_OPAQUE, const std::string& layer = "", const std::string& layerDisable = ""); + static Picked Pick(long cursorX, long cursorY, int pickType = PICK_OPAQUE, uint32_t layerMask = 0xFFFFFFFF); + static Picked Pick(RAY& ray, int pickType = PICK_OPAQUE, uint32_t layerMask = 0xFFFFFFFF); static RAY getPickRay(long cursorX, long cursorY); static void RayIntersectMeshes(const RAY& ray, const CulledList& culledObjects, std::vector& points, - int pickType = PICK_OPAQUE, bool dynamicObjects = true, const std::string& layer = "", const std::string& layerDisable = "", bool onlyVisible = false); + int pickType = PICK_OPAQUE, bool dynamicObjects = true, bool onlyVisible = false, uint32_t layerMask = 0xFFFFFFFF); static void CalculateVertexAO(Object* object); static PHYSICS* physicsEngine; diff --git a/WickedEngine/wiRenderer_BindLua.cpp b/WickedEngine/wiRenderer_BindLua.cpp index 523a046e7..9b0295c75 100644 --- a/WickedEngine/wiRenderer_BindLua.cpp +++ b/WickedEngine/wiRenderer_BindLua.cpp @@ -368,11 +368,6 @@ namespace wiRenderer_BindLua } return 0; } - int FinishLoading(lua_State* L) - { - wiRenderer::FinishLoading(); - return 0; - } int SetEnvironmentMap(lua_State* L) { int argc = wiLua::SGetArgCount(L); @@ -573,20 +568,17 @@ namespace wiRenderer_BindLua if (ray != nullptr) { int pickType = PICKTYPE::PICK_OPAQUE; - string layer = "", layerDisable = ""; + uint32_t layerMask = 0xFFFFFFFF; if (argc > 1) { pickType = wiLua::SGetInt(L, 2); if (argc > 2) { - layer = wiLua::SGetString(L, 3); - if (argc > 3) - { - layerDisable = wiLua::SGetString(L, 4); - } + int mask = wiLua::SGetInt(L, 3); + layerMask = *reinterpret_cast(&mask); } } - wiRenderer::Picked pick = wiRenderer::Pick(ray->ray, pickType, layer, layerDisable); + wiRenderer::Picked pick = wiRenderer::Pick(ray->ray, pickType, layerMask); Luna::push(L, new Object_BindLua(pick.object)); Luna::push(L, new Vector_BindLua(XMLoadFloat3(&pick.position))); Luna::push(L, new Vector_BindLua(XMLoadFloat3(&pick.normal))); @@ -742,7 +734,6 @@ namespace wiRenderer_BindLua wiLua::GetGlobal()->RegisterFunc("LoadModel", LoadModel); wiLua::GetGlobal()->RegisterFunc("LoadWorldInfo", LoadWorldInfo); - wiLua::GetGlobal()->RegisterFunc("FinishLoading", FinishLoading); wiLua::GetGlobal()->RegisterFunc("SetEnvironmentMap", SetEnvironmentMap); wiLua::GetGlobal()->RegisterFunc("SetColorGrading", SetColorGrading); wiLua::GetGlobal()->RegisterFunc("HairParticleSettings", HairParticleSettings); diff --git a/WickedEngine/wiTransform.cpp b/WickedEngine/wiTransform.cpp index 046d36ff3..182e03a08 100644 --- a/WickedEngine/wiTransform.cpp +++ b/WickedEngine/wiTransform.cpp @@ -12,16 +12,6 @@ Node::Node() { } -std::string Node::GetLayerID() -{ - auto x = name.find_last_of('_'); - if (x != std::string::npos) - { - return name.substr(x + 1); - } - return ""; -} - void Node::Serialize(wiArchive& archive) { if (archive.IsReadMode()) @@ -318,6 +308,14 @@ Transform* Transform::GetRoot() } return this; } +uint32_t Transform::GetLayerMask() +{ + if (parent != nullptr) + { + return parent->GetLayerMask() & Node::GetLayerMask(); + } + return Node::GetLayerMask(); +} void Transform::Serialize(wiArchive& archive) { Node::Serialize(archive); diff --git a/WickedEngine/wiTransform.h b/WickedEngine/wiTransform.h index 585d1772e..6ba317a3f 100644 --- a/WickedEngine/wiTransform.h +++ b/WickedEngine/wiTransform.h @@ -12,13 +12,15 @@ struct Node private: static std::atomic __Unique_ID_Counter; uint64_t ID; + uint32_t layerMask = 0xFFFFFFFF; // all layers enabled by default public: std::string name; Node(); + void SetLayerMask(uint32_t value) { layerMask = value; } + virtual uint32_t GetLayerMask() { return layerMask; } - std::string GetLayerID(); uint64_t GetID() { return ID; } void SetID(uint64_t newID) { ID = newID; } static const uint64_t INVALID_ID = UINT64_MAX; @@ -76,6 +78,8 @@ struct Transform : public Node virtual void UpdateTransform(); // Get the root of the tree Transform* GetRoot(); + // Layer mask with parent hierarchy masking + virtual uint32_t GetLayerMask() override; void Serialize(wiArchive& archive); }; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index e4ae9fbd9..56d117f6b 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 17; // minor bug fixes, alterations, refactors, updates - const int revision = 29; + const int revision = 30; long GetVersion()