From 4d1f4f96eb3472b13970dfa70eed09f49a41bce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Tue, 12 Dec 2023 20:30:50 +0100 Subject: [PATCH 1/5] Duplicate IDs will is no longer allowed --- Volt/Volt/src/Volt/Scene/Scene.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Volt/Volt/src/Volt/Scene/Scene.cpp b/Volt/Volt/src/Volt/Scene/Scene.cpp index 5d612efe8..86dd6346b 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.cpp +++ b/Volt/Volt/src/Volt/Scene/Scene.cpp @@ -369,7 +369,13 @@ namespace Volt } newEntity.AddComponent(); newEntity.AddComponent(); - newEntity.AddComponent(); + + auto& idComp = newEntity.AddComponent(); + + while (m_entityRegistry.Contains(idComp.id)) + { + idComp.id = {}; + } newEntity.GetComponent().layerId = m_sceneLayers.at(m_activeLayerIndex).id; newEntity.GetComponent().randomValue = Random::Float(0.f, 1.f); From 1914b0ea52b333d406e95685d50409eeb961cd44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Tue, 12 Dec 2023 21:23:41 +0100 Subject: [PATCH 2/5] Initial work on converting to meters --- .../Meshes/Primitives/SM_Capsule.fbx.vtmeta | 6 ++- .../Meshes/Primitives/SM_Capsule.vtmesh | 4 +- .../Primitives/SM_Capsule.vtmesh.vtmeta | 6 ++- .../Meshes/Primitives/SM_Cone.fbx.vtmeta | 6 ++- .../Engine/Meshes/Primitives/SM_Cone.vtmesh | 2 +- .../Meshes/Primitives/SM_Cone.vtmesh.vtmeta | 6 ++- Engine/Engine/Meshes/Primitives/SM_Cube.fbx | 4 +- .../Meshes/Primitives/SM_Cube.fbx.vtmeta | 6 ++- .../Engine/Meshes/Primitives/SM_Cube.vtmesh | 2 +- .../Meshes/Primitives/SM_Cube.vtmesh.vtmeta | 6 ++- .../Meshes/Primitives/SM_Cylinder.fbx.vtmeta | 6 ++- .../Meshes/Primitives/SM_Cylinder.vtmesh | 4 +- .../Primitives/SM_Cylinder.vtmesh.vtmeta | 6 ++- .../Meshes/Primitives/SM_Plane.fbx.vtmeta | 6 ++- .../Engine/Meshes/Primitives/SM_Plane.vtmesh | 2 +- .../Meshes/Primitives/SM_Plane.vtmesh.vtmeta | 6 ++- .../Meshes/Primitives/SM_Sphere.fbx.vtmeta | 6 ++- .../Engine/Meshes/Primitives/SM_Sphere.vtmesh | 4 +- .../Meshes/Primitives/SM_Sphere.vtmesh.vtmeta | 6 ++- .../Shaders/Source/HLSL/Editor/Grid_ps.hlsl | 6 +-- Engine/Scripts/Volt-ScriptCore.dll | 4 +- Engine/Scripts/Volt-ScriptCore.pdb | 4 +- .../Sandbox/Camera/EditorCameraController.cpp | 6 ++- .../Sandbox/Camera/EditorCameraController.h | 16 +++---- Volt/Sandbox/src/Sandbox/DebugRendering.cpp | 12 +++--- Volt/Sandbox/src/Sandbox/Sandbox.cpp | 2 +- .../Sandbox/Window/CharacterEditorPanel.cpp | 2 +- .../src/Sandbox/Window/MeshPreviewPanel.cpp | 2 +- .../Sandbox/Window/ParticleEmitterEditor.cpp | 2 +- .../src/Sandbox/Window/PrefabEditorPanel.cpp | 2 +- .../src/Sandbox/Window/ViewportPanel.h | 2 +- .../src/Volt/Components/LightComponents.h | 20 ++++----- .../Volt/Components/NavigationComponents.h | 16 +++---- .../src/Volt/Components/PhysicsComponents.h | 42 +++++++++---------- .../src/Volt/Components/RenderingComponents.h | 8 ++-- Volt/Volt/src/Volt/Physics/Physics.cpp | 6 +-- Volt/Volt/src/Volt/Physics/PhysicsScene.cpp | 2 +- Volt/Volt/src/Volt/Physics/PhysicsSettings.h | 6 +-- Volt/Volt/src/Volt/Rendering/Shape.cpp | 18 ++++---- Volt/Volt/src/Volt/Scene/Scene.cpp | 2 +- Volt/Volt/vendor/TGAFbx/src/Importer.cpp | 6 +-- 41 files changed, 153 insertions(+), 127 deletions(-) diff --git a/Engine/Engine/Meshes/Primitives/SM_Capsule.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Capsule.fbx.vtmeta index e6b8125e3..c545e5de3 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Capsule.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Capsule.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 7368991460119830626 + assetHandle: 6283149130508796929 filePath: Engine/Meshes/Primitives/SM_Capsule.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh index 246de04db..2a6f8ce3a 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:afcd2adde3c4247507899c6a6d53e5033cd959ab27474695aa2c9b8b4b538186 -size 27479 +oid sha256:1ccf6635a7516da564f63f4129fb0c3b3bbffdbfcf41a41252fe77bb7f1f5dd4 +size 42935 diff --git a/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh.vtmeta index 9fb51b643..4645818a5 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Capsule.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 18411356710391823355 + assetHandle: 10117410387453422377 filePath: Engine/Meshes/Primitives/SM_Capsule.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cone.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cone.fbx.vtmeta index b429ec6e8..d64e26b29 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cone.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cone.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 5244042238809914408 + assetHandle: 4608470111307946929 filePath: Engine/Meshes/Primitives/SM_Cone.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh index 4df39500d..8c7642b9e 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8354b65f1129201605e654f4c5babb17701dcb43e48e92764d5da6cfae8bbef +oid sha256:7898416a08ebdf0b7eba8d759b95d4a18c23d425eb44fc32d4dbc68d213f501c size 3782 diff --git a/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh.vtmeta index e2bc4a11e..63fb3f866 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cone.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 10242065537839545921 + assetHandle: 6968151257201624914 filePath: Engine/Meshes/Primitives/SM_Cone.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cube.fbx b/Engine/Engine/Meshes/Primitives/SM_Cube.fbx index d60dbb45c..5614568f1 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cube.fbx +++ b/Engine/Engine/Meshes/Primitives/SM_Cube.fbx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6fc1bc85447adf68aa69796e411fc6ece1b74eae959770536191531a2a1226b -size 21568 +oid sha256:877d50c08bf2c65a7db1e0d766bbb596677f115ecb17df6b00c35e028ec06251 +size 14844 diff --git a/Engine/Engine/Meshes/Primitives/SM_Cube.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cube.fbx.vtmeta index 1422f2f2b..16744ba27 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cube.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cube.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 6184134929358402430 + assetHandle: 16422502198230809186 filePath: Engine/Meshes/Primitives/SM_Cube.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh index f2f439f60..085152353 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0158934705a4b87e110a2a43710832247e8b2a6ea2e15370dacfe96d33fa70a9 +oid sha256:efd043d68900a0719ba947cb7c09f00b9100ad5a249c933ee9f4b2e008a88c7a size 2100 diff --git a/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh.vtmeta index 980fed766..dd746890f 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cube.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 10149696181569838305 + assetHandle: 7235711071482003307 filePath: Engine/Meshes/Primitives/SM_Cube.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cylinder.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cylinder.fbx.vtmeta index de8ba4b5f..bf80955a3 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cylinder.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cylinder.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 9963684909373996543 + assetHandle: 6095984363745051238 filePath: Engine/Meshes/Primitives/SM_Cylinder.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh index b06c45803..47586988b 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9f95d8252a8e62dffc35788e7e40c1b2e2238057de7527e087bdcec986a0857 -size 7480 +oid sha256:a9988f9894d2bcf9128f70cd29a21b2b0a431e9ed8fd1a1545df042772cee17b +size 8392 diff --git a/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh.vtmeta index 3fecbd4b0..dc43799ab 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Cylinder.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 2900881217054044389 + assetHandle: 9258625515238793615 filePath: Engine/Meshes/Primitives/SM_Cylinder.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Plane.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Plane.fbx.vtmeta index 0228a3a5e..1580bd50a 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Plane.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Plane.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 13661243206498577773 + assetHandle: 15731543908010069181 filePath: Engine/Meshes/Primitives/SM_Plane.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh index ae2dada53..0898aadd1 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd0318367487783aa749719e984b7d543eb0ea04366274294a4267bee6e18893 +oid sha256:50b004b989eeca3447a37bc4a1071fb67afda627424c7886ab0f8416a3030674 size 461 diff --git a/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh.vtmeta index 93dd3b573..85dd6d344 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Plane.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 3087037750680072373 + assetHandle: 7102265901469832403 filePath: Engine/Meshes/Primitives/SM_Plane.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Sphere.fbx.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Sphere.fbx.vtmeta index cbeb8424d..12ecb7549 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Sphere.fbx.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Sphere.fbx.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 16599656187294192819 + assetHandle: 11824673864998436943 filePath: Engine/Meshes/Primitives/SM_Sphere.fbx type: 2 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh b/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh index 0f1c7bdcd..3440f5c6b 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh +++ b/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d69fb924135234ee8cb880be2bb9bd4bc95039baaae4e6d15e9bab881b25c997 -size 99554 +oid sha256:fb442f6d67fb9b56baba924360c743429c3cc6320dd5149a4f172d561452019c +size 162146 diff --git a/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh.vtmeta b/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh.vtmeta index ef53b06c0..e13f1bfb6 100644 --- a/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh.vtmeta +++ b/Engine/Engine/Meshes/Primitives/SM_Sphere.vtmesh.vtmeta @@ -1,6 +1,8 @@ Metadata: - assetHandle: 12441354821563457429 + assetHandle: 11830290587447924398 filePath: Engine/Meshes/Primitives/SM_Sphere.vtmesh type: 1 Dependencies: - [] \ No newline at end of file + [] + Properties: + {} \ No newline at end of file diff --git a/Engine/Engine/Shaders/Source/HLSL/Editor/Grid_ps.hlsl b/Engine/Engine/Shaders/Source/HLSL/Editor/Grid_ps.hlsl index b9b5cbd06..55d2e70e2 100644 --- a/Engine/Engine/Shaders/Source/HLSL/Editor/Grid_ps.hlsl +++ b/Engine/Engine/Shaders/Source/HLSL/Editor/Grid_ps.hlsl @@ -28,13 +28,13 @@ float4 Grid(float3 position, float scale) float4 color = float4(0.2f, 0.2f, 0.2f, 1.f - min(lin, 1.f)); // Z axis - if (position.x > -100.f * minX && position.x < 100.f * minX) + if (position.x > -1.f * minX && position.x < 1.f * minX) { color.z = 1.f; } // X axis - if (position.z > -100.f * minZ && position.z < 100.f * minZ) + if (position.z > -1.f * minZ && position.z < 1.f * minZ) { color.x = 1.f; } @@ -66,7 +66,7 @@ Output main(Input input) const float fading = max(0.f, (0.5f - linearDepth)); Output output; - output.color = Grid(position, 0.01f) * float(t > 0); + output.color = Grid(position, 1.f) * float(t > 0); output.color.a *= fading; output.depth = ComputeDepth(position); diff --git a/Engine/Scripts/Volt-ScriptCore.dll b/Engine/Scripts/Volt-ScriptCore.dll index 0841805f0..223920832 100644 --- a/Engine/Scripts/Volt-ScriptCore.dll +++ b/Engine/Scripts/Volt-ScriptCore.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37a52072a1c89918403c47c876e2781554f59967ad83c293b87f442ccbe643e7 -size 95744 +oid sha256:d8920b464cbd4a15fd79b405d04043221e662f4d0b456f0baa88151c71a086ac +size 102912 diff --git a/Engine/Scripts/Volt-ScriptCore.pdb b/Engine/Scripts/Volt-ScriptCore.pdb index 245d276af..0b7f677ce 100644 --- a/Engine/Scripts/Volt-ScriptCore.pdb +++ b/Engine/Scripts/Volt-ScriptCore.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e37d496947f36ac305ec4963c1e68ad3e568ede404666aa326e6fc3532695707 -size 37372 +oid sha256:3df4e530c7a18b06017729e2bb78025940e94a5fd3c0b2d668a89dfbc03146a6 +size 47788 diff --git a/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.cpp b/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.cpp index 316fc006f..ba306df2b 100644 --- a/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.cpp +++ b/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.cpp @@ -17,7 +17,7 @@ EditorCameraController::EditorCameraController(float fov, float nearPlane, float farPlane) : m_fov(fov), m_nearPlane(nearPlane), m_farPlane(farPlane) { - const glm::vec3 startPosition = { 500.f, 500.f, 500.f }; + const glm::vec3 startPosition = { 5.f, 5.f, 5.f }; m_focalDistance = glm::distance(startPosition, m_focalPoint); m_rotation = { 45.f, 135.f, 0.f }; m_position = startPosition; @@ -111,10 +111,12 @@ void EditorCameraController::ArcBall(const glm::vec2& deltaPos) void EditorCameraController::ArcZoom(float deltaPos) { + constexpr float MAX_SPEED = 0.1f; + float distance = m_focalDistance * 0.2f; distance = glm::max(distance, 0.0f); float speed = distance * distance; - speed = glm::min(speed, 10.f); // max speed = 50 + speed = glm::min(speed, MAX_SPEED); // max speed = 50 m_focalDistance -= deltaPos * speed; m_position = m_focalPoint - m_camera->GetForward() * m_focalDistance; diff --git a/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.h b/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.h index ee805afc4..c9e226388 100644 --- a/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.h +++ b/Volt/Sandbox/src/Sandbox/Camera/EditorCameraController.h @@ -62,18 +62,18 @@ class EditorCameraController float m_yawDelta = 0.f; glm::vec3 m_focalPoint = { 0.f, 0.f, 0.f }; - float m_focalDistance = 100.f; - float m_minFocalDistance = 10000.f; + float m_focalDistance = 1.f; + float m_minFocalDistance = 100.f; float m_fov = 45.f; - float m_nearPlane = 0.1f; - float m_farPlane = 10000.f; + float m_nearPlane = 0.01f; + float m_farPlane = 1000.f; - float m_translationSpeed = 100.f; - float m_scrollTranslationSpeed = 100.f; + float m_translationSpeed = 5.f; - float m_maxTranslationSpeed = 100000.f; - float m_sensitivity = 0.12f; + const float m_scrollTranslationSpeed = 1.f; + const float m_maxTranslationSpeed = 40.f; + const float m_sensitivity = 0.12f; bool m_isControllable = false; bool m_isViewportHovered = false; diff --git a/Volt/Sandbox/src/Sandbox/DebugRendering.cpp b/Volt/Sandbox/src/Sandbox/DebugRendering.cpp index 241dd6d3c..d2ec54a53 100644 --- a/Volt/Sandbox/src/Sandbox/DebugRendering.cpp +++ b/Volt/Sandbox/src/Sandbox/DebugRendering.cpp @@ -90,8 +90,8 @@ void Sandbox::RenderGizmos(Ref scene, Ref camera) glm::vec3 p = entity.GetPosition(); - const float maxDist = 5000.f * 5000.f; - const float lerpStartDist = 4000.f * 4000.f; + const float maxDist = 50.f * 50.f; + const float lerpStartDist = 40.f * 40.f; const float maxScale = 1.f; const float minScale = 0.3f; const float distance = glm::distance2(camera->GetPosition(), p); @@ -124,8 +124,8 @@ void Sandbox::RenderGizmos(Ref scene, Ref camera) glm::vec3 p = entity.GetPosition(); - const float maxDist = 5000.f; - const float lerpStartDist = 4000.f; + const float maxDist = 50.f; + const float lerpStartDist = 40.f; const float maxScale = 1.f; const float distance = glm::distance(camera->GetPosition(), p); @@ -154,8 +154,8 @@ void Sandbox::RenderGizmos(Ref scene, Ref camera) glm::vec3 p = entity.GetPosition(); - const float maxDist = 5000.f; - const float lerpStartDist = 4000.f; + const float maxDist = 50.f; + const float lerpStartDist = 40.f; const float maxScale = 1.f; const float distance = glm::distance(camera->GetPosition(), p); diff --git a/Volt/Sandbox/src/Sandbox/Sandbox.cpp b/Volt/Sandbox/src/Sandbox/Sandbox.cpp index 341f964fb..f32e04fd1 100644 --- a/Volt/Sandbox/src/Sandbox/Sandbox.cpp +++ b/Volt/Sandbox/src/Sandbox/Sandbox.cpp @@ -110,7 +110,7 @@ void Sandbox::OnAttach() Volt::Application::Get().GetWindow().Maximize(); - myEditorCameraController = CreateRef(60.f, 1.f, 100000.f); + myEditorCameraController = CreateRef(60.f, 0.01f, 1000.f); UserSettingsManager::LoadUserSettings(); const auto& userSettings = UserSettingsManager::GetSettings(); diff --git a/Volt/Sandbox/src/Sandbox/Window/CharacterEditorPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/CharacterEditorPanel.cpp index 2ce1acf46..6a266e2cd 100644 --- a/Volt/Sandbox/src/Sandbox/Window/CharacterEditorPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/CharacterEditorPanel.cpp @@ -32,7 +32,7 @@ CharacterEditorPanel::CharacterEditorPanel() : EditorWindow("Character Editor", true) { m_windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; - myCameraController = CreateRef(60.f, 1.f, 100000.f); + myCameraController = CreateRef(60.f, 0.01f, 1000.f); myScene = Volt::Scene::CreateDefaultScene("Character Editor", false); diff --git a/Volt/Sandbox/src/Sandbox/Window/MeshPreviewPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/MeshPreviewPanel.cpp index 3aff09daf..589b794c6 100644 --- a/Volt/Sandbox/src/Sandbox/Window/MeshPreviewPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/MeshPreviewPanel.cpp @@ -23,7 +23,7 @@ MeshPreviewPanel::MeshPreviewPanel() : EditorWindow("Mesh Preview", true) { - myCameraController = CreateRef(60.f, 1.f, 100000.f); + myCameraController = CreateRef(60.f, 0.01f, 1000.f); myScene = Volt::Scene::CreateDefaultScene("Mesh Preview", false); // Preview entity diff --git a/Volt/Sandbox/src/Sandbox/Window/ParticleEmitterEditor.cpp b/Volt/Sandbox/src/Sandbox/Window/ParticleEmitterEditor.cpp index c61690623..327894f97 100644 --- a/Volt/Sandbox/src/Sandbox/Window/ParticleEmitterEditor.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/ParticleEmitterEditor.cpp @@ -21,7 +21,7 @@ ParticleEmitterEditor::ParticleEmitterEditor() : EditorWindow("Particle Editor") { m_windowFlags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; - myCameraController = CreateRef(60.f, 1.f, 100000.f); + myCameraController = CreateRef(60.f, 0.01f, 1000.f); myPreviewScene = Volt::Scene::CreateDefaultScene("Particle Editor", false); myReferenceModel = myPreviewScene->CreateEntity("Reference Entity"); myReferenceModel.AddComponent(); diff --git a/Volt/Sandbox/src/Sandbox/Window/PrefabEditorPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/PrefabEditorPanel.cpp index 7491187ae..349954e45 100644 --- a/Volt/Sandbox/src/Sandbox/Window/PrefabEditorPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/PrefabEditorPanel.cpp @@ -24,7 +24,7 @@ PrefabEditorPanel::PrefabEditorPanel() : EditorWindow("Prefab Editor", true) { - myCameraController = CreateRef(60.f, 1.f, 100000.f); + myCameraController = CreateRef(60.f, 0.01f, 1000.f); myScene = Volt::Scene::CreateDefaultScene("Prefab Editor", false); myScene->Clear(); diff --git a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.h b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.h index 70257e0e3..5214d743f 100644 --- a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.h +++ b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.h @@ -76,7 +76,7 @@ class ViewportPanel : public EditorWindow ImGuizmo::OPERATION m_gizmoOperation = ImGuizmo::OPERATION::TRANSLATE; SceneState& m_sceneState; - const std::vector m_snapToGridValues = { 1.f, 10.f, 25.f, 50.f, 100.f, 200.f, 500.f, 1000.f }; + const std::vector m_snapToGridValues = { 0.01f, 0.1f, 0.25f, 0.50f, 1.f, 2.f, 5.f, 10.f }; const std::vector m_snapRotationValues = { 10.f, 30.f, 45.f, 90.f }; const std::vector m_snapScaleValues = { 0.01f, 0.1f, 0.25f, 0.5f, 1.f }; diff --git a/Volt/Volt/src/Volt/Components/LightComponents.h b/Volt/Volt/src/Volt/Components/LightComponents.h index fe0cd6f16..63136dd5a 100644 --- a/Volt/Volt/src/Volt/Components/LightComponents.h +++ b/Volt/Volt/src/Volt/Components/LightComponents.h @@ -12,7 +12,7 @@ namespace Volt struct PointLightComponent { float intensity = 1.f; - float radius = 100.f; + float radius = 1.f; float falloff = 1.f; glm::vec3 color = { 1.f, 1.f, 1.f }; bool castShadows = false; @@ -23,7 +23,7 @@ namespace Volt reflect.SetGUID("{A30A8848-A30B-41DD-80F9-4E163C01ABC2}"_guid); reflect.SetLabel("Point Light Component"); reflect.AddMember(&PointLightComponent::intensity, "intensity", "Intensity", "", 1.f); - reflect.AddMember(&PointLightComponent::radius, "radius", "Radius", "", 100.f); + reflect.AddMember(&PointLightComponent::radius, "radius", "Radius", "", 1.f); reflect.AddMember(&PointLightComponent::falloff, "falloff", "Falloff", "", 1.f); reflect.AddMember(&PointLightComponent::color, "color", "Color", "", glm::vec3{ 1.f }, ComponentMemberFlag::Color3); reflect.AddMember(&PointLightComponent::castShadows, "castShadows", "Cast Shadows", "", false); @@ -37,7 +37,7 @@ namespace Volt { float intensity = 1.f; float angle = 45.f; - float range = 100.f; + float range = 1.f; float angleAttenuation = 1.f; float falloff = 1.f; glm::vec3 color = { 1.f, 1.f, 1.f }; @@ -49,7 +49,7 @@ namespace Volt reflect.SetLabel("Spot Light Component"); reflect.AddMember(&SpotLightComponent::intensity, "intensity", "Intensity", "", 1.f); reflect.AddMember(&SpotLightComponent::angle, "angle", "Angle", "", 45.f); - reflect.AddMember(&SpotLightComponent::range, "range", "Range", "", 100.f); + reflect.AddMember(&SpotLightComponent::range, "range", "Range", "", 1.f); reflect.AddMember(&SpotLightComponent::angleAttenuation, "angleAttenuation", "Angle Attenuation", "", 1.f); reflect.AddMember(&SpotLightComponent::falloff, "falloff", "Falloff", "", 1.f); reflect.AddMember(&SpotLightComponent::color, "color", "Color", "", glm::vec3{ 1.f }, ComponentMemberFlag::Color3); @@ -62,7 +62,7 @@ namespace Volt struct SphereLightComponent { float intensity = 1.f; - float radius = 50.f; + float radius = 0.5f; glm::vec3 color = { 1.f, 1.f, 1.f }; static void ReflectType(TypeDesc& reflect) @@ -70,7 +70,7 @@ namespace Volt reflect.SetGUID("{0D0CEEE2-A331-442A-BB4B-FBDB8E06C692}"_guid); reflect.SetLabel("Sphere Light Component"); reflect.AddMember(&SphereLightComponent::intensity, "intensity", "Intensity", "", 1.f); - reflect.AddMember(&SphereLightComponent::radius, "radius", "Radius", "", 50.f); + reflect.AddMember(&SphereLightComponent::radius, "radius", "Radius", "", 0.5f); reflect.AddMember(&SphereLightComponent::color, "color", "Color", "", glm::vec3{ 1.f }, ComponentMemberFlag::Color3); } @@ -81,8 +81,8 @@ namespace Volt { float intensity = 1.f; glm::vec3 color = { 1.f, 1.f, 1.f }; - float width = 50.f; - float height = 50.f; + float width = 0.5f; + float height = 0.5f; static void ReflectType(TypeDesc& reflect) { @@ -90,8 +90,8 @@ namespace Volt reflect.SetLabel("Rectangle Light Component"); reflect.AddMember(&RectangleLightComponent::intensity, "intensity", "Intensity", "", 1.f); reflect.AddMember(&RectangleLightComponent::color, "color", "Color", "", glm::vec3{ 1.f }, ComponentMemberFlag::Color3); - reflect.AddMember(&RectangleLightComponent::width, "width", "Width", "", 50.f); - reflect.AddMember(&RectangleLightComponent::height, "height", "Height", "", 50.f); + reflect.AddMember(&RectangleLightComponent::width, "width", "Width", "", 0.5f); + reflect.AddMember(&RectangleLightComponent::height, "height", "Height", "", 0.5f); } REGISTER_COMPONENT(RectangleLightComponent); diff --git a/Volt/Volt/src/Volt/Components/NavigationComponents.h b/Volt/Volt/src/Volt/Components/NavigationComponents.h index 195ca4729..a1332a087 100644 --- a/Volt/Volt/src/Volt/Components/NavigationComponents.h +++ b/Volt/Volt/src/Volt/Components/NavigationComponents.h @@ -63,10 +63,10 @@ namespace Volt struct NavAgentComponent { - float radius = 60.f; - float height = 200.f; - float maxSpeed = 300.f; - float acceleration = 1000.f; + float radius = 0.6f; + float height = 2.f; + float maxSpeed = 3.f; + float acceleration = 10.f; float separationWeight = 0.f; ObstacleAvoidanceQuality obstacleAvoidanceQuality = ObstacleAvoidanceQuality::None; bool active = true; @@ -75,10 +75,10 @@ namespace Volt { reflect.SetGUID("{2B4469CE-9B15-4FA9-ABA6-77BA83465357}"_guid); reflect.SetLabel("Nav Agent Component"); - reflect.AddMember(&NavAgentComponent::radius, "radius", "Radius", "", 60.f); - reflect.AddMember(&NavAgentComponent::height, "height", "Height", "", 200.f); - reflect.AddMember(&NavAgentComponent::maxSpeed, "maxSpeed", "Max Speed", "", 300.f); - reflect.AddMember(&NavAgentComponent::acceleration, "acceleration", "Acceleration", "", 1000.f); + reflect.AddMember(&NavAgentComponent::radius, "radius", "Radius", "", 0.6f); + reflect.AddMember(&NavAgentComponent::height, "height", "Height", "", 2.f); + reflect.AddMember(&NavAgentComponent::maxSpeed, "maxSpeed", "Max Speed", "", 3.f); + reflect.AddMember(&NavAgentComponent::acceleration, "acceleration", "Acceleration", "", 10.f); reflect.AddMember(&NavAgentComponent::separationWeight, "seperationWeight", "Seperation Weight", "", 0.f); reflect.AddMember(&NavAgentComponent::obstacleAvoidanceQuality, "obstacleAvoidanceQuality", "Obstacle Avoidance Quality", "", ObstacleAvoidanceQuality::None); reflect.AddMember(&NavAgentComponent::active, "active", "Active", "", false); diff --git a/Volt/Volt/src/Volt/Components/PhysicsComponents.h b/Volt/Volt/src/Volt/Components/PhysicsComponents.h index 37325e67d..2057b27c7 100644 --- a/Volt/Volt/src/Volt/Components/PhysicsComponents.h +++ b/Volt/Volt/src/Volt/Components/PhysicsComponents.h @@ -12,16 +12,16 @@ namespace Volt ClimbingMode climbingMode = ClimbingMode::Normal; float slopeLimit = 20.f; - float invisibleWallHeight = 200.f; - float maxJumpHeight = 100.f; - float contactOffset = 1.f; - float stepOffset = 10.f; + float invisibleWallHeight = 2.f; + float maxJumpHeight = 1.f; + float contactOffset = 0.01f; + float stepOffset = 0.1f; float density = 1.f; uint32_t layer = 0; bool hasGravity = true; - inline CharacterControllerComponent(ClimbingMode aClimbingMode = ClimbingMode::Normal, float aSlopeLimit = 20.f, float aInvisibleWallHeight = 200.f, float aMaxJumpHeight = 100.f, - float aContactOffset = 1.f, float aStepOffset = 10.f, float aDensity = 1.f, uint32_t aLayer = 0, bool aHasGravity = true) + inline CharacterControllerComponent(ClimbingMode aClimbingMode = ClimbingMode::Normal, float aSlopeLimit = 20.f, float aInvisibleWallHeight = 2.f, float aMaxJumpHeight = 1.f, + float aContactOffset = 0.01f, float aStepOffset = 0.1f, float aDensity = 1.f, uint32_t aLayer = 0, bool aHasGravity = true) : climbingMode(aClimbingMode), slopeLimit(aSlopeLimit), invisibleWallHeight(aInvisibleWallHeight), maxJumpHeight(aMaxJumpHeight), contactOffset(aContactOffset), stepOffset(aStepOffset), density(aDensity), layer(aLayer), hasGravity(aHasGravity) { } @@ -32,10 +32,10 @@ namespace Volt reflect.SetLabel("Character Controller Component"); reflect.AddMember(&CharacterControllerComponent::climbingMode, "climbingMode", "Climbing Mode", "", ClimbingMode::Normal); reflect.AddMember(&CharacterControllerComponent::slopeLimit, "slopeLimit", "Slope Limit", "", 20.f); - reflect.AddMember(&CharacterControllerComponent::invisibleWallHeight, "invisibleWallHeight", "Invisible Wall Height", "", 200.f); - reflect.AddMember(&CharacterControllerComponent::maxJumpHeight, "maxJumpHeight", "Max Jump Height", "", 100.f); - reflect.AddMember(&CharacterControllerComponent::contactOffset, "contactOffset", "Contact Offset", "", 1.f); - reflect.AddMember(&CharacterControllerComponent::stepOffset, "stepOffset", "Step Offset", "", 10.f); + reflect.AddMember(&CharacterControllerComponent::invisibleWallHeight, "invisibleWallHeight", "Invisible Wall Height", "", 2.f); + reflect.AddMember(&CharacterControllerComponent::maxJumpHeight, "maxJumpHeight", "Max Jump Height", "", 1.f); + reflect.AddMember(&CharacterControllerComponent::contactOffset, "contactOffset", "Contact Offset", "", 0.01f); + reflect.AddMember(&CharacterControllerComponent::stepOffset, "stepOffset", "Step Offset", "", 0.1f); reflect.AddMember(&CharacterControllerComponent::density, "density", "Density", "", 1.f); reflect.AddMember(&CharacterControllerComponent::layer, "layer", "Layer", "", 0); reflect.AddMember(&CharacterControllerComponent::hasGravity, "hasGravity", "Has Gravity", "", true); @@ -84,14 +84,14 @@ namespace Volt struct BoxColliderComponent { - glm::vec3 halfSize = { 50.f, 50.f, 50.f }; + glm::vec3 halfSize = { 0.5f, 0.5f, 0.5f }; glm::vec3 offset = { 0.f, 0.f, 0.f }; bool isTrigger = false; AssetHandle material = Asset::Null(); bool added = false; - inline BoxColliderComponent(const glm::vec3& aHalfSize = { 50.f, 50.f, 50.f }, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) + inline BoxColliderComponent(const glm::vec3& aHalfSize = { 0.5f, 0.5f, 0.5f }, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) : halfSize(aHalfSize), offset(aOffset), isTrigger(aIsTrigger), material(aMaterial) { } @@ -100,7 +100,7 @@ namespace Volt { reflect.SetGUID("{29707475-D536-4DA4-8D3A-A98948C89A5}"_guid); reflect.SetLabel("Box Collider Component"); - reflect.AddMember(&BoxColliderComponent::halfSize, "halfSize", "Half Size", "", glm::vec3{ 50.f }); + reflect.AddMember(&BoxColliderComponent::halfSize, "halfSize", "Half Size", "", glm::vec3{ 0.5f }); reflect.AddMember(&BoxColliderComponent::offset, "offset", "Offset", "", glm::vec3{ 0.f }); reflect.AddMember(&BoxColliderComponent::isTrigger, "isTrigger", "Is Trigger", "", false); reflect.AddMember(&BoxColliderComponent::material, "material", "Material", "", Asset::Null(), AssetType::PhysicsMaterial); @@ -111,14 +111,14 @@ namespace Volt struct SphereColliderComponent { - float radius = 50.f; + float radius = 0.5f; glm::vec3 offset = { 0.f, 0.f, 0.f }; bool isTrigger = false; AssetHandle material = Asset::Null(); bool added = false; - inline SphereColliderComponent(float aRadius = 50.f, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) + inline SphereColliderComponent(float aRadius = 0.5f, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) : radius(aRadius), offset(aOffset), isTrigger(aIsTrigger), material(aMaterial) { } @@ -127,7 +127,7 @@ namespace Volt { reflect.SetGUID("{90246BCE-FF83-41A2-A076-AB0A947C0D6A}"_guid); reflect.SetLabel("Sphere Collider Component"); - reflect.AddMember(&SphereColliderComponent::radius, "radius", "Radius", "", 50.f); + reflect.AddMember(&SphereColliderComponent::radius, "radius", "Radius", "", 0.5f); reflect.AddMember(&SphereColliderComponent::offset, "offset", "Offset", "", glm::vec3{ 0.f }); reflect.AddMember(&SphereColliderComponent::isTrigger, "isTrigger", "Is Trigger", "", false); reflect.AddMember(&SphereColliderComponent::material, "material", "Material", "", Asset::Null(), AssetType::PhysicsMaterial); @@ -138,15 +138,15 @@ namespace Volt struct CapsuleColliderComponent { - float radius = 50.f; - float height = 50.f; + float radius = 0.5f; + float height = 0.5f; glm::vec3 offset = { 0.f, 0.f, 0.f }; bool isTrigger = false; AssetHandle material = Asset::Null(); bool added = false; - inline CapsuleColliderComponent(float aRadius = 50.f, float aHeight = 50.f, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) + inline CapsuleColliderComponent(float aRadius = 0.5f, float aHeight = 0.5f, const glm::vec3& aOffset = { 0.f }, bool aIsTrigger = false, AssetHandle aMaterial = Asset::Null()) : radius(aRadius), height(aHeight), offset(aOffset), isTrigger(aIsTrigger), material(aMaterial) { } @@ -155,8 +155,8 @@ namespace Volt { reflect.SetGUID("{54A48952-7A77-492B-8A9C-2440D82EE5E2}"_guid); reflect.SetLabel("Capsule Collider Component"); - reflect.AddMember(&CapsuleColliderComponent::radius, "radius", "Radius", "", 50.f); - reflect.AddMember(&CapsuleColliderComponent::height, "height", "Height", "", 50.f); + reflect.AddMember(&CapsuleColliderComponent::radius, "radius", "Radius", "", 0.5f); + reflect.AddMember(&CapsuleColliderComponent::height, "height", "Height", "", 0.5f); reflect.AddMember(&CapsuleColliderComponent::offset, "offset", "Offset", "", glm::vec3{ 0.f }); reflect.AddMember(&CapsuleColliderComponent::isTrigger, "isTrigger", "Is Trigger", "", false); reflect.AddMember(&CapsuleColliderComponent::material, "material", "Material", "", Asset::Null(), AssetType::PhysicsMaterial); diff --git a/Volt/Volt/src/Volt/Components/RenderingComponents.h b/Volt/Volt/src/Volt/Components/RenderingComponents.h index 42ca39921..3b0a4c7b9 100644 --- a/Volt/Volt/src/Volt/Components/RenderingComponents.h +++ b/Volt/Volt/src/Volt/Components/RenderingComponents.h @@ -32,8 +32,8 @@ namespace Volt struct CameraComponent { float fieldOfView = 60.f; - float nearPlane = 1.f; - float farPlane = 100'000.f; + float nearPlane = 0.01f; + float farPlane = 1000.f; uint32_t priority = 0; Ref camera; @@ -43,8 +43,8 @@ namespace Volt reflect.SetGUID("{9258BEEC-3A31-4CAB-AB1E-654524E1C398}"_guid); reflect.SetLabel("Camera Component"); reflect.AddMember(&CameraComponent::fieldOfView, "fieldOfView", "Field Of View", "", 60.f); - reflect.AddMember(&CameraComponent::nearPlane, "nearPlane", "Near Plane", "", 1.f); - reflect.AddMember(&CameraComponent::farPlane, "farPlane", "Far Plane", "", 100'000.f); + reflect.AddMember(&CameraComponent::nearPlane, "nearPlane", "Near Plane", "", 0.01f); + reflect.AddMember(&CameraComponent::farPlane, "farPlane", "Far Plane", "", 1000.f); reflect.AddMember(&CameraComponent::priority, "priority", "Priority", "", 0); } diff --git a/Volt/Volt/src/Volt/Physics/Physics.cpp b/Volt/Volt/src/Volt/Physics/Physics.cpp index 9b4ba5d28..cdb5ae3bd 100644 --- a/Volt/Volt/src/Volt/Physics/Physics.cpp +++ b/Volt/Volt/src/Volt/Physics/Physics.cpp @@ -53,9 +53,9 @@ namespace Volt YAML::Node root = YAML::Load(sstream.str()); YAML::Node settingsNode = root["PhysicsSettings"]; - VT_DESERIALIZE_PROPERTY(gravity, mySettings.gravity, settingsNode, glm::vec3(0.f, -981.f, 0.f)); - VT_DESERIALIZE_PROPERTY(worldBoundsMin, mySettings.worldBoundsMin, settingsNode, glm::vec3(-100000.f)); - VT_DESERIALIZE_PROPERTY(worldBoundsMax, mySettings.worldBoundsMax, settingsNode, glm::vec3(100000.f)); + VT_DESERIALIZE_PROPERTY(gravity, mySettings.gravity, settingsNode, glm::vec3(0.f, -9.81f, 0.f)); + VT_DESERIALIZE_PROPERTY(worldBoundsMin, mySettings.worldBoundsMin, settingsNode, glm::vec3(-100.f)); + VT_DESERIALIZE_PROPERTY(worldBoundsMax, mySettings.worldBoundsMax, settingsNode, glm::vec3(100.f)); VT_DESERIALIZE_PROPERTY(worldBoundsSubDivisions, mySettings.worldBoundsSubDivisions, settingsNode, 2); VT_DESERIALIZE_PROPERTY(solverIterations, mySettings.solverIterations, settingsNode, 8); VT_DESERIALIZE_PROPERTY(solverVelocityIterations, mySettings.solverVelocityIterations, settingsNode, 2); diff --git a/Volt/Volt/src/Volt/Physics/PhysicsScene.cpp b/Volt/Volt/src/Volt/Physics/PhysicsScene.cpp index 8ce052002..e931cc817 100644 --- a/Volt/Volt/src/Volt/Physics/PhysicsScene.cpp +++ b/Volt/Volt/src/Volt/Physics/PhysicsScene.cpp @@ -40,7 +40,7 @@ namespace Volt VT_CORE_ASSERT(myPhysXScene, "PhysX scene not valid!"); myControllerManager = PxCreateControllerManager(*myPhysXScene); - myControllerManager->setTessellation(true, 100.f); + myControllerManager->setTessellation(true, 1.f); #ifndef VT_DIST if (!Application::Get().IsRuntime()) diff --git a/Volt/Volt/src/Volt/Physics/PhysicsSettings.h b/Volt/Volt/src/Volt/Physics/PhysicsSettings.h index 7d577fe60..c18fee6d7 100644 --- a/Volt/Volt/src/Volt/Physics/PhysicsSettings.h +++ b/Volt/Volt/src/Volt/Physics/PhysicsSettings.h @@ -9,13 +9,13 @@ namespace Volt struct PhysicsSettings { float fixedTimestep = 1.f / 60.f; - glm::vec3 gravity = { 0.f, -981.f, 0.f }; + glm::vec3 gravity = { 0.f, -9.81f, 0.f }; BroadphaseType broadphaseAlgorithm = BroadphaseType::AutomaticBoxPrune; FrictionType frictionModel = FrictionType::Patch; - glm::vec3 worldBoundsMin = glm::vec3{ -100000.f }; - glm::vec3 worldBoundsMax = glm::vec3{ 100000.f }; + glm::vec3 worldBoundsMin = glm::vec3{ -100.f }; + glm::vec3 worldBoundsMax = glm::vec3{ 100.f }; uint32_t worldBoundsSubDivisions = 2; uint32_t solverIterations = 8; diff --git a/Volt/Volt/src/Volt/Rendering/Shape.cpp b/Volt/Volt/src/Volt/Rendering/Shape.cpp index 18c29d516..4cb375d60 100644 --- a/Volt/Volt/src/Volt/Rendering/Shape.cpp +++ b/Volt/Volt/src/Volt/Rendering/Shape.cpp @@ -12,15 +12,15 @@ namespace Volt { std::vector vertices = { - {{ 50, 50, 50 }}, - {{ 50, 50, -50 }}, - {{ 50, -50, 50 }}, - {{ -50, 50, 50 }}, - - {{ 50, -50, -50 }}, - {{ -50, 50, -50 }}, - {{ -50, -50, 50 }}, - {{ -50, -50, -50 }} + {{ 0.5f, 0.5f, 0.5f }}, + {{ 0.5f, 0.5f, -0.5f }}, + {{ 0.5f, -0.5f, 0.5f }}, + {{ -0.5f, 0.5f, 0.5f }}, + + {{ 0.5f, -0.5f, -0.5f }}, + {{ -0.5f, 0.5f, -0.5f }}, + {{ -0.5f, -0.5f, 0.5f }}, + {{ -0.5f, -0.5f, -0.5f }} }; diff --git a/Volt/Volt/src/Volt/Scene/Scene.cpp b/Volt/Volt/src/Volt/Scene/Scene.cpp index 86dd6346b..5799cfafc 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.cpp +++ b/Volt/Volt/src/Volt/Scene/Scene.cpp @@ -716,7 +716,7 @@ namespace Volt auto ent = newScene->CreateEntity("Camera"); ent.AddComponent(); - ent.SetPosition({ 0.f, 0.f, -500.f }); + ent.SetPosition({ 0.f, 0.f, -5.f }); } } diff --git a/Volt/Volt/vendor/TGAFbx/src/Importer.cpp b/Volt/Volt/vendor/TGAFbx/src/Importer.cpp index 647a8d2ca..86a423a74 100644 --- a/Volt/Volt/vendor/TGAFbx/src/Importer.cpp +++ b/Volt/Volt/vendor/TGAFbx/src/Importer.cpp @@ -170,7 +170,7 @@ namespace TGA if (fbxImporter->Import(fbxScene)) { - if(fbxScene->GetGlobalSettings().GetSystemUnit() != FbxSystemUnit::cm) + if(fbxScene->GetGlobalSettings().GetSystemUnit() != FbxSystemUnit::m) { constexpr FbxSystemUnit::ConversionOptions sysUnitConversion = { @@ -182,8 +182,8 @@ namespace TGA true }; - FbxSystemUnit::cm.ConvertScene(fbxScene, sysUnitConversion); - assert(fbxScene->GetGlobalSettings().GetSystemUnit() == FbxSystemUnit::cm); + FbxSystemUnit::m.ConvertScene(fbxScene, sysUnitConversion); + assert(fbxScene->GetGlobalSettings().GetSystemUnit() == FbxSystemUnit::m); } // Load and set up Material data From d13c4453c03029597af5496bb982bc6afa4f170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Tue, 12 Dec 2023 22:31:30 +0100 Subject: [PATCH 3/5] Started work on OEPF (One Entity Per File) --- .../Volt/Asset/Importers/SceneImporter.cpp | 120 ++++++++++++++++-- .../src/Volt/Asset/Importers/SceneImporter.h | 7 +- .../src/Volt/Core/Threading/ThreadPool.cpp | 1 + .../Volt/src/Volt/Core/Threading/ThreadPool.h | 3 + Volt/Volt/src/Volt/Math/Math.h | 6 + Volt/Volt/src/Volt/Scene/Entity.cpp | 2 +- Volt/Volt/src/Volt/Utility/Algorithms.cpp | 70 ++++++++++ Volt/Volt/src/Volt/Utility/Algorithms.h | 10 ++ 8 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 Volt/Volt/src/Volt/Utility/Algorithms.cpp create mode 100644 Volt/Volt/src/Volt/Utility/Algorithms.h diff --git a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp index 34a83e890..f84172601 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp @@ -16,6 +16,8 @@ #include "Volt/Core/BinarySerializer.h" +#include "Volt/Utility/Algorithms.h" + namespace Volt { template @@ -147,9 +149,10 @@ namespace Volt streamReader.ExitScope(); const std::filesystem::path& scenePath = filePath; - std::filesystem::path folderPath = scenePath.parent_path(); + std::filesystem::path directoryPath = scenePath.parent_path(); - LoadSceneLayers(metadata, scene, folderPath); + LoadSceneLayers(metadata, scene, directoryPath); + LoadEntities(metadata, scene, directoryPath); scene->SortScene(); return true; } @@ -158,13 +161,13 @@ namespace Volt { const Ref scene = std::reinterpret_pointer_cast(asset); - std::filesystem::path folderPath = AssetManager::GetFilesystemPath(metadata.filePath); - if (!std::filesystem::is_directory(folderPath)) + std::filesystem::path directoryPath = AssetManager::GetFilesystemPath(metadata.filePath); + if (!std::filesystem::is_directory(directoryPath)) { - folderPath = folderPath.parent_path(); + directoryPath = directoryPath.parent_path(); } - std::filesystem::path scenePath = folderPath / (metadata.filePath.stem().string() + ".vtscene"); + std::filesystem::path scenePath = directoryPath / (metadata.filePath.stem().string() + ".vtscene"); YAMLStreamWriter streamWriter{ scenePath }; streamWriter.BeginMap(); @@ -174,7 +177,8 @@ namespace Volt streamWriter.EndMap(); streamWriter.WriteToDisk(); - SaveSceneLayers(metadata, scene, folderPath); + SaveSceneLayers(metadata, scene, directoryPath); + SaveEntities(metadata, scene, directoryPath); } void SceneImporter::LoadSceneLayers(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const @@ -218,10 +222,10 @@ namespace Volt sceneLayer.visible = streamReader.ReadKey("visible", true); sceneLayer.locked = streamReader.ReadKey("locked", false); - streamReader.ForEach("Entities", [&]() - { - DeserializeEntity(scene, metadata, streamReader); - }); + //streamReader.ForEach("Entities", [&]() + //{ + // DeserializeEntity(scene, metadata, streamReader); + //}); } streamReader.ExitScope(); } @@ -277,6 +281,98 @@ namespace Volt } } + void SceneImporter::SaveEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const + { + std::filesystem::path entitiesDirectoryPath = sceneDirectory / "Entities"; + if (!std::filesystem::exists(entitiesDirectoryPath)) + { + std::filesystem::create_directories(entitiesDirectoryPath); + } + + const auto entities = scene->GetAllEntities(); + + Algo::ForEachParallel([entitiesDirectoryPath, entities, metadata, scene, this](uint32_t i) + { + Entity entity = entities.at(i); + const auto entityPath = entitiesDirectoryPath / ("entity_" + entity.ToString() + ".entity"); + + YAMLStreamWriter streamWriter{ entityPath }; + SerializeEntity(entity, metadata, scene, streamWriter); + + streamWriter.WriteToDisk(); + }, + static_cast(entities.size())); + } + + void SceneImporter::LoadEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const + { + VT_PROFILE_FUNCTION(); + + std::filesystem::path layersFolderPath = sceneDirectory / "Entities"; + if (!std::filesystem::exists(layersFolderPath)) + { + return; + } + + std::vector entityPaths; + + for (const auto& it : std::filesystem::directory_iterator(layersFolderPath)) + { + if (!it.is_directory() && it.path().extension().string() == ".entity") + { + entityPaths.emplace_back(it.path()); + } + } + + scene->m_registry.reserve(entityPaths.size()); + + for (auto&& curr : scene->m_registry.storage()) + { + curr.second.reserve(entityPaths.size()); + } + + std::vector> dummyScenes{}; + + auto futures = Algo::ForEachParallelLockable([&dummyScenes, entityPaths, metadata, this](uint32_t i) + { + Ref dummyScene = CreateRef(); + + const auto& path = entityPaths.at(i); + + YAMLStreamReader streamReader{}; + if (!streamReader.OpenFile(path)) + { + return; + } + + DeserializeEntity(dummyScene, metadata, streamReader); + dummyScenes.push_back(dummyScene); + }, + static_cast(entityPaths.size())); + + for (auto& f : futures) + { + f.wait(); + } + + for (const auto& dummyScene : dummyScenes) + { + for (const auto& entity : dummyScene->GetAllEntities()) + { + Entity realEntity = scene->CreateEntityWithUUID(entity.GetID()); + Entity::Copy(entity, realEntity, Volt::EntityCopyFlags::None); + } + } + } + + Entity SceneImporter::CreateEntityFromUUIDThreadSafe(EntityID entityId, const Ref& scene) const + { + static std::mutex createEntityMutex; + std::scoped_lock lock{ createEntityMutex }; + + return scene->CreateEntityWithUUID(entityId); + } + void SceneImporter::SerializeEntity(entt::entity id, const AssetMetadata& metadata, const Ref& scene, YAMLStreamWriter& streamWriter) const { streamWriter.BeginMap(); @@ -519,7 +615,7 @@ namespace Volt return; } - auto entity = scene->CreateEntityWithUUID(entityId); + auto entity = CreateEntityFromUUIDThreadSafe(entityId, scene); streamReader.ForEach("components", [&]() { diff --git a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h index b9c41f7a5..c343ae215 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h @@ -5,7 +5,7 @@ #include "Volt/Utility/FileIO/YAMLStreamWriter.h" #include "Volt/Utility/FileIO/YAMLStreamReader.h" -#include +#include "Volt/Scene/Entity.h" #include #include @@ -45,6 +45,11 @@ namespace Volt void LoadSceneLayers(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; void SaveSceneLayers(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; + void SaveEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; + void LoadEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; + + Entity CreateEntityFromUUIDThreadSafe(EntityID entityId, const Ref& scene) const; + void SerializeClass(const uint8_t* data, const size_t offset, const IComponentTypeDesc* compDesc, YAMLStreamWriter& streamWriter, bool isSubComponent) const; void SerializeArray(const uint8_t* data, const size_t offset, const IArrayTypeDesc* arrayDesc, YAMLStreamWriter& streamWriter) const; void SerializeMono(entt::entity id, const Ref& scene, YAMLStreamWriter& streamWriter) const; diff --git a/Volt/Volt/src/Volt/Core/Threading/ThreadPool.cpp b/Volt/Volt/src/Volt/Core/Threading/ThreadPool.cpp index 318014fa7..9fe08ac95 100644 --- a/Volt/Volt/src/Volt/Core/Threading/ThreadPool.cpp +++ b/Volt/Volt/src/Volt/Core/Threading/ThreadPool.cpp @@ -24,6 +24,7 @@ namespace Volt } m_hasBeenInitialized = true; + m_threadCount = threadCount; }); } diff --git a/Volt/Volt/src/Volt/Core/Threading/ThreadPool.h b/Volt/Volt/src/Volt/Core/Threading/ThreadPool.h index 6efab3b35..08ae7b55f 100644 --- a/Volt/Volt/src/Volt/Core/Threading/ThreadPool.h +++ b/Volt/Volt/src/Volt/Core/Threading/ThreadPool.h @@ -22,6 +22,7 @@ namespace Volt inline const bool Initialized() const { ReadLock lock{ m_mutex }; return m_hasBeenInitialized; } inline const bool IsRunning() const { ReadLock lock{ m_mutex }; return IsRunningImpl(); } + inline const uint32_t GetThreadCount() const { return m_threadCount; } private: inline const bool IsRunningImpl() const @@ -37,6 +38,8 @@ namespace Volt bool m_shouldStop = false; bool m_shouldCancel = false; + uint32_t m_threadCount = 0; + mutable ThreadSafeQueue> m_tasks; mutable std::once_flag m_onceFlag; mutable std::shared_mutex m_mutex; diff --git a/Volt/Volt/src/Volt/Math/Math.h b/Volt/Volt/src/Volt/Math/Math.h index ec991bb61..fa895587f 100644 --- a/Volt/Volt/src/Volt/Math/Math.h +++ b/Volt/Volt/src/Volt/Math/Math.h @@ -146,4 +146,10 @@ namespace Math { return lhs ^ (rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2)); } + + template + inline static T DivideRoundUp(const T& numerator, const T& denominator) + { + return (numerator + denominator - T{ 1 }) / denominator; + } } diff --git a/Volt/Volt/src/Volt/Scene/Entity.cpp b/Volt/Volt/src/Volt/Scene/Entity.cpp index 43f347433..86ed0e65a 100644 --- a/Volt/Volt/src/Volt/Scene/Entity.cpp +++ b/Volt/Volt/src/Volt/Scene/Entity.cpp @@ -41,7 +41,7 @@ namespace Volt const std::string Entity::ToString() const { - return std::to_string(static_cast(m_handle)); + return std::to_string(static_cast(GetComponent().id)); } const uint32_t Entity::GetLayerID() const diff --git a/Volt/Volt/src/Volt/Utility/Algorithms.cpp b/Volt/Volt/src/Volt/Utility/Algorithms.cpp new file mode 100644 index 000000000..b9fbfcd0e --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/Algorithms.cpp @@ -0,0 +1,70 @@ +#include "vtpch.h" +#include "Algorithms.h" + +#include "Volt/Math/Math.h" +#include "Volt/Core/Application.h" +#include "Volt/Core/Threading/ThreadPool.h" + +namespace Volt::Algo +{ + std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount) + { + auto& threadPool = Application::GetThreadPool(); + + const uint32_t threadCount = std::min(iterationCount, threadPool.GetThreadCount()); + const uint32_t perThreadIterationCount = Math::DivideRoundUp(iterationCount, threadCount); + + std::vector> futures; + futures.reserve(threadCount); + + uint32_t iterOffset = 0; + for (uint32_t i = 0; i < threadCount; i++) + { + uint32_t currThreadIterationCount = perThreadIterationCount; + if (i == threadCount - 1) + { + currThreadIterationCount = iterationCount - i * perThreadIterationCount; + } + + futures.emplace_back(threadPool.SubmitTask([currThreadIterationCount, func, iterOffset]() + { + for (uint32_t iter = 0; iter < currThreadIterationCount; iter++) + { + func(iter + iterOffset); + } + })); + + iterOffset += currThreadIterationCount; + } + + return futures; + } + + void ForEachParallel(std::function&& func, uint32_t iterationCount) + { + auto& threadPool = Application::GetThreadPool(); + + const uint32_t threadCount = std::min(iterationCount, threadPool.GetThreadCount()); + const uint32_t perThreadIterationCount = Math::DivideRoundUp(iterationCount, threadCount); + + uint32_t iterOffset = 0; + for (uint32_t i = 0; i < threadCount; i++) + { + uint32_t currThreadIterationCount = perThreadIterationCount; + if (i == threadCount - 1) + { + currThreadIterationCount = iterationCount - i * perThreadIterationCount; + } + + threadPool.SubmitTask([currThreadIterationCount, func, iterOffset]() + { + for (uint32_t iter = 0; iter < currThreadIterationCount; iter++) + { + func(iter + iterOffset); + } + }); + + iterOffset += currThreadIterationCount; + } + } +} diff --git a/Volt/Volt/src/Volt/Utility/Algorithms.h b/Volt/Volt/src/Volt/Utility/Algorithms.h new file mode 100644 index 000000000..acd1fe8de --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/Algorithms.h @@ -0,0 +1,10 @@ +#pragma once + +#include + + +namespace Volt::Algo +{ + extern [[nodiscard]] std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount); + extern void ForEachParallel(std::function&& func, uint32_t iterationCount); +} From d36de49e3863bf2f147ab463606589eece53d753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Wed, 13 Dec 2023 23:30:54 +0100 Subject: [PATCH 4/5] Continued work on WorldEngine --- .../Modals/ConvertToWorldEngineModal.cpp | 58 ++++++++++ .../Modals/ConvertToWorldEngineModal.h | 24 +++++ Volt/Sandbox/src/Sandbox/Modals/Modal.h | 6 +- Volt/Sandbox/src/Sandbox/Sandbox.cpp | 7 +- .../Utility/ComponentPropertyUtilities.cpp | 16 ++- .../src/Sandbox/Utility/EditorUtilities.cpp | 6 ++ .../src/Sandbox/Utility/EditorUtilities.h | 2 + .../src/Sandbox/Window/PropertiesPanel.cpp | 22 +++- .../src/Sandbox/Window/SceneSettingsPanel.cpp | 30 ++++++ .../src/Sandbox/Window/SceneSettingsPanel.h | 23 ++++ .../src/Sandbox/Window/ViewportPanel.cpp | 21 ++-- .../Volt/Asset/Importers/SceneImporter.cpp | 102 +++++++++++++----- Volt/Volt/src/Volt/Scene/EntityRegistry.cpp | 18 ++++ Volt/Volt/src/Volt/Scene/EntityRegistry.h | 9 ++ Volt/Volt/src/Volt/Scene/Scene.cpp | 35 ++++++ Volt/Volt/src/Volt/Scene/Scene.h | 18 +++- Volt/Volt/src/Volt/Utility/Algorithms.cpp | 3 + 17 files changed, 347 insertions(+), 53 deletions(-) create mode 100644 Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.cpp create mode 100644 Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.h create mode 100644 Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.cpp create mode 100644 Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.h diff --git a/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.cpp b/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.cpp new file mode 100644 index 000000000..9911f94ba --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.cpp @@ -0,0 +1,58 @@ +#include "sbpch.h" +#include "ConvertToWorldEngineModal.h" + +#include +#include + +#include + +#include + +ConvertToWorldEngineModal::ConvertToWorldEngineModal(const std::string& stringId) + : Modal(stringId) +{ +} + +ConvertToWorldEngineModal::~ConvertToWorldEngineModal() +{ +} + +void ConvertToWorldEngineModal::DrawModalContent() +{ + ImGui::Text("Are you sure you want to convert to WorldEngine?"); + + ImGui::SameLine(); + + if (ImGui::Button("Convert")) + { + m_scene->GetSceneSettingsMutable().useWorldEngine = true; + + const auto& metadata = Volt::AssetManager::GetMetadataFromHandle(m_scene->handle); + if (metadata.IsValid()) + { + const std::filesystem::path directoryPath = Volt::AssetManager::GetFilesystemPath(metadata.filePath); + const std::filesystem::path layersPath = directoryPath / "Layers"; + + if (std::filesystem::exists(directoryPath) && std::filesystem::exists(layersPath)) + { + FileSystem::MoveToRecycleBin(layersPath); + } + } + + Volt::AssetManager::SaveAsset(m_scene.GetSharedPtr()); + Close(); + } + + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) + { + m_scene->GetSceneSettingsMutable().useWorldEngine = false; + Close(); + } +} + +void ConvertToWorldEngineModal::OnClose() +{ + m_scene.Reset(); +} diff --git a/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.h b/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.h new file mode 100644 index 000000000..bf6e222a6 --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Modals/ConvertToWorldEngineModal.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Sandbox/Modals/Modal.h" + +namespace Volt +{ + class Scene; +} + +class ConvertToWorldEngineModal : public Modal +{ +public: + ConvertToWorldEngineModal(const std::string& stringId); + ~ConvertToWorldEngineModal(); + + inline void SetCurrentScene(Weak scene) { m_scene = scene; } + +protected: + void DrawModalContent() override; + void OnClose() override; + +protected: + Weak m_scene; +}; diff --git a/Volt/Sandbox/src/Sandbox/Modals/Modal.h b/Volt/Sandbox/src/Sandbox/Modals/Modal.h index 0bc0a6f8e..2d4c949f3 100644 --- a/Volt/Sandbox/src/Sandbox/Modals/Modal.h +++ b/Volt/Sandbox/src/Sandbox/Modals/Modal.h @@ -4,6 +4,8 @@ #include +typedef Volt::UUID ModalID; + class Modal { public: @@ -14,7 +16,7 @@ class Modal void Close(); bool Update(); - inline const Volt::UUID GetID() const { return m_id; } + inline const ModalID GetID() const { return m_id; } protected: virtual void DrawModalContent() = 0; @@ -26,6 +28,6 @@ class Modal bool m_wasOpenLastFrame = false; - Volt::UUID m_id; + ModalID m_id; std::string m_strId; }; diff --git a/Volt/Sandbox/src/Sandbox/Sandbox.cpp b/Volt/Sandbox/src/Sandbox/Sandbox.cpp index f32e04fd1..b952e130a 100644 --- a/Volt/Sandbox/src/Sandbox/Sandbox.cpp +++ b/Volt/Sandbox/src/Sandbox/Sandbox.cpp @@ -41,6 +41,7 @@ #include "Sandbox/Window/Net/NetPanel.h" #include "Sandbox/Window/Net/NetContractPanel.h" #include "Sandbox/Window/BehaviourGraph/BehaviorPanel.h" +#include "Sandbox/Window/SceneSettingsPanel.h" #include "Sandbox/VertexPainting/VertexPainterPanel.h" #include "Sandbox/Utility/EditorResources.h" @@ -117,9 +118,6 @@ void Sandbox::OnAttach() NewScene(); - // WIP Panels. -#ifndef VT_DIST - // Shelved Panels (So panel tab doesn't get cluttered up). #ifdef VT_DEBUG EditorLibrary::RegisterWithType("", Volt::AssetType::Prefab); @@ -128,8 +126,6 @@ void Sandbox::OnAttach() EditorLibrary::Register("Advanced"); EditorLibrary::Register("Advanced"); EditorLibrary::Register("Advanced"); -#endif - #endif myNavigationPanel = EditorLibrary::Register("Advanced", myRuntimeScene); @@ -148,6 +144,7 @@ void Sandbox::OnAttach() EditorLibrary::Register("Advanced"); EditorLibrary::Register("Advanced"); + EditorLibrary::Register("", myRuntimeScene); if (userSettings.sceneSettings.lowMemoryUsage) { diff --git a/Volt/Sandbox/src/Sandbox/Utility/ComponentPropertyUtilities.cpp b/Volt/Sandbox/src/Sandbox/Utility/ComponentPropertyUtilities.cpp index 6bf22e81b..551318bc7 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/ComponentPropertyUtilities.cpp +++ b/Volt/Sandbox/src/Sandbox/Utility/ComponentPropertyUtilities.cpp @@ -311,6 +311,7 @@ void ComponentPropertyUtility::DrawComponentDefaultMemberArray(Weak if (EditorUtils::Property(label, *reinterpret_cast(elementData), arrayMember.assetType)) { AddLocalChangeToEntity(entity, arrayMember.ownerTypeDesc->GetGUID(), arrayMember.name); + EditorUtils::MarkEntityAsEdited(entity); } return; } @@ -320,6 +321,7 @@ void ComponentPropertyUtility::DrawComponentDefaultMemberArray(Weak if (UI::PropertyColor(label, *reinterpret_cast(elementData))) { AddLocalChangeToEntity(entity, arrayMember.ownerTypeDesc->GetGUID(), arrayMember.name); + EditorUtils::MarkEntityAsEdited(entity); } return; } @@ -329,6 +331,7 @@ void ComponentPropertyUtility::DrawComponentDefaultMemberArray(Weak if (UI::PropertyColor(label, *reinterpret_cast(elementData))) { AddLocalChangeToEntity(entity, arrayMember.ownerTypeDesc->GetGUID(), arrayMember.name); + EditorUtils::MarkEntityAsEdited(entity); } return; } @@ -339,6 +342,7 @@ void ComponentPropertyUtility::DrawComponentDefaultMemberArray(Weak if (UI::PropertyEntity(label, scene, *reinterpret_cast(elementData))) { AddLocalChangeToEntity(entity, arrayMember.ownerTypeDesc->GetGUID(), arrayMember.name); + EditorUtils::MarkEntityAsEdited(entity); } return; } @@ -351,6 +355,7 @@ void ComponentPropertyUtility::DrawComponentDefaultMemberArray(Weak if (s_propertyFunctions.at(typeIndex)(label, elementData, 0)) { AddLocalChangeToEntity(entity, arrayMember.ownerTypeDesc->GetGUID(), arrayMember.name); + EditorUtils::MarkEntityAsEdited(entity); } } @@ -383,6 +388,7 @@ void ComponentPropertyUtility::DrawComponentEnum(Weak scene, Volt:: { currentValue = indexToValueMap.at(currentValue); AddLocalChangeToEntity(entity, member.ownerTypeDesc->GetGUID(), member.name); + EditorUtils::MarkEntityAsEdited(entity); } } @@ -446,6 +452,8 @@ void ComponentPropertyUtility::DrawComponentArray(Weak scene, Volt: { arrayDesc->EmplaceBack(arrayPtr, nullptr); AddLocalChangeToEntity(entity, member.ownerTypeDesc->GetGUID(), member.name); + + EditorUtils::MarkEntityAsEdited(entity); } ImGui::TreePop(); @@ -566,7 +574,6 @@ void ComponentPropertyUtility::DrawMonoMembers(Weak scene, const Vo if (EditorUtils::Property(displayName, value, field.type.assetType)) { scriptInstance->SetField(name, &value); - AddLocalChangeToEntity(entity, scriptEntry.name, name); } continue; @@ -713,7 +720,7 @@ void ComponentPropertyUtility::DrawMonoMembers(Weak scene, const Vo scriptInstance->SetField(name, str); } - AddLocalChangeToEntity(entity, scriptEntry.name, name); + fieldChanged = true; } } else if (field.type.IsEntity()) @@ -762,7 +769,6 @@ void ComponentPropertyUtility::DrawMonoMembers(Weak scene, const Vo if (scriptInstance && fieldChanged) { scriptInstance->SetField(name, currentField->data.As()); - AddLocalChangeToEntity(entity, scriptEntry.name, name); } @@ -816,6 +822,8 @@ void ComponentPropertyUtility::AddLocalChangeToEntity(Volt::Entity entity, const auto& newChange = prefabComp.componentLocalChanges.emplace_back(); newChange.componentGUID = componentGuid; newChange.memberName = strMemberName; + + EditorUtils::MarkEntityAsEdited(entity); } void ComponentPropertyUtility::AddLocalChangeToEntity(Volt::Entity entity, const std::string& scriptName, std::string_view memberName) @@ -841,4 +849,6 @@ void ComponentPropertyUtility::AddLocalChangeToEntity(Volt::Entity entity, const auto& newChange = prefabComp.scriptLocalChanges.emplace_back(); newChange.scriptName = scriptName; newChange.memberName = memberName; + + EditorUtils::MarkEntityAsEdited(entity); } diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp index 95d20a9a5..6f2872570 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp @@ -978,3 +978,9 @@ std::filesystem::path EditorUtils::GetThumbnailPathFromPath(const std::filesyste { return path.string() + ".vtthumb.png"; } + +void EditorUtils::MarkEntityAsEdited(const Volt::Entity& entity) +{ + auto scene = entity.GetScene(); + scene->MarkEntityAsEdited(entity); +} diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h index a225f7603..3353d09e8 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h @@ -80,6 +80,8 @@ class EditorUtils static bool HasThumbnail(const std::filesystem::path& path); static std::filesystem::path GetThumbnailPathFromPath(const std::filesystem::path& path); + static void MarkEntityAsEdited(const Volt::Entity& entity); + private: static bool AssetBrowserPopupInternal(const std::string& id, Volt::AssetHandle& assetHandle, bool startState, Volt::AssetType wantedType = Volt::AssetType::None); struct DefaultFalse diff --git a/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp index 4d1c630e4..ba4821fc4 100644 --- a/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp @@ -61,7 +61,10 @@ void PropertiesPanel::UpdateMainContent() if (firstEntity.HasComponent()) { auto& tag = firstEntity.GetComponent(); - UI::InputText("Name", tag.tag); + if (UI::InputText("Name", tag.tag)) + { + EditorUtils::MarkEntityAsEdited(firstEntity); + } } } else @@ -110,6 +113,7 @@ void PropertiesPanel::UpdateMainContent() if (entity.HasComponent()) { entity.GetComponent().tag = inputText; + EditorUtils::MarkEntityAsEdited(entity); } } } @@ -146,6 +150,8 @@ void PropertiesPanel::UpdateMainContent() Volt::Entity ent = myCurrentScene->GetEntityFromUUID(entId); ent.SetLocalPosition(transform.position); myCurrentScene->InvalidateEntityTransform(entId); + + EditorUtils::MarkEntityAsEdited(ent); } } @@ -169,6 +175,8 @@ void PropertiesPanel::UpdateMainContent() Volt::Entity ent = myCurrentScene->GetEntityFromUUID(entId); ent.SetLocalRotation(transform.rotation); myCurrentScene->InvalidateEntityTransform(entId); + + EditorUtils::MarkEntityAsEdited(ent); } } @@ -188,6 +196,8 @@ void PropertiesPanel::UpdateMainContent() Volt::Entity ent = myCurrentScene->GetEntityFromUUID(entId); ent.SetLocalScale(transform.scale); myCurrentScene->InvalidateEntityTransform(entId); + + EditorUtils::MarkEntityAsEdited(ent); } } @@ -316,9 +326,12 @@ void PropertiesPanel::AddComponentPopup() { for (auto& ent : SelectionManager::GetSelectedEntities()) { - if (!Volt::ComponentRegistry::Helpers::HasComponentWithGUID(compGuid, myCurrentScene->GetRegistry(), myCurrentScene->GetHandleFromUUID(ent))) + auto entity = myCurrentScene->GetEntityFromUUID(ent); + EditorUtils::MarkEntityAsEdited(entity); + + if (!Volt::ComponentRegistry::Helpers::HasComponentWithGUID(compGuid, myCurrentScene->GetRegistry(), entity)) { - Volt::ComponentRegistry::Helpers::AddComponentWithGUID(compGuid, myCurrentScene->GetRegistry(), myCurrentScene->GetHandleFromUUID(ent)); + Volt::ComponentRegistry::Helpers::AddComponentWithGUID(compGuid, myCurrentScene->GetRegistry(), entity); } if (newMonoScript) @@ -394,6 +407,7 @@ void PropertiesPanel::AddMonoScriptPopup() for (auto& id : SelectionManager::GetSelectedEntities()) { Volt::Entity entity = myCurrentScene->GetEntityFromUUID(id); + EditorUtils::MarkEntityAsEdited(entity); if (!entity.HasComponent()) { @@ -438,6 +452,7 @@ void PropertiesPanel::AddMonoScriptPopup() for (auto& id : SelectionManager::GetSelectedEntities()) { Volt::Entity entity = myCurrentScene->GetEntityFromUUID(id); + EditorUtils::MarkEntityAsEdited(entity); if (!entity.HasComponent()) { @@ -506,6 +521,7 @@ void PropertiesPanel::AcceptMonoDragDrop() for (auto& id : SelectionManager::GetSelectedEntities()) { Volt::Entity entity = myCurrentScene->GetEntityFromUUID(id); + EditorUtils::MarkEntityAsEdited(entity); if (!entity.HasComponent()) { diff --git a/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.cpp new file mode 100644 index 000000000..3ac241ea6 --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.cpp @@ -0,0 +1,30 @@ +#include "sbpch.h" +#include "SceneSettingsPanel.h" + +#include "Sandbox/Modals/ConvertToWorldEngineModal.h" +#include "Sandbox/UISystems/ModalSystem.h" + +#include + +SceneSettingsPanel::SceneSettingsPanel(Ref& editorScene) + : EditorWindow("Scene Settings"), m_editorScene(editorScene) +{ + auto& modal = ModalSystem::AddModal("Convert To World Engine##sceneSettings"); + m_convertionModal = modal.GetID(); +} + +void SceneSettingsPanel::UpdateMainContent() +{ + auto& sceneSettings = m_editorScene->GetSceneSettingsMutable(); + + if (UI::BeginProperties("sceneSettings")) + { + if (UI::Property("Use World Engine", sceneSettings.useWorldEngine)) + { + ModalSystem::GetModal(m_convertionModal).SetCurrentScene(m_editorScene); + ModalSystem::GetModal(m_convertionModal).Open(); + } + + UI::EndProperties(); + } +} diff --git a/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.h b/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.h new file mode 100644 index 000000000..f7672b73f --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Window/SceneSettingsPanel.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Sandbox/Window/EditorWindow.h" + +#include "Sandbox/Modals/Modal.h" + +namespace Volt +{ + class Scene; +} + +class SceneSettingsPanel : public EditorWindow +{ +public: + SceneSettingsPanel(Ref& editorScene); + + void UpdateMainContent() override; + +private: + Ref& m_editorScene; + + ModalID m_convertionModal = 0; +}; diff --git a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp index ec190f92c..dfd159f3e 100644 --- a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp @@ -141,10 +141,17 @@ void ViewportPanel::UpdateMainContent() const auto view = tempCamera->GetView(); const auto projection = tempCamera->GetProjection(); - ImGuizmo::Manipulate( + if (ImGuizmo::Manipulate( glm::value_ptr(view), glm::value_ptr(projection), - m_gizmoOperation, gizmoMode, glm::value_ptr(averageTransform), glm::value_ptr(deltaMatrix), snap ? snapValues : nullptr); + m_gizmoOperation, gizmoMode, glm::value_ptr(averageTransform), glm::value_ptr(deltaMatrix), snap ? snapValues : nullptr)) + { + for (const auto& entId : SelectionManager::GetSelectedEntities()) + { + auto entity = m_editorScene->GetEntityFromUUID(entId); + EditorUtils::MarkEntityAsEdited(entity); + } + } bool wasUsedPreviousFrame = isUsing; isUsing = ImGuizmo::IsUsing(); @@ -706,7 +713,7 @@ void ViewportPanel::CheckDragDrop() m_isInViewport = true; const Volt::AssetHandle handle = GlobalEditorStates::dragAsset; - const Volt::AssetType type = Volt::AssetManager::Get().GetAssetTypeFromHandle(handle); + const Volt::AssetType type = Volt::AssetManager::GetAssetTypeFromHandle(handle); switch (type) { @@ -724,7 +731,7 @@ void ViewportPanel::CheckDragDrop() meshComp.handle = mesh->handle; } - newEntity.GetComponent().tag = Volt::AssetManager::Get().GetFilePathFromAssetHandle(handle).stem().string(); + newEntity.GetComponent().tag = Volt::AssetManager::GetFilePathFromAssetHandle(handle).stem().string(); m_createdEntity = newEntity; break; @@ -732,7 +739,7 @@ void ViewportPanel::CheckDragDrop() case Volt::AssetType::MeshSource: { - const std::filesystem::path meshSourcePath = Volt::AssetManager::Get().GetFilePathFromAssetHandle(handle); + const std::filesystem::path meshSourcePath = Volt::AssetManager::GetFilePathFromAssetHandle(handle); const std::filesystem::path vtMeshPath = meshSourcePath.parent_path() / (meshSourcePath.stem().string() + ".vtmesh"); Volt::AssetHandle resultHandle = handle; @@ -781,7 +788,7 @@ void ViewportPanel::CheckDragDrop() particleEmitter.preset = preset->handle; } - newEntity.GetComponent().tag = Volt::AssetManager::Get().GetFilePathFromAssetHandle(handle).stem().string(); + newEntity.GetComponent().tag = Volt::AssetManager::GetFilePathFromAssetHandle(handle).stem().string(); m_createdEntity = newEntity; break; @@ -1086,7 +1093,7 @@ void ViewportPanel::HandleNonMeshDragDrop() if (void* ptr = UI::DragDropTarget({ "ASSET_BROWSER_ITEM" })) { const Volt::AssetHandle handle = *(const Volt::AssetHandle*)ptr; - const Volt::AssetType type = Volt::AssetManager::Get().GetAssetTypeFromHandle(handle); + const Volt::AssetType type = Volt::AssetManager::GetAssetTypeFromHandle(handle); switch (type) { diff --git a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp index f84172601..872e5e35e 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp @@ -17,6 +17,7 @@ #include "Volt/Core/BinarySerializer.h" #include "Volt/Utility/Algorithms.h" +#include "Volt/Utility/FileSystem.h" namespace Volt { @@ -25,8 +26,8 @@ namespace Volt { VT_PROFILE_FUNCTION(); - outTypes[std::type_index{ typeid(T) }] = [](YAMLStreamWriter& streamWriter, const uint8_t* data, const size_t offset) - { + outTypes[std::type_index{ typeid(T) }] = [](YAMLStreamWriter& streamWriter, const uint8_t* data, const size_t offset) + { const T& var = *reinterpret_cast(&data[offset]); streamWriter.SetKey("data", var); }; @@ -37,9 +38,9 @@ namespace Volt { VT_PROFILE_FUNCTION(); - outTypes[std::type_index{ typeid(T) }] = [](YAMLStreamReader& streamReader, uint8_t* data, const size_t offset) - { - *reinterpret_cast(&data[offset]) = streamReader.ReadKey("data", T()); + outTypes[std::type_index{ typeid(T) }] = [](YAMLStreamReader& streamReader, uint8_t* data, const size_t offset) + { + *reinterpret_cast(&data[offset]) = streamReader.ReadKey("data", T()); }; } @@ -106,7 +107,7 @@ namespace Volt RegisterDeserializationFunction(s_typeDeserializers); RegisterDeserializationFunction(s_typeDeserializers); - RegisterDeserializationFunction(s_typeDeserializers); + RegisterDeserializationFunction(s_typeDeserializers); RegisterDeserializationFunction(s_typeDeserializers); RegisterDeserializationFunction(s_typeDeserializers); @@ -146,13 +147,25 @@ namespace Volt streamReader.EnterScope("Scene"); scene->m_name = streamReader.ReadKey("name", std::string("New Scene")); + + streamReader.EnterScope("Settings"); + scene->m_sceneSettings.useWorldEngine = streamReader.ReadKey("useWorldEngine", false); + streamReader.ExitScope(); + streamReader.ExitScope(); const std::filesystem::path& scenePath = filePath; std::filesystem::path directoryPath = scenePath.parent_path(); - LoadSceneLayers(metadata, scene, directoryPath); - LoadEntities(metadata, scene, directoryPath); + if (scene->m_sceneSettings.useWorldEngine) + { + LoadEntities(metadata, scene, directoryPath); + } + else + { + LoadSceneLayers(metadata, scene, directoryPath); + } + scene->SortScene(); return true; } @@ -173,12 +186,23 @@ namespace Volt streamWriter.BeginMap(); streamWriter.BeginMapNamned("Scene"); streamWriter.SetKey("name", metadata.filePath.stem().string()); + + streamWriter.BeginMapNamned("Settings"); + streamWriter.SetKey("useWorldEngine", scene->m_sceneSettings.useWorldEngine); + streamWriter.EndMap(); + streamWriter.EndMap(); streamWriter.EndMap(); streamWriter.WriteToDisk(); - SaveSceneLayers(metadata, scene, directoryPath); - SaveEntities(metadata, scene, directoryPath); + if (scene->m_sceneSettings.useWorldEngine) + { + SaveEntities(metadata, scene, directoryPath); + } + else + { + SaveSceneLayers(metadata, scene, directoryPath); + } } void SceneImporter::LoadSceneLayers(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const @@ -222,10 +246,10 @@ namespace Volt sceneLayer.visible = streamReader.ReadKey("visible", true); sceneLayer.locked = streamReader.ReadKey("locked", false); - //streamReader.ForEach("Entities", [&]() - //{ - // DeserializeEntity(scene, metadata, streamReader); - //}); + streamReader.ForEach("Entities", [&]() + { + DeserializeEntity(scene, metadata, streamReader); + }); } streamReader.ExitScope(); } @@ -289,19 +313,42 @@ namespace Volt std::filesystem::create_directories(entitiesDirectoryPath); } - const auto entities = scene->GetAllEntities(); + const auto entities = scene->GetAllEditedEntities(); + if (!entities.empty()) + { + Algo::ForEachParallel([entitiesDirectoryPath, entities, metadata, scene, this](uint32_t i) + { + Entity entity = entities.at(i); + const auto entityPath = entitiesDirectoryPath / (entity.ToString() + ".entity"); - Algo::ForEachParallel([entitiesDirectoryPath, entities, metadata, scene, this](uint32_t i) + YAMLStreamWriter streamWriter{ entityPath }; + SerializeEntity(entity, metadata, scene, streamWriter); + + streamWriter.WriteToDisk(); + }, + static_cast(entities.size())); + } + + const auto removedEntities = scene->GetAllRemovedEntities(); + if (!removedEntities.empty()) { - Entity entity = entities.at(i); - const auto entityPath = entitiesDirectoryPath / ("entity_" + entity.ToString() + ".entity"); + Algo::ForEachParallel([removedEntities, entitiesDirectoryPath](uint32_t i) + { + EntityID id = removedEntities.at(i); - YAMLStreamWriter streamWriter{ entityPath }; - SerializeEntity(entity, metadata, scene, streamWriter); + const std::filesystem::path entityFilePath = entitiesDirectoryPath / (std::to_string(id) + ".entity"); + if (std::filesystem::exists(entityFilePath)) + { + FileSystem::MoveToRecycleBin(entityFilePath); + } - streamWriter.WriteToDisk(); - }, - static_cast(entities.size())); + }, static_cast(removedEntities.size())); + } + + VT_CORE_INFO("[SceneImporter]: Saved {0} entities!", entities.size()); + VT_CORE_INFO("[SceneImporter]: Removed {0} entities!", removedEntities.size()); + + scene->ClearEditedEntities(); } void SceneImporter::LoadEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const @@ -324,15 +371,12 @@ namespace Volt } } - scene->m_registry.reserve(entityPaths.size()); - - for (auto&& curr : scene->m_registry.storage()) + if (entityPaths.empty()) { - curr.second.reserve(entityPaths.size()); + return; } std::vector> dummyScenes{}; - auto futures = Algo::ForEachParallelLockable([&dummyScenes, entityPaths, metadata, this](uint32_t i) { Ref dummyScene = CreateRef(); @@ -666,7 +710,7 @@ namespace Volt if (std::filesystem::exists(vpPath)) { auto& vpComp = scene->GetRegistry().get(entity); - + std::ifstream vpFile(vpPath, std::ios::in | std::ios::binary); if (!vpFile.is_open()) { diff --git a/Volt/Volt/src/Volt/Scene/EntityRegistry.cpp b/Volt/Volt/src/Volt/Scene/EntityRegistry.cpp index d2460b4c5..3bce1e3d3 100644 --- a/Volt/Volt/src/Volt/Scene/EntityRegistry.cpp +++ b/Volt/Volt/src/Volt/Scene/EntityRegistry.cpp @@ -5,6 +5,17 @@ namespace Volt { + void EntityRegistry::MarkEntityAsEdited(const Entity& entity) + { + m_editedEntities.emplace(entity.GetID()); + } + + void EntityRegistry::ClearEditedEntities() + { + m_editedEntities.clear(); + m_removedEntities.clear(); + } + void EntityRegistry::AddEntity(const Entity& entity) { if (m_entityMap.contains(entity.GetID()) || m_handleMap.contains(entity)) @@ -27,6 +38,13 @@ namespace Volt { m_handleMap.erase(entity); } + + if (m_editedEntities.contains(entity.GetID())) + { + m_editedEntities.erase(entity.GetID()); + } + + m_removedEntities.emplace(entity.GetID()); } EntityID EntityRegistry::GetUUIDFromHandle(entt::entity handle) const diff --git a/Volt/Volt/src/Volt/Scene/EntityRegistry.h b/Volt/Volt/src/Volt/Scene/EntityRegistry.h index a37c023d8..bea913e02 100644 --- a/Volt/Volt/src/Volt/Scene/EntityRegistry.h +++ b/Volt/Volt/src/Volt/Scene/EntityRegistry.h @@ -11,6 +11,9 @@ namespace Volt class EntityRegistry { public: + void MarkEntityAsEdited(const Entity& entity); + void ClearEditedEntities(); + void AddEntity(const Entity& entity); void RemoveEntity(const Entity& entity); @@ -20,8 +23,14 @@ namespace Volt const bool Contains(EntityID uuid) const; const bool Contains(entt::entity handle) const; + inline const std::set& GetEditedEntities() const { return m_editedEntities; } + inline const std::set& GetRemovedEntities() const { return m_removedEntities; } + private: std::unordered_map m_entityMap; std::unordered_map m_handleMap; + + std::set m_editedEntities; + std::set m_removedEntities; }; } diff --git a/Volt/Volt/src/Volt/Scene/Scene.cpp b/Volt/Volt/src/Volt/Scene/Scene.cpp index 5799cfafc..c725dab3b 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.cpp +++ b/Volt/Volt/src/Volt/Scene/Scene.cpp @@ -384,6 +384,7 @@ namespace Volt const auto uuid = newEntity.GetComponent().id; m_entityRegistry.AddEntity(newEntity); + m_entityRegistry.MarkEntityAsEdited(newEntity); InvalidateEntityTransform(uuid); SortScene(); @@ -1257,6 +1258,16 @@ namespace Volt return std::find_if(m_sceneLayers.begin(), m_sceneLayers.end(), [layerId](const auto& lhs) { return lhs.id == layerId; }) != m_sceneLayers.end(); } + void Scene::MarkEntityAsEdited(const Entity& entity) + { + m_entityRegistry.MarkEntityAsEdited(entity); + } + + void Scene::ClearEditedEntities() + { + m_entityRegistry.ClearEditedEntities(); + } + const std::vector Scene::GetAllEntities() const { std::vector result{}; @@ -1269,4 +1280,28 @@ namespace Volt return result; } + + const std::vector Scene::GetAllEditedEntities() const + { + std::vector entities; + + for (const auto& entity : m_entityRegistry.GetEditedEntities()) + { + entities.push_back(GetEntityFromUUID(entity)); + } + + return entities; + } + + const std::vector Scene::GetAllRemovedEntities() const + { + std::vector entities; + + for (const auto& entity : m_entityRegistry.GetRemovedEntities()) + { + entities.push_back(entity); + } + + return entities; + } } diff --git a/Volt/Volt/src/Volt/Scene/Scene.h b/Volt/Volt/src/Volt/Scene/Scene.h index 3f63a73bc..6d2604b92 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.h +++ b/Volt/Volt/src/Volt/Scene/Scene.h @@ -40,6 +40,11 @@ namespace Volt float intensity = 1.f; }; + struct SceneSettings + { + bool useWorldEngine = false; + }; + struct SceneLayer { uint32_t id = 0; @@ -100,6 +105,9 @@ namespace Volt void SetActiveLayer(uint32_t layerId); bool LayerExists(uint32_t layerId); + void MarkEntityAsEdited(const Entity& entity); + void ClearEditedEntities(); + inline const uint32_t GetActiveLayer() const { return m_sceneLayers.at(m_activeLayerIndex).id; } inline const std::vector& GetLayers() const { return m_sceneLayers; } inline std::vector& GetLayersMutable() { return m_sceneLayers; } @@ -108,6 +116,9 @@ namespace Volt inline MonoScriptFieldCache& GetScriptFieldCache() { return m_monoFieldCache; } const bool IsRelatedTo(Entity entity, Entity otherEntity); + inline SceneSettings& GetSceneSettingsMutable() { return m_sceneSettings; } + inline const SceneSettings& GetSceneSettings() const { return m_sceneSettings; } + void SetRenderSize(uint32_t aWidth, uint32_t aHeight); Entity CreateEntity(const std::string& tag = ""); @@ -117,7 +128,6 @@ namespace Volt entt::entity GetHandleFromUUID(const EntityID uuid) const; void RemoveEntity(Entity entity); - void ParentEntity(Entity parent, Entity child); void UnparentEntity(Entity entity); @@ -143,10 +153,9 @@ namespace Volt template void ForEachWithComponents(const F& func); - template - void ForEachParallelWithComponents(const F& func); - const std::vector GetAllEntities() const; + const std::vector GetAllEditedEntities() const; + const std::vector GetAllRemovedEntities() const; static const std::set GetDependencyList(const std::filesystem::path& scenePath); static bool IsSceneFullyLoaded(const std::filesystem::path& scenePath); @@ -198,6 +207,7 @@ namespace Volt ////////////////////////////// SceneEnvironment m_environment; + SceneSettings m_sceneSettings; Statistics m_statistics; bool m_isPlaying = false; diff --git a/Volt/Volt/src/Volt/Utility/Algorithms.cpp b/Volt/Volt/src/Volt/Utility/Algorithms.cpp index b9fbfcd0e..fa7d86fef 100644 --- a/Volt/Volt/src/Volt/Utility/Algorithms.cpp +++ b/Volt/Volt/src/Volt/Utility/Algorithms.cpp @@ -4,6 +4,7 @@ #include "Volt/Math/Math.h" #include "Volt/Core/Application.h" #include "Volt/Core/Threading/ThreadPool.h" +#include "Volt/Core/Base.h" namespace Volt::Algo { @@ -42,6 +43,8 @@ namespace Volt::Algo void ForEachParallel(std::function&& func, uint32_t iterationCount) { + VT_CORE_ASSERT(iterationCount > 0, "Iteration count must be greater than zero!"); + auto& threadPool = Application::GetThreadPool(); const uint32_t threadCount = std::min(iterationCount, threadPool.GetThreadCount()); From 918e2eb546328121c69e9c69242e5538a83bab89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Thu, 14 Dec 2023 22:14:29 +0100 Subject: [PATCH 5/5] Implemented base of WorldEngine --- Engine/Launcher.exe | 4 +- Engine/Sandbox.exe | 4 +- Engine/Scripts/Volt-ScriptCore.dll | 4 +- Volt/Sandbox/src/Sandbox/Sandbox.cpp | 2 + .../src/Sandbox/Utility/EditorUtilities.cpp | 11 + .../src/Sandbox/Utility/EditorUtilities.h | 1 + .../src/Sandbox/Window/PropertiesPanel.cpp | 2 +- .../src/Sandbox/Window/SceneViewPanel.cpp | 20 +- .../src/Sandbox/Window/ViewportPanel.cpp | 2 +- .../src/Sandbox/Window/WorldEnginePanel.cpp | 72 ++++++ .../src/Sandbox/Window/WorldEnginePanel.h | 14 ++ .../Volt/Asset/Importers/SceneImporter.cpp | 218 +++++++++++++++++- .../src/Volt/Asset/Importers/SceneImporter.h | 7 + .../Volt/src/Volt/Components/CoreComponents.h | 22 ++ Volt/Volt/src/Volt/EntryPoint.h | 13 +- Volt/Volt/src/Volt/Math/Math.h | 13 ++ Volt/Volt/src/Volt/Scene/Scene.cpp | 22 +- Volt/Volt/src/Volt/Scene/Scene.h | 9 +- .../src/Volt/Scene/WorldEngine/WorldCell.h | 23 ++ .../Volt/Scene/WorldEngine/WorldEngine.cpp | 195 ++++++++++++++++ .../src/Volt/Scene/WorldEngine/WorldEngine.h | 47 ++++ Volt/Volt/src/Volt/Utility/Algorithms.cpp | 22 +- Volt/Volt/src/Volt/Utility/Algorithms.h | 5 +- 23 files changed, 704 insertions(+), 28 deletions(-) create mode 100644 Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.cpp create mode 100644 Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.h create mode 100644 Volt/Volt/src/Volt/Scene/WorldEngine/WorldCell.h create mode 100644 Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.cpp create mode 100644 Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.h diff --git a/Engine/Launcher.exe b/Engine/Launcher.exe index e12b26219..08d037f74 100644 --- a/Engine/Launcher.exe +++ b/Engine/Launcher.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b025add2fab2758a4285ab25bbdc6dcadb939298a753a84cb5e42319d997bd42 -size 26464768 +oid sha256:c93f087dd44a83598fca6acc33a15f24336f53716b7fc06507f717b7aa606371 +size 26640896 diff --git a/Engine/Sandbox.exe b/Engine/Sandbox.exe index a3641b25c..ac296dcd3 100644 --- a/Engine/Sandbox.exe +++ b/Engine/Sandbox.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50884c1e3054bdca66a12816419864e1dfa9e3c4d15f1986a4b126978311095f -size 42923520 +oid sha256:277b4eda0a027174ff4e3cd945ee9534f511da9b98cc375fab837f7203b635ca +size 43632640 diff --git a/Engine/Scripts/Volt-ScriptCore.dll b/Engine/Scripts/Volt-ScriptCore.dll index 223920832..ec5b9e3ea 100644 --- a/Engine/Scripts/Volt-ScriptCore.dll +++ b/Engine/Scripts/Volt-ScriptCore.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8920b464cbd4a15fd79b405d04043221e662f4d0b456f0baa88151c71a086ac -size 102912 +oid sha256:1180e5dd5e612b687bbba15f0506b40ccab9fbc8e957fcbd19691871231c5e21 +size 94720 diff --git a/Volt/Sandbox/src/Sandbox/Sandbox.cpp b/Volt/Sandbox/src/Sandbox/Sandbox.cpp index b952e130a..2f5836594 100644 --- a/Volt/Sandbox/src/Sandbox/Sandbox.cpp +++ b/Volt/Sandbox/src/Sandbox/Sandbox.cpp @@ -42,6 +42,7 @@ #include "Sandbox/Window/Net/NetContractPanel.h" #include "Sandbox/Window/BehaviourGraph/BehaviorPanel.h" #include "Sandbox/Window/SceneSettingsPanel.h" +#include "Sandbox/Window/WorldEnginePanel.h" #include "Sandbox/VertexPainting/VertexPainterPanel.h" #include "Sandbox/Utility/EditorResources.h" @@ -145,6 +146,7 @@ void Sandbox::OnAttach() EditorLibrary::Register("Advanced"); EditorLibrary::Register("Advanced"); EditorLibrary::Register("", myRuntimeScene); + EditorLibrary::Register("", myRuntimeScene); if (userSettings.sceneSettings.lowMemoryUsage) { diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp index 6f2872570..d10267dd6 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp @@ -984,3 +984,14 @@ void EditorUtils::MarkEntityAsEdited(const Volt::Entity& entity) auto scene = entity.GetScene(); scene->MarkEntityAsEdited(entity); } + +void EditorUtils::MarkEntityAndChildrenAsEdited(const Volt::Entity& entity) +{ + auto scene = entity.GetScene(); + scene->MarkEntityAsEdited(entity); + + for (const auto& child : entity.GetChildren()) + { + MarkEntityAndChildrenAsEdited(child); + } +} diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h index 3353d09e8..85e1ac92f 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.h @@ -81,6 +81,7 @@ class EditorUtils static std::filesystem::path GetThumbnailPathFromPath(const std::filesystem::path& path); static void MarkEntityAsEdited(const Volt::Entity& entity); + static void MarkEntityAndChildrenAsEdited(const Volt::Entity& entity); private: static bool AssetBrowserPopupInternal(const std::string& id, Volt::AssetHandle& assetHandle, bool startState, Volt::AssetType wantedType = Volt::AssetType::None); diff --git a/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp index ba4821fc4..209a761fa 100644 --- a/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/PropertiesPanel.cpp @@ -151,7 +151,7 @@ void PropertiesPanel::UpdateMainContent() ent.SetLocalPosition(transform.position); myCurrentScene->InvalidateEntityTransform(entId); - EditorUtils::MarkEntityAsEdited(ent); + EditorUtils::MarkEntityAndChildrenAsEdited(ent); } } diff --git a/Volt/Sandbox/src/Sandbox/Window/SceneViewPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/SceneViewPanel.cpp index e2f71d538..85c082134 100644 --- a/Volt/Sandbox/src/Sandbox/Window/SceneViewPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/SceneViewPanel.cpp @@ -251,6 +251,7 @@ void SceneViewPanel::UpdateMainContent() //data->myChild = child; //undoData.push_back(data); + EditorUtils::MarkEntityAsEdited(entity); m_scene->MoveToLayer(entity, layer.id); } @@ -288,6 +289,7 @@ void SceneViewPanel::UpdateMainContent() } entity.SetVisible(newVal); + EditorUtils::MarkEntityAsEdited(entity); } } @@ -313,6 +315,7 @@ void SceneViewPanel::UpdateMainContent() } entity.SetLocked(newVal); + EditorUtils::MarkEntityAsEdited(entity); } } } @@ -465,6 +468,7 @@ void SceneViewPanel::HighlightEntity(Volt::Entity entity) void RecursiveUnpackPrefab(Ref scene, Volt::EntityID id) { Volt::Entity entity = scene->GetEntityFromUUID(id); + EditorUtils::MarkEntityAsEdited(entity); if (entity.HasComponent()) { @@ -845,6 +849,9 @@ void SceneViewPanel::DrawEntity(Volt::Entity entity, const std::string& filter) undoData.push_back(data); m_scene->ParentEntity(newParent, child); + + EditorUtils::MarkEntityAsEdited(child); + EditorUtils::MarkEntityAsEdited(newParent); } Ref command = CreateRef(undoData, ParentingAction::Parent); @@ -984,6 +991,7 @@ void SceneViewPanel::DrawEntity(Volt::Entity entity, const std::string& filter) recursiveSetVisible(e, visible, recursiveSetVisible); } + EditorUtils::MarkEntityAsEdited(entity); return false; }; @@ -1062,6 +1070,8 @@ void SceneViewPanel::CreatePrefabAndSetupEntities(Volt::Entity entity) path.erase(std::remove_if(path.begin(), path.end(), ::isspace), path.end()); Volt::AssetManager::SaveAssetAs(prefab, path); + + EditorUtils::MarkEntityAndChildrenAsEdited(entity); } void SceneViewPanel::UpdatePrefabsInScene(Ref prefab, Volt::Entity srcEntity) @@ -1089,7 +1099,10 @@ void SceneViewPanel::UpdatePrefabsInScene(Ref prefab, Volt::Entity return; } - prefabAsset->UpdateEntityInScene(Volt::Entity{ id, m_scene }); + auto entity = Volt::Entity{ id, m_scene }; + prefabAsset->UpdateEntityInScene(entity); + + EditorUtils::MarkEntityAsEdited(entity); }); if (prefabAsset->IsReference(srcEntity)) @@ -1114,7 +1127,10 @@ void SceneViewPanel::UpdatePrefabsInScene(Ref prefab, Volt::Entity return; } - prefabRefAsset->UpdateEntityInScene(Volt::Entity{ id, m_scene }); + auto entity = Volt::Entity{ id, m_scene }; + prefabRefAsset->UpdateEntityInScene(entity); + + EditorUtils::MarkEntityAsEdited(entity); }); } } diff --git a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp index dfd159f3e..5d2a96ae4 100644 --- a/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp +++ b/Volt/Sandbox/src/Sandbox/Window/ViewportPanel.cpp @@ -149,7 +149,7 @@ void ViewportPanel::UpdateMainContent() for (const auto& entId : SelectionManager::GetSelectedEntities()) { auto entity = m_editorScene->GetEntityFromUUID(entId); - EditorUtils::MarkEntityAsEdited(entity); + EditorUtils::MarkEntityAndChildrenAsEdited(entity); } } diff --git a/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.cpp b/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.cpp new file mode 100644 index 000000000..6455ec203 --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.cpp @@ -0,0 +1,72 @@ +#include "sbpch.h" +#include "WorldEnginePanel.h" + +#include +#include + +WorldEnginePanel::WorldEnginePanel(Ref& editorScene) + : EditorWindow("World Engine"), m_editorScene(editorScene) +{ +} + +void WorldEnginePanel::UpdateMainContent() +{ + auto& worldEngine = m_editorScene->GetWorldEngineMutable(); + + if (UI::BeginProperties("worldEngineSettings")) + { + if (UI::Property("Cell Size", worldEngine.GetSettingsMutable().cellSize)) + { + worldEngine.GenerateCells(); + } + + if (UI::Property("World Size", worldEngine.GetSettingsMutable().worldSize)) + { + worldEngine.GenerateCells(); + } + + UI::EndProperties(); + } + + ImGui::Text("Cells"); + + const glm::uvec2& worldSize = worldEngine.GetSettings().worldSize; + const int32_t cellSize = worldEngine.GetSettings().cellSize; + + const uint32_t cellCountX = Math::DivideRoundUp(worldSize.x, static_cast(cellSize)); + const uint32_t cellCountY = Math::DivideRoundUp(worldSize.y, static_cast(cellSize)); + + const float contentWidth = ImGui::GetContentRegionAvail().x; + const float buttonSize = contentWidth / static_cast(cellCountX); + + UI::ScopedStyleFloat2 padding{ ImGuiStyleVar_ItemSpacing, { 0.f } }; + + for (uint32_t x = 0; x < cellCountX; x++) + { + for (uint32_t y = 0; y < cellCountY; y++) + { + glm::vec4 color = { 1.f, 0.f, 0.f, 1.f }; + + Volt::WorldCellID cellId = (x * cellCountX) + y; + + if (worldEngine.IsCellLoaded(cellId)) + { + color = { 0.f, 1.f, 0.f, 1.f }; + } + + UI::ScopedColor buttonColor{ ImGuiCol_Button, color }; + + std::string id = "Cell " + std::to_string(cellId) + "##" + std::to_string(x + y); + if (ImGui::Button(id.c_str(), { buttonSize, buttonSize })) + { + worldEngine.BeginStreamingCell(cellId); + } + + if (y < cellCountY - 1) + { + ImGui::SameLine(); + } + } + } +} + diff --git a/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.h b/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.h new file mode 100644 index 000000000..61b8dd584 --- /dev/null +++ b/Volt/Sandbox/src/Sandbox/Window/WorldEnginePanel.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Sandbox/Window/EditorWindow.h" + +class WorldEnginePanel : public EditorWindow +{ +public: + WorldEnginePanel(Ref& editorScene); + + void UpdateMainContent() override; + +private: + Ref& m_editorScene; +}; diff --git a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp index 872e5e35e..378492e65 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.cpp @@ -152,6 +152,11 @@ namespace Volt scene->m_sceneSettings.useWorldEngine = streamReader.ReadKey("useWorldEngine", false); streamReader.ExitScope(); + if (scene->m_sceneSettings.useWorldEngine) + { + DeserializeWorldEngine(scene, streamReader); + } + streamReader.ExitScope(); const std::filesystem::path& scenePath = filePath; @@ -159,7 +164,8 @@ namespace Volt if (scene->m_sceneSettings.useWorldEngine) { - LoadEntities(metadata, scene, directoryPath); + LoadCellEntities(metadata, scene, directoryPath); + //LoadEntities(metadata, scene, directoryPath); } else { @@ -191,6 +197,11 @@ namespace Volt streamWriter.SetKey("useWorldEngine", scene->m_sceneSettings.useWorldEngine); streamWriter.EndMap(); + if (scene->m_sceneSettings.useWorldEngine) + { + SerializeWorldEngine(scene, streamWriter); + } + streamWriter.EndMap(); streamWriter.EndMap(); streamWriter.WriteToDisk(); @@ -316,7 +327,7 @@ namespace Volt const auto entities = scene->GetAllEditedEntities(); if (!entities.empty()) { - Algo::ForEachParallel([entitiesDirectoryPath, entities, metadata, scene, this](uint32_t i) + Algo::ForEachParallel([entitiesDirectoryPath, entities, metadata, scene, this](uint32_t threadIdx, uint32_t i) { Entity entity = entities.at(i); const auto entityPath = entitiesDirectoryPath / (entity.ToString() + ".entity"); @@ -332,7 +343,7 @@ namespace Volt const auto removedEntities = scene->GetAllRemovedEntities(); if (!removedEntities.empty()) { - Algo::ForEachParallel([removedEntities, entitiesDirectoryPath](uint32_t i) + Algo::ForEachParallel([removedEntities, entitiesDirectoryPath](uint32_t threadIdx, uint32_t i) { EntityID id = removedEntities.at(i); @@ -376,10 +387,15 @@ namespace Volt return; } + const uint32_t iterationCount = static_cast(entityPaths.size()); + std::vector> dummyScenes{}; - auto futures = Algo::ForEachParallelLockable([&dummyScenes, entityPaths, metadata, this](uint32_t i) + dummyScenes.resize(iterationCount); + + auto futures = Algo::ForEachParallelLockable([&dummyScenes, entityPaths, metadata, this](uint32_t threadIdx, uint32_t i) { Ref dummyScene = CreateRef(); + dummyScenes[threadIdx] = dummyScene; const auto& path = entityPaths.at(i); @@ -390,7 +406,6 @@ namespace Volt } DeserializeEntity(dummyScene, metadata, streamReader); - dummyScenes.push_back(dummyScene); }, static_cast(entityPaths.size())); @@ -409,6 +424,106 @@ namespace Volt } } + void SceneImporter::SerializeWorldEngine(const Ref& scene, YAMLStreamWriter& streamWriter) const + { + auto& worldEngine = scene->m_worldEngine; + + streamWriter.BeginMapNamned("WorldEngine"); + streamWriter.SetKey("cellSize", worldEngine.GetSettings().cellSize); + streamWriter.SetKey("worldSize", worldEngine.GetSettings().worldSize); + + streamWriter.EndMap(); + } + + void SceneImporter::DeserializeWorldEngine(const Ref& scene, YAMLStreamReader& streamReader) const + { + auto& worldEngine = scene->m_worldEngine; + + streamReader.EnterScope("WorldEngine"); + worldEngine.GetSettingsMutable().cellSize = streamReader.ReadKey("cellSize", 256); + worldEngine.GetSettingsMutable().worldSize = streamReader.ReadKey("worldSize", glm::uvec2{ 1280 }); + + worldEngine.GenerateCells(); + + streamReader.ExitScope(); + } + + void SceneImporter::LoadCellEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const + { + VT_PROFILE_FUNCTION(); + + std::filesystem::path layersFolderPath = sceneDirectory / "Entities"; + if (!std::filesystem::exists(layersFolderPath)) + { + return; + } + + std::vector entityPaths; + + for (const auto& it : std::filesystem::directory_iterator(layersFolderPath)) + { + if (!it.is_directory() && it.path().extension().string() == ".entity") + { + entityPaths.emplace_back(it.path()); + } + } + + if (entityPaths.empty()) + { + return; + } + + const uint32_t iterationCount = static_cast(entityPaths.size()); + + std::vector>> threadCellEntities{}; + threadCellEntities.resize(Algo::GetThreadCountFromIterationCount(iterationCount)); + + auto futures = Algo::ForEachParallelLockable([&threadCellEntities, entityPaths, metadata, this](uint32_t threadIdx, uint32_t i) + { + const auto& path = entityPaths.at(i); + + YAMLStreamReader streamReader{}; + if (!streamReader.OpenFile(path)) + { + return; + } + + streamReader.EnterScope("Entity"); + + EntityID entityId = streamReader.ReadKey("id", Entity::NullID()); + WorldCellID cellId = streamReader.ReadKey("cellId", INVALID_WORLD_CELL_ID); + + if (entityId == Entity::NullID()) + { + return; + } + + if (cellId == INVALID_WORLD_CELL_ID) + { + cellId = 0; + } + + streamReader.ExitScope(); + + threadCellEntities[threadIdx][cellId].push_back(entityId); + }, + iterationCount); + + for (auto& f : futures) + { + f.wait(); + } + + auto& worldEngine = scene->m_worldEngine; + for (const auto& tCellEntities : threadCellEntities) + { + for (const auto& [cellId, entities] : tCellEntities) + { + worldEngine.AddEntitiesToCell(cellId, entities); + } + } + } + Entity SceneImporter::CreateEntityFromUUIDThreadSafe(EntityID entityId, const Ref& scene) const { static std::mutex createEntityMutex; @@ -427,6 +542,7 @@ namespace Volt Entity entity{ id, scene }; streamWriter.SetKey("id", entity.GetID()); + streamWriter.SetKey("cellId", scene->m_worldEngine.GetCellIDFromEntity(entity)); streamWriter.BeginSequence("components"); { for (auto&& curr : registry.storage()) @@ -913,4 +1029,96 @@ namespace Volt streamReader.ExitScope(); }); } + + void SceneImporter::LoadWorldCell(const Ref& scene, const WorldCell& worldCell) const + { + VT_PROFILE_FUNCTION(); + + if (worldCell.isLoaded) + { + VT_CORE_WARN("[SceneImporter]: World Cell is already loaded!"); + return; + } + + if (worldCell.cellEntities.empty()) + { + VT_CORE_WARN("[SceneImporter]: Unable to load World Cell which contains zero entities!"); + return; + } + + const auto& metadata = AssetManager::GetMetadataFromHandle(scene->handle); + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + const std::filesystem::path sceneDirectory = filePath.parent_path(); + + std::filesystem::path layersFolderPath = sceneDirectory / "Entities"; + if (!std::filesystem::exists(layersFolderPath)) + { + return; + } + + std::vector entityPaths; + + for (const auto& it : std::filesystem::directory_iterator(layersFolderPath)) + { + if (!it.is_directory() && it.path().extension().string() == ".entity") + { + entityPaths.emplace_back(it.path()); + } + } + + for (int32_t i = static_cast(entityPaths.size()) - 1; i >= 0; i--) + { + const auto& path = entityPaths.at(i); + + const std::string stem = path.stem().string(); + uint32_t entityId = std::stoul(stem); + auto it = std::ranges::find(worldCell.cellEntities, EntityID(entityId)); + + if (it == worldCell.cellEntities.end()) + { + entityPaths.erase(entityPaths.begin() + i); + } + } + + if (entityPaths.empty()) + { + return; + } + + const uint32_t iterationCount = static_cast(entityPaths.size()); + + std::vector> dummyScenes{}; + dummyScenes.resize(iterationCount); + + auto futures = Algo::ForEachParallelLockable([&dummyScenes, entityPaths, metadata, this](uint32_t threadIdx, uint32_t i) + { + Ref dummyScene = CreateRef(); + dummyScenes[threadIdx] = dummyScene; + + const auto& path = entityPaths.at(i); + + YAMLStreamReader streamReader{}; + if (!streamReader.OpenFile(path)) + { + return; + } + + DeserializeEntity(dummyScene, metadata, streamReader); + }, + static_cast(entityPaths.size())); + + for (auto& f : futures) + { + f.wait(); + } + + for (const auto& dummyScene : dummyScenes) + { + for (const auto& entity : dummyScene->GetAllEntities()) + { + Entity realEntity = scene->CreateEntityWithUUID(entity.GetID()); + Entity::Copy(entity, realEntity, Volt::EntityCopyFlags::None); + } + } + } } diff --git a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h index c343ae215..b955e01a4 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/SceneImporter.h @@ -36,6 +36,8 @@ namespace Volt void DeserializeEntity(const Ref& scene, const AssetMetadata& metadata, YAMLStreamReader& streamReader) const; void DeserializeMono(entt::entity id, const Ref& scene, YAMLStreamReader& streamReader) const; + void LoadWorldCell(const Ref& scene, const WorldCell& worldCell) const; + [[nodiscard]] inline static const SceneImporter& Get() { return *s_instance; } [[nodiscard]] inline static const auto& GetTypeDeserializers() { return s_typeDeserializers; } @@ -48,6 +50,11 @@ namespace Volt void SaveEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; void LoadEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; + void SerializeWorldEngine(const Ref& scene, YAMLStreamWriter& streamWriter) const; + void DeserializeWorldEngine(const Ref& scene, YAMLStreamReader& streamReader) const; + + void LoadCellEntities(const AssetMetadata& metadata, const Ref& scene, const std::filesystem::path& sceneDirectory) const; + Entity CreateEntityFromUUIDThreadSafe(EntityID entityId, const Ref& scene) const; void SerializeClass(const uint8_t* data, const size_t offset, const IComponentTypeDesc* compDesc, YAMLStreamWriter& streamWriter, bool isSubComponent) const; diff --git a/Volt/Volt/src/Volt/Components/CoreComponents.h b/Volt/Volt/src/Volt/Components/CoreComponents.h index 78c08ad20..8b55d65b1 100644 --- a/Volt/Volt/src/Volt/Components/CoreComponents.h +++ b/Volt/Volt/src/Volt/Components/CoreComponents.h @@ -12,6 +12,25 @@ namespace Volt { + enum class Movability : uint32_t + { + Static = 0, + Stationary, + Movable + }; + + static void ReflectType(TypeDesc& reflect) + { + reflect.SetGUID("{2DC55D4C-63C8-432A-8037-1D6762C8DC33}"_guid); + reflect.SetLabel("Movability"); + reflect.SetDefaultValue(Movability::Static); + reflect.AddConstant(Movability::Static, "static", "Static"); + reflect.AddConstant(Movability::Stationary, "stationary", "Stationary"); + reflect.AddConstant(Movability::Movable, "movable", "Movable"); + } + + REGISTER_ENUM(Movability); + struct CommonComponent { uint32_t layerId = 0; @@ -65,6 +84,8 @@ namespace Volt glm::quat rotation = glm::identity(); glm::vec3 scale = { 1.f }; + Movability movability = Movability::Static; + bool visible = true; bool locked = false; @@ -99,6 +120,7 @@ namespace Volt reflect.AddMember(&TransformComponent::scale, "scale", "Scale", "", glm::vec3{ 1.f }); reflect.AddMember(&TransformComponent::visible, "visible", "Visible", "", true); reflect.AddMember(&TransformComponent::locked, "locked", "Locked", "", false); + reflect.AddMember(&TransformComponent::movability, "movability", "Movability", "", Movability::Static); } REGISTER_COMPONENT(TransformComponent); diff --git a/Volt/Volt/src/Volt/EntryPoint.h b/Volt/Volt/src/Volt/EntryPoint.h index 846172a06..65c0225c5 100644 --- a/Volt/Volt/src/Volt/EntryPoint.h +++ b/Volt/Volt/src/Volt/EntryPoint.h @@ -41,7 +41,9 @@ namespace Volt int Main(const std::filesystem::path& appPath) { std::filesystem::path dmpPath; + CreateProxy(dmpPath, appPath); + return 0; } } @@ -52,7 +54,16 @@ namespace Volt int APIENTRY WinMain(HINSTANCE aHInstance, HINSTANCE aPrevHInstance, PSTR aCmdLine, int aCmdShow) { - return Volt::Main(aCmdLine); + LPWSTR* szArglist; + int nArgs = 0; + szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); + + if (nArgs > 1) + { + return Volt::Main(szArglist[1]); + } + + return Volt::Main(""); } #else diff --git a/Volt/Volt/src/Volt/Math/Math.h b/Volt/Volt/src/Volt/Math/Math.h index fa895587f..c9bc41b87 100644 --- a/Volt/Volt/src/Volt/Math/Math.h +++ b/Volt/Volt/src/Volt/Math/Math.h @@ -152,4 +152,17 @@ namespace Math { return (numerator + denominator - T{ 1 }) / denominator; } + + template + concept Integer = std::is_integral::value; + + template + inline static T RoundToClosestMultiple(const T& number, const T& multiple) + { + T result = std::abs(number) + multiple / 2; + result -= result % multiple; + result *= number > 0 ? 1 : -1; + + return result; + } } diff --git a/Volt/Volt/src/Volt/Scene/Scene.cpp b/Volt/Volt/src/Volt/Scene/Scene.cpp index c725dab3b..37537c427 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.cpp +++ b/Volt/Volt/src/Volt/Scene/Scene.cpp @@ -58,6 +58,12 @@ namespace Volt SetupComponentFunctions(); AddLayer("Main", 0); + + m_worldEngine.Reset(this, 16, 4); + } + + void Scene::PostInitialize() + { } Scene::Scene() @@ -67,6 +73,8 @@ namespace Volt SetupComponentFunctions(); AddLayer("Main", 0); + + m_worldEngine.Reset(this, 16, 4); } void Scene::OnEvent(Event& e) @@ -313,9 +321,9 @@ namespace Volt // Update scene data { - SceneData sceneData; - sceneData.deltaTime = aDeltaTime; - sceneData.timeSinceStart = m_timeSinceStart; + //SceneData sceneData; + //sceneData.deltaTime = aDeltaTime; + //sceneData.timeSinceStart = m_timeSinceStart; //Renderer::SetSceneData(sceneData); } @@ -385,6 +393,7 @@ namespace Volt m_entityRegistry.AddEntity(newEntity); m_entityRegistry.MarkEntityAsEdited(newEntity); + m_worldEngine.AddEntity(newEntity); InvalidateEntityTransform(uuid); SortScene(); @@ -424,9 +433,11 @@ namespace Volt newEntity.GetComponent().id = uuid; m_entityRegistry.AddEntity(newEntity); + m_worldEngine.AddEntity(newEntity); InvalidateEntityTransform(uuid); SortScene(); + return newEntity; } @@ -543,6 +554,11 @@ namespace Volt m_cachedEntityTransforms.erase(currentUUID); } } + + if (m_sceneSettings.useWorldEngine) + { + m_worldEngine.OnEntityMoved(ent); + } } } diff --git a/Volt/Volt/src/Volt/Scene/Scene.h b/Volt/Volt/src/Volt/Scene/Scene.h index 6d2604b92..eaa68f04e 100644 --- a/Volt/Volt/src/Volt/Scene/Scene.h +++ b/Volt/Volt/src/Volt/Scene/Scene.h @@ -8,6 +8,7 @@ #include "Volt/Vision/TimelinePlayer.h" #include "Volt/Scene/EntityRegistry.h" +#include "Volt/Scene/WorldEngine/WorldEngine.h" #include "Volt/Scripting/Mono/MonoScriptFieldCache.h" @@ -72,6 +73,8 @@ namespace Volt Scene(); Scene(const std::string& name); + void PostInitialize(); + inline entt::registry& GetRegistry() { return m_registry; } inline const std::string& GetName() const { return m_name; } inline const Statistics& GetStatistics() const { return m_statistics; } @@ -114,11 +117,13 @@ namespace Volt inline const MonoScriptFieldCache& GetScriptFieldCache() const { return m_monoFieldCache; } inline MonoScriptFieldCache& GetScriptFieldCache() { return m_monoFieldCache; } - const bool IsRelatedTo(Entity entity, Entity otherEntity); inline SceneSettings& GetSceneSettingsMutable() { return m_sceneSettings; } inline const SceneSettings& GetSceneSettings() const { return m_sceneSettings; } + inline const WorldEngine& GetWorldEngine() const { return m_worldEngine; } + inline WorldEngine& GetWorldEngineMutable() { return m_worldEngine; } + void SetRenderSize(uint32_t aWidth, uint32_t aHeight); Entity CreateEntity(const std::string& tag = ""); @@ -127,6 +132,7 @@ namespace Volt Entity GetEntityFromUUID(const EntityID uuid) const; entt::entity GetHandleFromUUID(const EntityID uuid) const; + const bool IsRelatedTo(Entity entity, Entity otherEntity); void RemoveEntity(Entity entity); void ParentEntity(Entity parent, Entity child); void UnparentEntity(Entity entity); @@ -209,6 +215,7 @@ namespace Volt SceneEnvironment m_environment; SceneSettings m_sceneSettings; Statistics m_statistics; + WorldEngine m_worldEngine; bool m_isPlaying = false; float m_timeSinceStart = 0.f; diff --git a/Volt/Volt/src/Volt/Scene/WorldEngine/WorldCell.h b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldCell.h new file mode 100644 index 000000000..53b43c227 --- /dev/null +++ b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldCell.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Volt/Scene/EntityID.h" + +#include + +#include + +namespace Volt +{ + typedef uint32_t WorldCellID; + + static constexpr WorldCellID INVALID_WORLD_CELL_ID = std::numeric_limits::max(); + + struct WorldCell + { + WorldCellID cellId = 0; + std::vector cellEntities; + glm::ivec3 origin; + + bool isLoaded = false; + }; +} diff --git a/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.cpp b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.cpp new file mode 100644 index 000000000..05545a35a --- /dev/null +++ b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.cpp @@ -0,0 +1,195 @@ +#include "vtpch.h" +#include "WorldEngine.h" + +#include "Volt/Scene/Scene.h" +#include "Volt/Scene/Entity.h" + +#include "Volt/Components/CoreComponents.h" + +#include "Volt/Asset/Importers/SceneImporter.h" + +#include "Volt/Math/Math.h" + +namespace Volt +{ + void WorldEngine::Reset(Scene* scene, uint32_t initialCellCount, uint32_t cellCountWidth) + { + m_scene = scene; + + m_cells.clear(); + + for (uint32_t i = 0; i < initialCellCount; i++) + { + auto& newCell = m_cells.emplace_back(); + newCell.cellId = i; + newCell.origin = { (i / cellCountWidth) * m_settings.cellSize / 2, 0, (i % cellCountWidth) * m_settings.cellSize / 2 }; + } + + // Put entities into cells + for (const auto& entity : m_scene->GetAllEntities()) + { + AddEntity(entity); + } + } + + void WorldEngine::AddEntity(const Entity& entity) + { + // We only want to add non movable actors to World Engine + if (entity.GetComponent().movability == Movability::Movable) + { + return; + } + + const auto position = entity.GetPosition(); + const glm::ivec3 intPosition = position; + + const int32_t closestXPos = Math::RoundToClosestMultiple(intPosition.x, m_settings.cellSize / 2); + const int32_t closestZPos = Math::RoundToClosestMultiple(intPosition.z, m_settings.cellSize / 2); + + for (auto& cell : m_cells) + { + if (cell.origin == glm::ivec3{ closestXPos, 0, closestZPos }) + { + cell.cellEntities.emplace_back(entity.GetID()); + } + } + } + + void WorldEngine::RemoveEntity(const Entity& entity) + { + for (auto& cell : m_cells) + { + auto it = std::find_if(cell.cellEntities.begin(), cell.cellEntities.end(), [&](const auto id) { return id == entity.GetID(); }); + if (it != cell.cellEntities.end()) + { + cell.cellEntities.erase(it); + } + } + } + + void WorldEngine::AddCell(const glm::ivec3& origin, WorldCellID id) + { + for (const auto& cell : m_cells) + { + if (cell.origin == origin) + { + // Cell with that origin already exists! + return; + } + } + + auto& newCell = m_cells.emplace_back(); + newCell.origin = origin; + newCell.cellId = id == std::numeric_limits::max() ? static_cast(m_cells.size() - 1) : id; + } + + void WorldEngine::GenerateCells() + { + m_cells.clear(); + + const glm::uvec2& worldSize = m_settings.worldSize; + + // Find absolute origin offset + const glm::ivec2 absoluteOrigin = worldSize / 2u; + + const uint32_t cellCountX = Math::DivideRoundUp(worldSize.x, static_cast(m_settings.cellSize)); + const uint32_t cellCountY = Math::DivideRoundUp(worldSize.y, static_cast(m_settings.cellSize)); + + for (uint32_t x = 0; x < cellCountX; x++) + { + for (uint32_t y = 0; y < cellCountY; y++) + { + const glm::ivec3 cellOrigin = { x * m_settings.cellSize - absoluteOrigin.x + m_settings.cellSize / 2, 0, y * m_settings.cellSize - absoluteOrigin.y + m_settings.cellSize / 2 }; + AddCell(cellOrigin); + } + } + + // Put entities into cells + for (const auto& entity : m_scene->GetAllEntities()) + { + AddEntity(entity); + } + } + + void WorldEngine::AddEntitiesToCell(WorldCellID cellId, const std::vector& entities) + { + auto cellIt = std::find_if(m_cells.begin(), m_cells.end(), [cellId](const WorldCell& cell) + { + return cell.cellId == cellId; + }); + + if (cellIt == m_cells.end()) + { + return; + } + + WorldCell& cell = *cellIt; + cell.cellEntities.insert(cell.cellEntities.end(), entities.begin(), entities.end()); + } + + void WorldEngine::OnEntityMoved(const Entity& entity) + { + RemoveEntity(entity); + AddEntity(entity); + } + + void WorldEngine::BeginStreamingCell(WorldCellID cellId) + { + auto& cell = GetCellFromID(cellId); + if (cell.cellId == INVALID_WORLD_CELL_ID) + { + return; + } + + SceneImporter::Get().LoadWorldCell(m_scene->shared_from_this(), cell); + cell.isLoaded = true; + } + + WorldCellID WorldEngine::GetCellIDFromEntity(const Entity& entity) const + { + for (const auto& cell : m_cells) + { + auto it = std::find_if(cell.cellEntities.begin(), cell.cellEntities.end(), [&](const auto id) { return id == entity.GetID(); }); + if (it != cell.cellEntities.end()) + { + return cell.cellId; + } + } + + return INVALID_WORLD_CELL_ID; + } + + bool WorldEngine::IsCellLoaded(WorldCellID cellId) const + { + const auto& cell = GetCellFromID(cellId); + return cell.isLoaded; + } + + WorldCell& WorldEngine::GetCellFromID(WorldCellID cellId) + { + for (auto& cell : m_cells) + { + if (cell.cellId == cellId) + { + return cell; + } + } + + static WorldCell nullCell{}; + return nullCell; + } + + const WorldCell& WorldEngine::GetCellFromID(WorldCellID cellId) const + { + for (auto& cell : m_cells) + { + if (cell.cellId == cellId) + { + return cell; + } + } + + static WorldCell nullCell{}; + return nullCell; + } +} diff --git a/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.h b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.h new file mode 100644 index 000000000..6b0447b70 --- /dev/null +++ b/Volt/Volt/src/Volt/Scene/WorldEngine/WorldEngine.h @@ -0,0 +1,47 @@ +#pragma once + +#include "WorldCell.h" + +namespace Volt +{ + struct WorldGridSettings + { + int32_t cellSize = 256; + glm::uvec2 worldSize = { 1280, 1280 }; + }; + + class Scene; + class Entity; + + class WorldEngine + { + public: + WorldEngine() = default; + + void Reset(Scene* scene, uint32_t initialCellCount, uint32_t cellCountWidth); + void AddEntity(const Entity& entity); + void RemoveEntity(const Entity& entity); + void AddCell(const glm::ivec3& origin, WorldCellID id = std::numeric_limits::max()); + void GenerateCells(); + void AddEntitiesToCell(WorldCellID cellId, const std::vector& entities); + void OnEntityMoved(const Entity& entity); + + void BeginStreamingCell(WorldCellID cellId); + + WorldCellID GetCellIDFromEntity(const Entity& entity) const; + [[nodiscard]] bool IsCellLoaded(WorldCellID cellId) const; + + [[nodiscard]] inline const std::vector& GetCells() const { return m_cells; } + [[nodiscard]] inline const WorldGridSettings& GetSettings() const { return m_settings; } + [[nodiscard]] inline WorldGridSettings& GetSettingsMutable() { return m_settings; } + + private: + WorldCell& GetCellFromID(WorldCellID cellId); + const WorldCell& GetCellFromID(WorldCellID cellId) const; + + WorldGridSettings m_settings; + std::vector m_cells; + + Scene* m_scene = nullptr; + }; +} diff --git a/Volt/Volt/src/Volt/Utility/Algorithms.cpp b/Volt/Volt/src/Volt/Utility/Algorithms.cpp index fa7d86fef..ac5b160fb 100644 --- a/Volt/Volt/src/Volt/Utility/Algorithms.cpp +++ b/Volt/Volt/src/Volt/Utility/Algorithms.cpp @@ -8,7 +8,7 @@ namespace Volt::Algo { - std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount) + std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount) { auto& threadPool = Application::GetThreadPool(); @@ -27,11 +27,11 @@ namespace Volt::Algo currThreadIterationCount = iterationCount - i * perThreadIterationCount; } - futures.emplace_back(threadPool.SubmitTask([currThreadIterationCount, func, iterOffset]() + futures.emplace_back(threadPool.SubmitTask([currThreadIterationCount, func, iterOffset, i]() { for (uint32_t iter = 0; iter < currThreadIterationCount; iter++) { - func(iter + iterOffset); + func(i, iter + iterOffset); } })); @@ -41,7 +41,7 @@ namespace Volt::Algo return futures; } - void ForEachParallel(std::function&& func, uint32_t iterationCount) + void ForEachParallel(std::function&& func, uint32_t iterationCount) { VT_CORE_ASSERT(iterationCount > 0, "Iteration count must be greater than zero!"); @@ -59,15 +59,25 @@ namespace Volt::Algo currThreadIterationCount = iterationCount - i * perThreadIterationCount; } - threadPool.SubmitTask([currThreadIterationCount, func, iterOffset]() + threadPool.SubmitTask([currThreadIterationCount, func, iterOffset, i]() { for (uint32_t iter = 0; iter < currThreadIterationCount; iter++) { - func(iter + iterOffset); + func(i, iter + iterOffset); } }); iterOffset += currThreadIterationCount; } } + + uint32_t GetThreadCountFromIterationCount(uint32_t iterationCount) + { + VT_CORE_ASSERT(iterationCount > 0, "Iteration count must be greater than zero!"); + + auto& threadPool = Application::GetThreadPool(); + const uint32_t threadCount = std::min(iterationCount, threadPool.GetThreadCount()); + + return threadCount; + } } diff --git a/Volt/Volt/src/Volt/Utility/Algorithms.h b/Volt/Volt/src/Volt/Utility/Algorithms.h index acd1fe8de..2e53d1fcc 100644 --- a/Volt/Volt/src/Volt/Utility/Algorithms.h +++ b/Volt/Volt/src/Volt/Utility/Algorithms.h @@ -5,6 +5,7 @@ namespace Volt::Algo { - extern [[nodiscard]] std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount); - extern void ForEachParallel(std::function&& func, uint32_t iterationCount); + extern [[nodiscard]] std::vector> ForEachParallelLockable(std::function&& func, uint32_t iterationCount); + extern void ForEachParallel(std::function&& func, uint32_t iterationCount); + extern [[nodiscard]] uint32_t GetThreadCountFromIterationCount(uint32_t iterationCount); }