From 78d13c0ab8f69e0cd37641c0e9913aed474d9e5a Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Sat, 1 Oct 2022 14:28:13 +0800 Subject: [PATCH 01/57] Changed some couts and asserts to use SHLOG --- SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp | 3 ++- SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h | 3 ++- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h index 8921fbce..517fb4b9 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h @@ -439,7 +439,7 @@ namespace SHADE { if ((templateIDs[i] == oID)) { - assert("This Component is owned by another group"); + SHLOG_WARNING("Component type already owned by another component group"); } } } diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp index bbf8d400..b0332728 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp @@ -88,7 +88,8 @@ namespace SHADE if (!entityVec[eIndex]) { //There is still an entity stored there.Something went wrong - assert("FATAL ERROR: Entity Creation error. Entity Index Conflict"); + SHLOG_CRITICAL("FATAL ERROR: Entity Creation error. Entity index conflict.") + } //Reset it to a newly constructed entity diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h index f32ab2c4..fac97339 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h @@ -119,7 +119,7 @@ namespace SHADE if (!entityVec[eIndex]) { //There is still an entity stored there.Something went wrong - assert("FATAL ERROR: Entity Creation error. Entity Index Conflict"); + SHLOG_CRITICAL("FATAL ERROR: Entity Creation error. Entity index conflict.") } //Reset it to a newly constructed entity diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp index 551233db..35269863 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp @@ -29,7 +29,7 @@ namespace SHADE { system.second->Init(); #ifdef _DEBUG - std::cout << system.first << " Init" << std::endl; + SHLOG_INFO("{} Init", system.first); #endif } } diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h index 995a1cf5..25ff0c15 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h @@ -94,7 +94,8 @@ namespace SHADE if (systemContainer.find(id) == systemContainer.end()) { - std::cout << "System Manager error: System Version " << version << " does not exit." << std::endl; + SHLOG_WARNING("System Manager warning: System Version {} does not exist. Returning as nullptr", version) + return nullptr; } From 5aee22a5e3fc06b02dcdc66ef9f029f130956a71 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Sat, 1 Oct 2022 16:37:47 +0800 Subject: [PATCH 02/57] Revert "Changed some couts and asserts to use SHLOG" This reverts commit 78d13c0ab8f69e0cd37641c0e9913aed474d9e5a. --- SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp | 3 +-- SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp | 2 +- SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h | 3 +-- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h index 517fb4b9..8921fbce 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.h @@ -439,7 +439,7 @@ namespace SHADE { if ((templateIDs[i] == oID)) { - SHLOG_WARNING("Component type already owned by another component group"); + assert("This Component is owned by another group"); } } } diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp index b0332728..bbf8d400 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp @@ -88,8 +88,7 @@ namespace SHADE if (!entityVec[eIndex]) { //There is still an entity stored there.Something went wrong - SHLOG_CRITICAL("FATAL ERROR: Entity Creation error. Entity index conflict.") - + assert("FATAL ERROR: Entity Creation error. Entity Index Conflict"); } //Reset it to a newly constructed entity diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h index fac97339..f32ab2c4 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h @@ -119,7 +119,7 @@ namespace SHADE if (!entityVec[eIndex]) { //There is still an entity stored there.Something went wrong - SHLOG_CRITICAL("FATAL ERROR: Entity Creation error. Entity index conflict.") + assert("FATAL ERROR: Entity Creation error. Entity Index Conflict"); } //Reset it to a newly constructed entity diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp index 35269863..551233db 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.cpp @@ -29,7 +29,7 @@ namespace SHADE { system.second->Init(); #ifdef _DEBUG - SHLOG_INFO("{} Init", system.first); + std::cout << system.first << " Init" << std::endl; #endif } } diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h index 25ff0c15..995a1cf5 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHSystemManager.h @@ -94,8 +94,7 @@ namespace SHADE if (systemContainer.find(id) == systemContainer.end()) { - SHLOG_WARNING("System Manager warning: System Version {} does not exist. Returning as nullptr", version) - + std::cout << "System Manager error: System Version " << version << " does not exit." << std::endl; return nullptr; } From b0f28f98c5500161c09ac93450de42834cf7ab87 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Thu, 27 Oct 2022 15:01:18 +0800 Subject: [PATCH 03/57] WIP camera arm component --- .../src/Application/SBApplication.cpp | 5 +- .../src/Camera/SHCameraArmComponent.cpp | 67 +++++++++++++++++++ .../src/Camera/SHCameraArmComponent.h | 43 ++++++++++++ SHADE_Engine/src/Camera/SHCameraComponent.h | 2 +- SHADE_Engine/src/Camera/SHCameraDirector.cpp | 7 ++ SHADE_Engine/src/Camera/SHCameraSystem.cpp | 42 +++++++++--- SHADE_Engine/src/Camera/SHCameraSystem.h | 8 ++- .../Inspector/SHEditorInspector.cpp | 5 ++ 8 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 SHADE_Engine/src/Camera/SHCameraArmComponent.cpp create mode 100644 SHADE_Engine/src/Camera/SHCameraArmComponent.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 54dc0ccf..ba49c904 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -108,7 +108,7 @@ namespace Sandbox SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); - SHComponentManager::CreateComponentSparseSet(); + //SHComponentManager::CreateComponentSparseSet(); //TODO: REMOVE AFTER PRESENTATION //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); @@ -119,9 +119,6 @@ namespace Sandbox //TODO: REMOVE AFTER PRESENTATION - auto id = SHFamilyID::GetID(); - auto id2 = SHFamilyID::GetID(); - auto id3 = SHFamilyID::GetID(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp new file mode 100644 index 00000000..8cd856e6 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -0,0 +1,67 @@ +#include "SHpch.h" +#include "SHCameraArmComponent.h" + + + +namespace SHADE +{ + + SHCameraArmComponent::SHCameraArmComponent() + :pitch(0.0f), yaw(0.0f), armLength(1.0f),rtMatrix(), dirty(true) + { + + } + + + SHMatrix const& SHCameraArmComponent::GetMatrix() const noexcept + { + return rtMatrix; + } + + float SHCameraArmComponent::GetPitch() const noexcept + { + return pitch; + } + + float SHCameraArmComponent::GetYaw() const noexcept + { + return yaw; + } + + float SHCameraArmComponent::GetArmLength() const noexcept + { + return armLength; + } + + void SHCameraArmComponent::SetPitch(float pitch) noexcept + { + this->pitch = pitch; + dirty = true; + } + + void SHCameraArmComponent::SetYaw(float yaw) noexcept + { + this->yaw = yaw; + dirty = true; + } + + void SHCameraArmComponent::SetArmLength(float length) noexcept + { + this->armLength = length; + dirty = true; + } + +}//namespace SHADE + + +RTTR_REGISTRATION +{ + using namespace SHADE; + using namespace rttr; + + registration::class_("Camera Arm Component") + .property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch) + .property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw) + .property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength); + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.h b/SHADE_Engine/src/Camera/SHCameraArmComponent.h new file mode 100644 index 00000000..8a189434 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -0,0 +1,43 @@ +#pragma once + + +#include +#include "ECS_Base/Components/SHComponent.h" +#include "Math/SHMatrix.h" +#include "SH_API.h" + +namespace SHADE +{ + class SH_API SHCameraArmComponent final: public SHComponent + { + private: + float pitch; + float yaw; + float armLength; + + bool dirty; + SHMatrix rtMatrix; + + public: + friend class SHCameraSystem; + SHCameraArmComponent(); + virtual ~SHCameraArmComponent() = default; + + + //Getters + SHMatrix const& GetMatrix() const noexcept; + float GetPitch() const noexcept; + float GetYaw() const noexcept; + float GetArmLength() const noexcept; + + //Setters + void SetPitch(float pitch) noexcept; + void SetYaw(float yaw) noexcept; + void SetArmLength(float length) noexcept; + + protected: + + + }; + +}//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index f5e08af4..846f4c2b 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -41,7 +41,7 @@ namespace SHADE friend class SHCameraSystem; SHCameraComponent(); - ~SHCameraComponent(); + virtual ~SHCameraComponent(); //Getters and setters. diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp index 559897c0..f1e98b71 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.cpp +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -1,6 +1,7 @@ #include "SHpch.h" #include "SHCameraDirector.h" #include "SHCameraComponent.h" +#include "SHCameraArmComponent.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Managers/SHEntityManager.h" @@ -48,6 +49,12 @@ namespace SHADE viewMatrix = camComponent->GetViewMatrix(); projMatrix = camComponent->GetProjMatrix(); } + SHCameraArmComponent* armComponent = SHComponentManager::GetComponent_s(mainCameraEID); + if (armComponent && camComponent) + { + SHMatrix tempView = armComponent->GetMatrix() * camComponent->GetViewMatrix(); + viewMatrix = tempView; + } } void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 609805f8..115d83bb 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -1,5 +1,6 @@ #include "SHpch.h" #include "SHCameraSystem.h" +#include "SHCameraArmComponent.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" #include "Math/Vector/SHVec2.h" @@ -121,6 +122,9 @@ namespace SHADE editorCamera.SetYaw(0.0f); editorCamera.SetRoll(0.0f); editorCamera.movementSpeed = 2.0f; + + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); } @@ -134,6 +138,19 @@ namespace SHADE return &editorCamera; } + void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept + { + if (pivot.dirty) + { + pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) + * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw())) + * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength())); + + pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); + } + } + + void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) @@ -241,6 +258,13 @@ namespace SHADE { SHCameraSystem* system = static_cast(GetSystem()); auto& dense = SHComponentManager::GetDense(); + auto& pivotDense = SHComponentManager::GetDense(); + + for (auto& pivot : pivotDense) + { + system->UpdatePivotArmComponent(pivot); + } + for (auto& cam : dense) { system->UpdateCameraComponent(cam); @@ -274,17 +298,17 @@ namespace SHADE } void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept { + constexpr float clampVal = 85.0f; - - if (camera.pitch > 85) - camera.SetPitch(85); - if (camera.pitch < -85) - camera.SetPitch(-85); - if (camera.roll > 85) - camera.SetRoll(85); - if (camera.roll < -85) - camera.SetRoll(-85); + if (camera.pitch > clampVal) + camera.SetPitch(clampVal); + if (camera.pitch < -clampVal) + camera.SetPitch(-clampVal); + if (camera.roll > clampVal) + camera.SetRoll(clampVal); + if (camera.roll < -clampVal) + camera.SetRoll(-clampVal); } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index 68071160..b15e27dd 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -9,6 +9,9 @@ namespace SHADE { + + class SHCameraArmComponent; + class SH_API SHCameraSystem final : public SHSystem { private: @@ -39,7 +42,7 @@ namespace SHADE class SH_API CameraSystemUpdate final: public SHSystemRoutine { public: - CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {}; + CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {}; virtual void Execute(double dt)noexcept override final; }; friend class CameraSystemUpdate; @@ -51,10 +54,11 @@ namespace SHADE DirectorHandle GetDirector(size_t index) noexcept; void ClampCameraRotation(SHCameraComponent& camera) noexcept; void UpdateEditorCamera(double dt) noexcept; + protected: void UpdateCameraComponent(SHCameraComponent& camera) noexcept; - + void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 42b516aa..301f5c6b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -21,6 +21,7 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" #include "Camera/SHCameraComponent.h" +#include "Camera/SHCameraArmComponent.h" namespace SHADE { @@ -103,6 +104,9 @@ namespace SHADE if (auto cameraComponent = SHComponentManager::GetComponent_s(eid)) { DrawComponent(cameraComponent); + }if (auto cameraArmComponent = SHComponentManager::GetComponent_s(eid)) + { + DrawComponent(cameraArmComponent); } ImGui::Separator(); // Render Scripts @@ -113,6 +117,7 @@ namespace SHADE { DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); // Components that require Transforms From e4394b617031558a24c7811ae7cc96cc669e7d95 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 28 Oct 2022 21:32:05 +0800 Subject: [PATCH 04/57] Generalised SHResourceManager --- Assets/Shaders/Kirsch_CS.shshaderb | Bin 5909 -> 5909 bytes Assets/Shaders/Kirsch_CS.shshaderb.shmeta | 2 +- Assets/Shaders/PureCopy_CS.shshaderb | Bin 1273 -> 1273 bytes Assets/Shaders/PureCopy_CS.shshaderb.shmeta | 2 +- Assets/Shaders/TestCube_FS.shshaderb | Bin 2309 -> 2309 bytes Assets/Shaders/TestCube_FS.shshaderb.shmeta | 2 +- Assets/Shaders/TestCube_VS.shshaderb | Bin 2501 -> 2501 bytes Assets/Shaders/TestCube_VS.shshaderb.shmeta | 2 +- .../src/Assets/Asset Types/SHShaderAsset.h | 11 +- .../Compilers/SHShaderSourceCompiler.cpp | 201 +++++++++--------- SHADE_Engine/src/Assets/SHAssetMacros.h | 9 +- SHADE_Engine/src/Resource/SHResourceManager.h | 36 ++++ .../src/Resource/SHResourceManager.hpp | 129 +++++------ 13 files changed, 221 insertions(+), 173 deletions(-) diff --git a/Assets/Shaders/Kirsch_CS.shshaderb b/Assets/Shaders/Kirsch_CS.shshaderb index 6219d9a9c9a9e8ae16a498e700cba315f72f58b8..4c54946c91f269b181aa2869965af1861c3cd8c5 100644 GIT binary patch delta 10 RcmbQLH&u^OVI!l6H~*vQDj2>=bU0sjC1 delta 10 RcmZn_Y87H++{nnn2>=ae0q_6- diff --git a/Assets/Shaders/TestCube_FS.shshaderb.shmeta b/Assets/Shaders/TestCube_FS.shshaderb.shmeta index 3a647313..42f270af 100644 --- a/Assets/Shaders/TestCube_FS.shshaderb.shmeta +++ b/Assets/Shaders/TestCube_FS.shshaderb.shmeta @@ -1,3 +1,3 @@ Name: TestCube_FS -ID: 18415057 +ID: 37450402 Type: 2 diff --git a/Assets/Shaders/TestCube_VS.shshaderb b/Assets/Shaders/TestCube_VS.shshaderb index 3d12507b9b6dac6ea9f270db7269266f4030a2b5..e070a9a6e4478efc121bc03a322dd966e0b786cd 100644 GIT binary patch delta 10 RcmX>qd{mf`aUqd{mf`VI$)aP5={f12F&q diff --git a/Assets/Shaders/TestCube_VS.shshaderb.shmeta b/Assets/Shaders/TestCube_VS.shshaderb.shmeta index 23c5e30d..b133437b 100644 --- a/Assets/Shaders/TestCube_VS.shshaderb.shmeta +++ b/Assets/Shaders/TestCube_VS.shshaderb.shmeta @@ -1,3 +1,3 @@ Name: TestCube_VS -ID: 29315909 +ID: 41688429 Type: 2 diff --git a/SHADE_Engine/src/Assets/Asset Types/SHShaderAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHShaderAsset.h index adcd215a..d71c1bb3 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHShaderAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHShaderAsset.h @@ -10,6 +10,7 @@ *****************************************************************************/ #pragma once +#include #include "SHAssetData.h" #include "SH_API.h" #include @@ -17,12 +18,14 @@ namespace SHADE { + //! Tighter control over types of shaders. Maps directly to their + //! equivalent vk::ShaderStageFlagBits. enum class SH_SHADER_TYPE : uint8_t { - VERTEX, - FRAGMENT, - COMPUTE, - INAVLID_TYPE + VERTEX = static_cast(vk::ShaderStageFlagBits::eVertex), + FRAGMENT = static_cast(vk::ShaderStageFlagBits::eFragment), + COMPUTE = static_cast(vk::ShaderStageFlagBits::eCompute), + INAVLID_TYPE = std::numeric_limits::max() }; struct SH_API SHShaderAsset : SHAssetData diff --git a/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp index 329e34e9..fd1f6d8a 100644 --- a/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Compilers/SHShaderSourceCompiler.cpp @@ -19,144 +19,145 @@ namespace SHADE { - std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept - { - std::string newPath{ path.string() }; + std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept + { + std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('.')); newPath += SHADER_BUILT_IN_EXTENSION.data(); - std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc }; + std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc }; - file.write( - reinterpret_cast(& data.shaderType), sizeof(uint8_t) - ); + file.write( + reinterpret_cast(& data.shaderType), sizeof(uint8_t) + ); - size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size(); + size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size(); - file.write( - reinterpret_cast(&byteCount), sizeof(size_t) - ); + file.write( + reinterpret_cast(&byteCount), sizeof(size_t) + ); - file.write( - reinterpret_cast(data.spirvBinary.data()), byteCount - ); + file.write( + reinterpret_cast(data.spirvBinary.data()), byteCount + ); - file.close(); + file.close(); - return newPath; - } + return newPath; + } - SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept - { - // shaderc compiler - shaderc::Compiler compiler; - shaderc::CompileOptions options; + SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept + { + // shaderc compiler + shaderc::Compiler compiler; + shaderc::CompileOptions options; - options.AddMacroDefinition("MY_DEFINE", "1"); + options.AddMacroDefinition("MY_DEFINE", "1"); - //TODO: Check if we need optimisation levels when compiling into spirv - // Set optimization levels - //if (opLevel != shaderc_optimization_level_zero) - // options.SetOptimizationLevel(opLevel); + //TODO: Check if we need optimisation levels when compiling into spirv + // Set optimization levels + //if (opLevel != shaderc_optimization_level_zero) + // options.SetOptimizationLevel(opLevel); - // Attempt to get the shaderc equivalent shader stage - shaderc_shader_kind shaderKind; - switch (type) - { - case SH_SHADER_TYPE::VERTEX: - shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader; - break; - case SH_SHADER_TYPE::FRAGMENT: - shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader; - break; - case SH_SHADER_TYPE::COMPUTE: - shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader; - break; - default: - shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader; - break; - } + // Attempt to get the shaderc equivalent shader stage + shaderc_shader_kind shaderKind; + switch (type) + { + case SH_SHADER_TYPE::VERTEX: + shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader; + break; + case SH_SHADER_TYPE::FRAGMENT: + shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader; + break; + case SH_SHADER_TYPE::COMPUTE: + shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader; + break; + default: + shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader; + break; + } - // Compile the shader and get the result - shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options); + // Compile the shader and get the result + shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options); - if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success) - { - SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage()); - return nullptr; - } + if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success) + { + SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage()); + return nullptr; + } - auto result = new SHShaderAsset(); - result->spirvBinary.resize(compileResult.end() - compileResult.begin()); + auto result = new SHShaderAsset(); + result->spirvBinary.resize(compileResult.end() - compileResult.begin()); - std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data()); + std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data()); result->name = name; result->shaderType = type; - return result; - } + return result; + } - SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept - { - for (auto i { 0}; i < SHADER_TYPE_MAX_COUNT; ++i) - { - if (name.find(SHADER_IDENTIFIERS[i].data()) != std::string::npos) - { - return static_cast(i); - } - } + SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept + { + for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i) + { + const auto& [SHADER_SUFFIX, SHADER_TYPE] = SHADER_IDENTIFIERS[i]; + if (name.find(SHADER_SUFFIX.data()) != std::string::npos) + { + return SHADER_TYPE; + } + } - return SH_SHADER_TYPE::INAVLID_TYPE; - } + return SH_SHADER_TYPE::INAVLID_TYPE; + } std::optional SHShaderSourceCompiler::LoadAndCompileShader(AssetPath path) noexcept - { - auto type = GetShaderTypeFromFilename(path.filename().string()); + { + auto type = GetShaderTypeFromFilename(path.filename().string()); - if (type == SH_SHADER_TYPE::INAVLID_TYPE) - { - SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string()); - return {}; - } + if (type == SH_SHADER_TYPE::INAVLID_TYPE) + { + SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string()); + return {}; + } path.make_preferred(); - std::ifstream file{ path.string(), std::ios::in }; + std::ifstream file{ path.string(), std::ios::in }; - if (file.is_open()) - { - std::stringstream stream; + if (file.is_open()) + { + std::stringstream stream; - stream << file.rdbuf(); + stream << file.rdbuf(); - std::string const content = stream.str(); + std::string const content = stream.str(); - auto data = CompileShaderSourceToMemory(content, path.filename().string(), type); + auto data = CompileShaderSourceToMemory(content, path.filename().string(), type); - if (data == nullptr) - { - return{}; - } + if (data == nullptr) + { + return{}; + } - return CompileShaderSourceToBinary(path, *data); - } + return CompileShaderSourceToBinary(path, *data); + } - SHLOG_ERROR("Unable to open shader file: {}", path.string()); + SHLOG_ERROR("Unable to open shader file: {}", path.string()); - return {}; - } + return {}; + } - std::optional SHShaderSourceCompiler::CompileShaderFromString - (std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept - { - auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type); + std::optional SHShaderSourceCompiler::CompileShaderFromString + (std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept + { + auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type); - if (data == nullptr) - { - return{}; - } + if (data == nullptr) + { + return{}; + } - return CompileShaderSourceToBinary(path, *data); - } + return CompileShaderSourceToBinary(path, *data); + } } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 1df4e30b..633bfc4d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -13,6 +13,7 @@ #include #include #include +#include "Asset Types/SHShaderAsset.h" // FMOD Fwd Declare namespace FMOD @@ -103,10 +104,10 @@ constexpr std::string_view VERTEX_SHADER{ "_VS" }; constexpr std::string_view FRAGMENT_SHADER{ "_FS" }; constexpr std::string_view COMPUTER_SHADER{ "_CS" }; -constexpr std::string_view SHADER_IDENTIFIERS[] = { - VERTEX_SHADER, - FRAGMENT_SHADER, - COMPUTER_SHADER +constexpr std::pair SHADER_IDENTIFIERS[] = { + std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX), + std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT), + std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE) }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 84f93b10..cd014da8 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -17,9 +17,37 @@ of DigiPen Institute of Technology is prohibited. #include "SH_API.h" #include "SHResourceLibrary.h" #include "Assets/SHAssetMacros.h" +#include "Assets/Asset Types/SHMeshAsset.h" +#include "Assets/Asset Types/SHTextureAsset.h" +#include "Assets/Asset Types/SHShaderAsset.h" +#include "Graphics/Shaders/SHVkShaderModule.h" +#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" +#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" namespace SHADE { + template + struct SHResourceLoader + { + using AssetType = void; + }; + + template<> + struct SHResourceLoader + { + using AssetType = SHMeshAsset; + }; + template<> + struct SHResourceLoader + { + using AssetType = SHTextureAsset; + }; + template<> + struct SHResourceLoader + { + using AssetType = SHShaderAsset; + }; + /// /// Static class responsible for loading and caching runtime resources from their /// serialised Asset IDs. @@ -124,6 +152,14 @@ namespace SHADE /// Reference to the AssetHandleMap of the specified type. template static std::pair getAssetHandleMap(); + /// + /// + /// + /// + /// + /// + template + static Handle load(AssetID assetId, const typename SHResourceLoader::AssetType& assetData); }; } diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 072adaa2..f6c485d3 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -3,7 +3,7 @@ \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Oct 21, 2022 -\brief Contains the definition of the function templates of the +\brief Contains the definition of the function templates of the SHResourceManager static class. Copyright (C) 2022 DigiPen Institute of Technology. @@ -19,6 +19,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Tools/SHLog.h" +#include "Graphics/Shaders/SHVkShaderModule.h" namespace SHADE { @@ -40,67 +41,19 @@ namespace SHADE return Handle(typedHandleMap.get()[assetId]); /* Otherwise, we need to load it! */ - // Meshes - if constexpr (std::is_same_v) + // Load Asset Data + const auto* assetData = SHAssetManager::GetData::AssetType>(assetId); + if (assetData == nullptr) { - // Get system - SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem == nullptr) - throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); - - // Load - const SHMeshAsset* assetData = SHAssetManager::GetData(assetId); - if (assetData == nullptr) - { - SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); - return {}; - } - loadedAssetData.emplace_back(assetId); - - Handle meshHandle = gfxSystem->AddMesh - ( - assetData->vertexPosition.size(), - assetData->vertexPosition.data(), - assetData->texCoords.data(), - assetData->vertexTangent.data(), - assetData->vertexNormal.data(), - assetData->indices.size(), - assetData->indices.data() - ); - Handle genericHandle = Handle(meshHandle); - typedHandleMap.get().emplace(assetId, genericHandle); - typedAssetIdMap.get().emplace(genericHandle, assetId); - return meshHandle; + SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); + return {}; } - // Textures - else if constexpr (std::is_same_v) - { - // Get system - SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem == nullptr) - throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); - // Load - const SHTextureAsset* assetData = SHAssetManager::GetData(assetId); - if (assetData == nullptr) - { - SHLog::Warning("[SHResourceManager] Attempted to load an asset with an invalid Asset ID."); - return {}; - } - loadedAssetData.emplace_back(assetId); - - Handle texHandle = gfxSystem->AddTexture - ( - assetData->numBytes, - assetData->pixelData, - assetData->width, - assetData->height, - assetData->format, - assetData->mipOffsets - ); - typedHandleMap.get().emplace(assetId, Handle(texHandle)); - return texHandle; - } + auto handle = load(assetId, *assetData); + Handle genericHandle = Handle(); + typedHandleMap.get().emplace(assetId, genericHandle); + typedAssetIdMap.get().emplace(genericHandle, assetId); + return handle; } template @@ -152,7 +105,7 @@ namespace SHADE template std::pair SHResourceManager::getAssetHandleMap() { - const std::type_index TYPE = typeid(ResourceType); + const std::type_index TYPE = typeid(ResourceType); if (!handlesMap.contains(TYPE)) { @@ -160,7 +113,7 @@ namespace SHADE assetIdMap.emplace(TYPE, HandleAssetMap{}); typedFreeFuncMap.emplace ( - TYPE, + TYPE, [TYPE](AssetID assetId) { static_cast>(SHResourceManager::handlesMap[TYPE][assetId]).Free(); @@ -169,4 +122,58 @@ namespace SHADE } return std::make_pair(std::ref(handlesMap[TYPE]), std::ref(assetIdMap[TYPE])); } + + template + Handle SHResourceManager::load(AssetID assetId, const typename SHResourceLoader::AssetType& assetData) + { + // Get system + SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem == nullptr) + throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); + + // Meshes + if constexpr (std::is_same_v) + { + loadedAssetData.emplace_back(assetId); + + return gfxSystem->AddMesh + ( + assetData.vertexPosition.size(), + assetData.vertexPosition.data(), + assetData.texCoords.data(), + assetData.vertexTangent.data(), + assetData.vertexNormal.data(), + assetData.indices.size(), + assetData.indices.data() + ); + } + // Textures + else if constexpr (std::is_same_v) + { + loadedAssetData.emplace_back(assetId); + + return gfxSystem->AddTexture + ( + assetData.numBytes, + assetData.pixelData, + assetData.width, + assetData.height, + assetData.format, + assetData.mipOffsets + ); + } + // Shaders + else if constexpr (std::is_same_v) + { + return gfxSystem->GetDevice()->CreateShaderModule + ( + assetData.spirvBinary, + "main", + static_cast(assetData.shaderType), + assetData.name + ); + } + // Materials + + } } From 3c2e51cb0baf2ad5e11cf88ecbfe9aa26d41fb0c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 29 Oct 2022 01:38:29 +0800 Subject: [PATCH 05/57] Built-in shaders are now fully loaded via the SHResourceManager --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 17 +-- .../MiddleEnd/Interface/SHGraphicsSystem.h | 11 +- .../Shaders/SHShaderModuleLibrary.cpp | 139 ------------------ .../MiddleEnd/Shaders/SHShaderModuleLibrary.h | 44 ------ .../src/Resource/SHResourceManager.hpp | 4 +- 5 files changed, 18 insertions(+), 197 deletions(-) delete mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.cpp delete mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 3330a189..ad63f0ec 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -37,6 +37,8 @@ of DigiPen Institute of Technology is prohibited. #include "Assets/Asset Types/SHTextureAsset.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" #include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h" +#include "Assets/SHAssetManager.h" +#include "Resource/SHResourceManager.h" namespace SHADE { @@ -117,9 +119,10 @@ namespace SHADE transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - - shaderModuleLibrary.ImportAllShaderSource(device); - shaderModuleLibrary.ReflectAllShaderModules(); + // Load Built In Shaders + static constexpr AssetID VS_DEFAULT = 41688429; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); + static constexpr AssetID FS_DEFAULT = 37450402; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); + static constexpr AssetID CS_PURE_COPY = 34987209; copyComputeShader = SHResourceManager::LoadOrGet(CS_PURE_COPY); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -178,8 +181,7 @@ namespace SHADE //gBufferNode->AddNodeCompute(kirschShader, { "Scene Pre-Process", "Scene" }); // copy - auto pureCopyShader = shaderModuleLibrary.GetBuiltInShaderModule("PureCopy_CS"); - gBufferNode->AddNodeCompute(pureCopyShader, { "Scene Pre-Process", "Scene" }); + gBufferNode->AddNodeCompute(copyComputeShader, { "Scene Pre-Process", "Scene" }); auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors @@ -196,10 +198,7 @@ namespace SHADE worldRenderer->SetCameraDirector(cameraSystem->CreateDirector()); - auto cubeVS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_VS"); - auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS"); - - defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass); + defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass); } void SHGraphicsSystem::InitMiddleEnd(void) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index f657965c..72b661ee 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -25,7 +25,6 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/System/SHSystemRoutine.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Graphics/RenderGraph/SHRenderGraph.h" -#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h" #include "SHMeshLibrary.h" #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" #include "../Textures/SHTextureLibrary.h" @@ -325,6 +324,7 @@ namespace SHADE SHTextureLibrary texLibrary; SHSamplerCache samplerCache; SHMaterialInstanceCache materialInstanceCache; + // Viewports #ifdef SHEDITOR Handle editorViewport; @@ -345,10 +345,13 @@ namespace SHADE // Temp Cameras Handle worldCamera; Handle screenCamera; - - SHShaderModuleLibrary shaderModuleLibrary; - // Temp Materials + // Built-In Shaders + Handle defaultVertShader; + Handle defaultFragShader; + Handle copyComputeShader; + + // Built-In Materials Handle defaultMaterial; Handle worldRenderGraph; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.cpp deleted file mode 100644 index d0b160df..00000000 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "SHPch.h" -#include "SHShaderModuleLibrary.h" -#include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Assets/SHAssetManager.h" - -namespace SHADE -{ - /***************************************************************************/ - /*! - - \brief - Imports all shader binaries from the source library. - - \param logicalDeviceHdl - For creating shader modules. - - \param sourceLib - The source library class that stores the container of shader binary data. - - */ - /***************************************************************************/ - //void SHShaderModuleLibrary::ImportFromSourceLibrary(Handle& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept - //{ - // auto const& sources = sourceLib.GetSourceLibrary(); - // for (auto const& source : sources) - // { - // vk::ShaderStageFlagBits shaderType{}; - // switch (source.shaderType) - // { - // case SH_SHADER_TYPE::VERTEX: - // shaderType = vk::ShaderStageFlagBits::eVertex; - // break; - // case SH_SHADER_TYPE::FRAGMENT: - // shaderType = vk::ShaderStageFlagBits::eFragment; - // break; - // case SH_SHADER_TYPE::COMPUTE: - // shaderType = vk::ShaderStageFlagBits::eCompute; - // break; - // default: - // shaderType = vk::ShaderStageFlagBits::eVertex; - // break; - // } - - // Handle newShaderModule = logicalDeviceHdl->CreateShaderModule(source.spirvBinary, "main", shaderType, source.name); - // shaderModules.emplace(source.id, newShaderModule); - // stringToID.emplace(source.name, source.id); - // } - //} - - /***************************************************************************/ - /*! - - \brief - Gets the shader module based on module name. - - \param shaderName - - \return - - */ - /***************************************************************************/ - //Handle SHShaderModuleLibrary::GetShaderModule(std::string shaderName) const noexcept - //{ - // if (stringToID.contains(shaderName)) - // return shaderModules.at(stringToID.at(shaderName)); - // else - // return {}; - //} - - vk::ShaderStageFlagBits SHShaderModuleLibrary::GetVkShaderFlag(SH_SHADER_TYPE type) noexcept - { - vk::ShaderStageFlagBits shaderType{}; - switch (type) - { - case SH_SHADER_TYPE::VERTEX: - shaderType = vk::ShaderStageFlagBits::eVertex; - break; - case SH_SHADER_TYPE::FRAGMENT: - shaderType = vk::ShaderStageFlagBits::eFragment; - break; - case SH_SHADER_TYPE::COMPUTE: - shaderType = vk::ShaderStageFlagBits::eCompute; - break; - default: - shaderType = vk::ShaderStageFlagBits::eVertex; - break; - } - - return shaderType; - } - - Handle SHShaderModuleLibrary::GetBuiltInShaderModule(std::string shaderName) const noexcept - { - if (builtInShaderModules.contains(shaderName)) - return builtInShaderModules.at(shaderName); - else - return {}; - } - - void SHShaderModuleLibrary::ImportAllShaderSource(Handle& logicalDeviceHdl) noexcept - { - uint32_t idCounter{ 0 }; - - auto const data = SHAssetManager::GetAllDataOfType(AssetType::SHADER); - for (auto const& dataPtr : data) - { - auto const shader = dynamic_cast(dataPtr); - - Handle newShaderModule = - logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name); - - shaderModules.emplace(idCounter++, newShaderModule); - } - - auto const builtIn = SHAssetManager::GetAllDataOfType(AssetType::SHADER_BUILT_IN); - for (auto const& dataPtr : builtIn) - { - auto const shader = dynamic_cast(dataPtr); - - Handle newShaderModule = - logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name); - - builtInShaderModules.emplace(shader->name, newShaderModule); - } - } - - void SHShaderModuleLibrary::ReflectAllShaderModules() noexcept - { - for (auto& module : shaderModules) - { - module.second->Reflect(); - } - - for (auto& module : builtInShaderModules) - { - module.second->Reflect(); - } - } -} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h deleted file mode 100644 index 9daae816..00000000 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef SH_SHADER_MODULE_LIBRARY_H -#define SH_SHADER_MODULE_LIBRARY_H - -#include "Graphics/Shaders/SHVkShaderModule.h" -#include "Assets/Asset Types/SHShaderAsset.h" - -namespace SHADE -{ - class SHVkLogicalDevice; - - /* - * The purpose of this shader module library is to be separate from the source library. The source library contains - * pure shader binary data that contains no vulkan related objects. Every time we load on unload a scene/level, - * this class and the source library class is cleared of its modules and recreated. - */ - class SHShaderModuleLibrary - { - private: - /*-----------------------------------------------------------------------*/ - /* PRIVATE MEMBER VARIABLES */ - /*-----------------------------------------------------------------------*/ - //! Stored shader modules - std::unordered_map> shaderModules; - std::unordered_map> builtInShaderModules; - - inline vk::ShaderStageFlagBits GetVkShaderFlag(SH_SHADER_TYPE type) noexcept; - - public: - /*-----------------------------------------------------------------------*/ - /* PUBLIC MEMBER FUNCTIONS */ - /*-----------------------------------------------------------------------*/ - //void ImportFromSourceLibrary(Handle& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept; - - /*-----------------------------------------------------------------------*/ - /* SETTERS AND GETTERS */ - /*-----------------------------------------------------------------------*/ - Handle GetBuiltInShaderModule(std::string shaderName) const noexcept; - - void ImportAllShaderSource(Handle& logicalDeviceHdl) noexcept; - void ReflectAllShaderModules() noexcept; - }; -} - -#endif \ No newline at end of file diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index f6c485d3..4c924151 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -165,13 +165,15 @@ namespace SHADE // Shaders else if constexpr (std::is_same_v) { - return gfxSystem->GetDevice()->CreateShaderModule + auto shader = gfxSystem->GetDevice()->CreateShaderModule ( assetData.spirvBinary, "main", static_cast(assetData.shaderType), assetData.name ); + shader->Reflect(); + return shader; } // Materials From 15e9aaa57d0bd0f3a29b19f44a8706d4aef5df9a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 29 Oct 2022 01:54:43 +0800 Subject: [PATCH 06/57] Modified SHSerialization to load Material using SHResourceManager --- SHADE_Engine/src/Resource/SHResourceManager.hpp | 4 ++++ .../src/Serialization/SHSerializationHelper.hpp | 15 +++------------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 4c924151..badb301f 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -20,6 +20,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/Managers/SHSystemManager.h" #include "Tools/SHLog.h" #include "Graphics/Shaders/SHVkShaderModule.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" namespace SHADE { @@ -176,6 +177,9 @@ namespace SHADE return shader; } // Materials + else if constexpr (std::is_same_v) + { + } } } diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index a8e46d88..856aaadf 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -77,16 +77,15 @@ namespace YAML // Write Material YAML::Node node; - node[VERT_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID(vertexShader).value_or(0); - node[FRAG_SHADER_YAML_TAG.data()] = 0; // SHResourceManager::GetAssetID(fragShader).value_or(0); - node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName(); + node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID(vertexShader).value_or(0); + node[FRAG_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID(fragShader).value_or(0); + node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName(); node[PROPS_YAML_TAG.data()] = propertiesNode; return node; } static bool decode(YAML::Node const& node, SHMaterial& rhs) { - /* // Retrieve Shader Asset IDs AssetID vertShaderId = 0; AssetID fragShaderId = 0; @@ -126,14 +125,6 @@ namespace YAML subPass )); } - */ - - // TODO: Load Proper Material! - // Set default material - auto gfxSystem = SHSystemManager::GetSystem(); - if (!gfxSystem) - return false; - rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline()); if (node[PROPS_YAML_TAG.data()]) { From 72cdbf55e502dacade403a43e328d884e2f70417 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sat, 29 Oct 2022 16:42:02 +0800 Subject: [PATCH 07/57] Fixed boolean for updating entities in Transform system --- SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index a2ab6880..60dc6675 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -47,16 +47,14 @@ namespace SHADE { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - - // TODO(Diren): Consider how to clear dirty in pause / stop mode and update physics, but do not clear in play mode. - UpdateEntity(SCENE_GRAPH.GetRoot(), false); + UpdateEntity(SCENE_GRAPH.GetRoot(), !IsRunInEditorPause); } void SHTransformSystem::TransformPostPhysicsUpdate::Execute(double) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - UpdateEntity(SCENE_GRAPH.GetRoot(), true); + UpdateEntity(SCENE_GRAPH.GetRoot(), IsRunInEditorPause); } void SHTransformSystem::Init() From cac93b7df962ee9325cac114fadd763aac902ea0 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 29 Oct 2022 23:56:37 +0800 Subject: [PATCH 08/57] Fixed indentation issue in SHGraphicsSystem --- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index ad63f0ec..484cca3f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -120,8 +120,8 @@ namespace SHADE graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // Load Built In Shaders - static constexpr AssetID VS_DEFAULT = 41688429; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); - static constexpr AssetID FS_DEFAULT = 37450402; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); + static constexpr AssetID VS_DEFAULT = 41688429; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); + static constexpr AssetID FS_DEFAULT = 37450402; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); static constexpr AssetID CS_PURE_COPY = 34987209; copyComputeShader = SHResourceManager::LoadOrGet(CS_PURE_COPY); } From 5eaf2b55aaa0df47c7d76e8a48ccf408f23d776d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 12:20:46 +0800 Subject: [PATCH 09/57] Added WIP Application class and adjustments to how ScriptStore destroys scripts (SpdLog errors) --- .../MiddleEnd/Interface/SHGraphicsSystem.h | 6 +- .../src/Graphics/Windowing/SHWindow.cpp | 2 +- .../src/Graphics/Windowing/SHWindow.h | 2 +- SHADE_Managed/src/Engine/Application.cxx | 100 ++++++++++++++++++ SHADE_Managed/src/Engine/Application.hxx | 77 ++++++++++++++ SHADE_Managed/src/Scripts/ScriptStore.cxx | 10 +- 6 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 SHADE_Managed/src/Engine/Application.cxx create mode 100644 SHADE_Managed/src/Engine/Application.hxx diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 0f9d602a..c5908db4 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -293,6 +293,10 @@ namespace SHADE //Handle GetRenderPass() const { return renderPass; } + /*-----------------------------------------------------------------------------*/ + /* Getters */ + /*-----------------------------------------------------------------------------*/ + SHWindow* GetWindow() noexcept { return window; } private: /*-----------------------------------------------------------------------------*/ @@ -320,7 +324,7 @@ namespace SHADE SHWindow* window = nullptr; // Middle End Resources - SHResourceHub resourceManager; + SHResourceHub resourceManager; SHMeshLibrary meshLibrary; SHTextureLibrary texLibrary; SHSamplerCache samplerCache; diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp index 7995e394..e0dbc1a4 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.cpp @@ -260,7 +260,7 @@ namespace SHADE return wndHWND; } - const WindowData SHWindow::GetWindowData() + const WindowData SHWindow::GetWindowData() const { return wndData; } diff --git a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h index 8595ce4b..11308d90 100644 --- a/SHADE_Engine/src/Graphics/Windowing/SHWindow.h +++ b/SHADE_Engine/src/Graphics/Windowing/SHWindow.h @@ -123,7 +123,7 @@ namespace SHADE HWND GetHWND(); - const WindowData GetWindowData(); + const WindowData GetWindowData() const; CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn); void UnregisterWindowSizeCallback(CALLBACKID const& callbackid); diff --git a/SHADE_Managed/src/Engine/Application.cxx b/SHADE_Managed/src/Engine/Application.cxx new file mode 100644 index 00000000..c4bce19f --- /dev/null +++ b/SHADE_Managed/src/Engine/Application.cxx @@ -0,0 +1,100 @@ +/************************************************************************************//*! +\file Application.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definitions of the functions in the static managed + Application class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Application.hxx" +// External Dependencies +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Graphics/Windowing/SHWindow.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + bool Application::IsPlaying::get() + { + auto editor = SHSystemManager::GetSystem(); + if (editor) + return editor->editorState == SHEditor::State::PLAY + || + editor->editorState == SHEditor::State::PAUSE; + + return true; + } + bool Application::IsPaused::get() + { + auto editor = SHSystemManager::GetSystem(); + if (editor) + return editor->editorState == SHEditor::State::PAUSE; + + return false; + } + int Application::WindowWidth::get() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowSize().first; + } + + throw gcnew System::InvalidOperationException("Unable to get current window width!"); + } + int Application::WindowHeight::get() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowSize().second; + } + + throw gcnew System::InvalidOperationException("Unable to get current window height!"); + } + bool Application::IsFullscreen::get() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowData().isFullscreen; + } + + throw gcnew System::InvalidOperationException("Unable to get current window height!"); + } + /*void Application::IsFullscreen::set(bool value) + { + return Pls::Window::SetFullScreen(value); + }*/ + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void Application::Quit() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + auto WND = gfxSystem->GetWindow(); + return WND->Close(); + } + + throw gcnew System::InvalidOperationException("Unable to quit!"); + } +} diff --git a/SHADE_Managed/src/Engine/Application.hxx b/SHADE_Managed/src/Engine/Application.hxx new file mode 100644 index 00000000..8629cf75 --- /dev/null +++ b/SHADE_Managed/src/Engine/Application.hxx @@ -0,0 +1,77 @@ +/************************************************************************************//*! +\file Application.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definitions of a managed static Application class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +namespace SHADE +{ + /// + /// Static class that contains useful properties for querying the state of the + /// engine. + /// + public ref class Application abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Whether or not the engine is playing. This will always be true on Publish. + /// On Debug/Release builds, this is true when the editor is in Play Mode. It + /// will also be true even if the editor is in Play Mode but is paused. + /// + static property bool IsPlaying + { + bool get(); + } + /// + /// Whether or not the engine is in a paused state where script updates and + /// physics are not in play. + /// + static property bool IsPaused + { + bool get(); + } + /// + /// Retrieves the designated width of the current window. + /// + static property int WindowWidth + { + int get(); + } + /// + /// Retrieves the designated height of the current window. + /// + static property int WindowHeight + { + int get(); + } + /// + /// Whether or not the application is currently in fullscreen mode or not. + /// + static property bool IsFullscreen + { + bool get(); + // TODO: once implemented on SHADE_Engine + //void set(bool value); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Marks the application to stop at the end of the current frame. + /// + static void Quit(); + }; +} diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index b6bc1815..1c732358 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -27,6 +27,7 @@ of DigiPen Institute of Technology is prohibited. #include "Script.hxx" #include "Engine/Entity.hxx" #include "Serialisation/ReflectionUtilities.hxx" +#include "Engine/Application.hxx" namespace SHADE { @@ -372,8 +373,11 @@ namespace SHADE // Clear the queue while (disposalQueue.Count > 0) { - Script^ script = disposalQueue.Dequeue(); - script->OnDestroy(); + Script^ script = disposalQueue.Dequeue(); + if (Application::IsPlaying) + { + script->OnDestroy(); + } auto entity = script->Owner.GetEntity(); auto scriptList = scripts[script->Owner.GetEntity()]; scriptList->Remove(script); @@ -388,7 +392,7 @@ namespace SHADE { SAFE_NATIVE_CALL_BEGIN // Run the deinit all scripts if needed - //if (Application::IsPlaying) + if (Application::IsPlaying) { Debug::Log("Running OnDestroy() for scripts."); for each (System::Collections::Generic::KeyValuePair entity in scripts) From 66529474cd8af126de5f08c4ec3afd4bed52ef79 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 14:51:50 +0800 Subject: [PATCH 10/57] Added Application class equivalent to SHADE_Managed --- SHADE_Engine/src/Editor/SHEditor.h | 4 +- .../Interface/SHGraphicsSystemInterface.cpp | 77 +++++++++++++++++++ .../Interface/SHGraphicsSystemInterface.h | 52 +++++++++++++ SHADE_Engine/src/Tools/SHLog.h | 2 +- SHADE_Managed/premake5.lua | 10 ++- SHADE_Managed/src/Engine/Application.cxx | 41 ++-------- 6 files changed, 147 insertions(+), 39 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.h diff --git a/SHADE_Engine/src/Editor/SHEditor.h b/SHADE_Engine/src/Editor/SHEditor.h index 34405390..624069db 100644 --- a/SHADE_Engine/src/Editor/SHEditor.h +++ b/SHADE_Engine/src/Editor/SHEditor.h @@ -15,7 +15,7 @@ #include "ECS_Base/System/SHSystemRoutine.h" #include "Resource/SHHandle.h" #include "EditorWindow/SHEditorWindow.h" -#include "Tools/SHLogger.h" +#include "Tools/SHLog.h" #include "Gizmos/SHTransformGizmo.h" @@ -76,7 +76,7 @@ namespace SHADE } else { - SHLOG_WARNING("Attempt to create duplicate of Editor window type") + SHLog::Warning("Attempt to create duplicate of Editor window type"); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.cpp new file mode 100644 index 00000000..1ad46e04 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.cpp @@ -0,0 +1,77 @@ +/************************************************************************************//*! +\file SHGraphicsSystemInterface.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definitions of the functions of the static + SHGraphicsSystemInterface class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "SHGraphicsSystemInterface.h" +// Project Includes +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Graphics/Windowing/SHWindow.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + uint32_t SHGraphicsSystemInterface::GetWindowWidth() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowSize().first; + } + + SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window width. Value of 0 returned instead."); + return 0; + } + + uint32_t SHGraphicsSystemInterface::GetWindowHeight() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowSize().second; + } + + SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window height. Value of 0 returned instead."); + return 0; + } + + bool SHGraphicsSystemInterface::IsFullscreen() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + const auto WND = gfxSystem->GetWindow(); + return WND->GetWindowData().isFullscreen; + } + + SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window fullscreen status. Value of false returned instead."); + return false; + } + + void SHGraphicsSystemInterface::CloseWindow() + { + auto gfxSystem = SHSystemManager::GetSystem(); + if (gfxSystem) + { + auto WND = gfxSystem->GetWindow(); + return WND->Close(); + } + + SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to close window."); + } +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.h new file mode 100644 index 00000000..5bc77ed9 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.h @@ -0,0 +1,52 @@ +/************************************************************************************//*! +\file SHGraphicsSystemInterface.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definition of the SHGraphicsSystemInterface static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +namespace SHADE +{ + /// + /// Static class that wraps up certain functions in the SHGraphicsSystem so that + /// accessing it from SHADE_Managed would not cause issues due to C++20 features. + /// + class SH_API SHGraphicsSystemInterface final + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructor */ + /*---------------------------------------------------------------------------------*/ + SHGraphicsSystemInterface() = delete; + + /*---------------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Retrieves the current window width. + /// + /// The current window width. + static uint32_t GetWindowWidth(); + /// + /// Retrieves the current window height. + /// + /// The current window height. + static uint32_t GetWindowHeight(); + /// + /// Retrieves the current window fullscreen status. + /// + /// The current window fullscreen status.. + static bool IsFullscreen(); + /// + /// Closes the current window, and depending on the implementation, should also + /// close the application. + /// + static void CloseWindow(); + }; +} diff --git a/SHADE_Engine/src/Tools/SHLog.h b/SHADE_Engine/src/Tools/SHLog.h index 89dd9206..91117da6 100644 --- a/SHADE_Engine/src/Tools/SHLog.h +++ b/SHADE_Engine/src/Tools/SHLog.h @@ -9,7 +9,7 @@ Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ - +#pragma once // Standard Library #include // Project Headers diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index 906511c1..b383f002 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -25,11 +25,16 @@ project "SHADE_Managed" includedirs { "%{prj.location}/src", + } + + externalincludedirs + { "%{IncludeDir.spdlog}/include", "%{IncludeDir.imgui}", "%{IncludeDir.imguizmo}", "%{IncludeDir.imnodes}", "%{IncludeDir.yamlcpp}", + "%{IncludeDir.SDL}\\include", "%{IncludeDir.RTTR}/include", "%{IncludeDir.dotnet}\\include", "%{IncludeDir.reactphysics3d}\\include", @@ -38,13 +43,16 @@ project "SHADE_Managed" libdirs { - "%{IncludeDir.RTTR}/lib" + "%{IncludeDir.RTTR}/lib", + "%{IncludeDir.SDL}/lib" } links { "yaml-cpp", "imgui", + "SDL2.lib", + "SDL2main.lib", "SHADE_Engine", "SHADE_CSharp" } diff --git a/SHADE_Managed/src/Engine/Application.cxx b/SHADE_Managed/src/Engine/Application.cxx index c4bce19f..c19bafa6 100644 --- a/SHADE_Managed/src/Engine/Application.cxx +++ b/SHADE_Managed/src/Engine/Application.cxx @@ -19,8 +19,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" -#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" -#include "Graphics/Windowing/SHWindow.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystemInterface.h" namespace SHADE { @@ -47,40 +46,19 @@ namespace SHADE } int Application::WindowWidth::get() { - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - const auto WND = gfxSystem->GetWindow(); - return WND->GetWindowSize().first; - } - - throw gcnew System::InvalidOperationException("Unable to get current window width!"); + return SHGraphicsSystemInterface::GetWindowWidth(); } int Application::WindowHeight::get() { - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - const auto WND = gfxSystem->GetWindow(); - return WND->GetWindowSize().second; - } - - throw gcnew System::InvalidOperationException("Unable to get current window height!"); + return SHGraphicsSystemInterface::GetWindowWidth(); } bool Application::IsFullscreen::get() { - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - const auto WND = gfxSystem->GetWindow(); - return WND->GetWindowData().isFullscreen; - } - - throw gcnew System::InvalidOperationException("Unable to get current window height!"); + return SHGraphicsSystemInterface::IsFullscreen(); } /*void Application::IsFullscreen::set(bool value) { - return Pls::Window::SetFullScreen(value); + return SHGraphicsSystemInterface::SetFullscreen(value); }*/ /*---------------------------------------------------------------------------------*/ @@ -88,13 +66,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void Application::Quit() { - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - auto WND = gfxSystem->GetWindow(); - return WND->Close(); - } - - throw gcnew System::InvalidOperationException("Unable to quit!"); + SHGraphicsSystemInterface::CloseWindow(); } } From ab46d0a96abcdab19a6ca08eb3f90160614d5c2f Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 15:02:28 +0800 Subject: [PATCH 11/57] Decompose matrix WIP --- .../src/Camera/SHCameraArmComponent.cpp | 6 +- .../src/Camera/SHCameraArmComponent.h | 5 +- SHADE_Engine/src/Camera/SHCameraComponent.cpp | 2 +- SHADE_Engine/src/Camera/SHCameraComponent.h | 2 +- SHADE_Engine/src/Camera/SHCameraDirector.cpp | 7 +- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 80 +++++++++++++++++-- SHADE_Engine/src/Camera/SHCameraSystem.h | 2 + 7 files changed, 84 insertions(+), 20 deletions(-) diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp index 8cd856e6..3b4351fa 100644 --- a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -7,15 +7,15 @@ namespace SHADE { SHCameraArmComponent::SHCameraArmComponent() - :pitch(0.0f), yaw(0.0f), armLength(1.0f),rtMatrix(), dirty(true) + :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true) { } - SHMatrix const& SHCameraArmComponent::GetMatrix() const noexcept + SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept { - return rtMatrix; + return offset; } float SHCameraArmComponent::GetPitch() const noexcept diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.h b/SHADE_Engine/src/Camera/SHCameraArmComponent.h index 8a189434..e3636b70 100644 --- a/SHADE_Engine/src/Camera/SHCameraArmComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -16,7 +16,7 @@ namespace SHADE float armLength; bool dirty; - SHMatrix rtMatrix; + SHVec3 offset; public: friend class SHCameraSystem; @@ -25,7 +25,8 @@ namespace SHADE //Getters - SHMatrix const& GetMatrix() const noexcept; + //SHMatrix const& GetMatrix() const noexcept; + SHVec3 const& GetOffset() const noexcept; float GetPitch() const noexcept; float GetYaw() const noexcept; float GetArmLength() const noexcept; diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 31afe2ac..ac451df5 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -13,7 +13,7 @@ namespace SHADE , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , perspProj(true), dirtyView(true), dirtyProj(true) , viewMatrix(), projMatrix() - , position() + , position(), offset() { ComponentFamily::GetID(); } diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.h b/SHADE_Engine/src/Camera/SHCameraComponent.h index 846f4c2b..b778b8fa 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraComponent.h @@ -33,7 +33,7 @@ namespace SHADE SHVec3 position; bool perspProj; - + SHVec3 offset; diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.cpp b/SHADE_Engine/src/Camera/SHCameraDirector.cpp index f1e98b71..98341098 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.cpp +++ b/SHADE_Engine/src/Camera/SHCameraDirector.cpp @@ -49,12 +49,7 @@ namespace SHADE viewMatrix = camComponent->GetViewMatrix(); projMatrix = camComponent->GetProjMatrix(); } - SHCameraArmComponent* armComponent = SHComponentManager::GetComponent_s(mainCameraEID); - if (armComponent && camComponent) - { - SHMatrix tempView = armComponent->GetMatrix() * camComponent->GetViewMatrix(); - viewMatrix = tempView; - } + } void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 115d83bb..be34ecf0 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -6,6 +6,7 @@ #include "Math/Vector/SHVec2.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" +#include namespace SHADE @@ -60,6 +61,7 @@ namespace SHADE } UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { @@ -113,6 +115,8 @@ namespace SHADE //std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl; system->UpdateCameraComponent(system->editorCamera); + + system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); } void SHCameraSystem::Init(void) @@ -142,11 +146,18 @@ namespace SHADE { if (pivot.dirty) { - pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) - * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw())) - * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength())); - pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); + SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() }; + offset = SHVec3::RotateX(offset, (pivot.GetPitch())); + offset = SHVec3::RotateY(offset, (pivot.GetYaw())); + + + //pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) + // * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw())) + // * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength())); + + pivot.offset = offset; + // pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix); } } @@ -168,6 +179,12 @@ namespace SHADE if (camera.dirtyView) { + camera.offset = SHVec3{ 0.0f }; + if (SHComponentManager::HasComponent(camera.GetEID())) + { + camera.offset = SHComponentManager::GetComponent(camera.GetEID())->GetOffset(); + } + SHVec3 view, right, UP; @@ -188,9 +205,12 @@ namespace SHADE camera.viewMatrix(2, 1) = view[1]; camera.viewMatrix(2, 2) = view[2]; - camera.viewMatrix(0, 3) = -right.Dot(camera.position); - camera.viewMatrix(1, 3) = -UP.Dot(camera.position); - camera.viewMatrix(2, 3) = -view.Dot(camera.position); + camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset); + camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset); + camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset); + + + camera.dirtyView = false; } @@ -237,6 +257,13 @@ namespace SHADE SHVec3 target{ 0.0f,0.0f,-1.0f }; SHVec3 up = { 0.0f,1.0f,0.0f }; + if (SHComponentManager::HasComponent(camera.GetEID())) + { + auto arm = SHComponentManager::GetComponent(camera.GetEID()); + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch + arm->GetPitch())); + target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw + arm->GetYaw())); + } + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); @@ -310,6 +337,45 @@ namespace SHADE if (camera.roll < -clampVal) camera.SetRoll(-clampVal); + while (camera.yaw > 360) + camera.yaw -= 360; + while (camera.yaw < -360) + camera.yaw += 360; + + } + + void SHCameraSystem::SetMainCamera(EntityID eid, size_t directorIndex) noexcept + { + if (SHComponentManager::HasComponent(eid) && directorIndex < directorHandleList.size()) + directorHandleList[directorIndex]->SetMainCamera(*SHComponentManager::GetComponent(eid)); + else + { + SHLOG_WARNING("Set Main Camera warning: Entity does not have camera component or director does not exist.") + } + } + + void SHCameraSystem::DecomposeViewMatrix(SHMatrix& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept + { + + float initPitch = pitch; + SHVec3 initPos = pos; + SHVec3 translate3, scale; + SHQuaternion quat; + + SHMatrix viewInverse = viewMatrix; + + viewInverse.Decompose(translate3, quat, scale); + yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y); + pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x); + SHVec4 translate = (viewMatrix * SHVec4(0.0f, 0.0f, 0.0f,1.0f) ); + + //float forwardLengthXZ = sqrt(viewMatrix(0,2) * viewMatrix(0,2) + viewMatrix(2, 2) * viewMatrix(2, 2)); + //yaw = SHMath::RadiansToDegrees( atan2f(viewMatrix(2,0), viewMatrix(2, 2))); + //pitch = SHMath::RadiansToDegrees( atan2f(viewMatrix(2, 1), forwardLengthXZ )); + //roll = SHMath::RadiansToDegrees( atan2f(viewMatrix(0, 1), viewMatrix(0,0))); + + //std::cout << "Init yaw: " << initPitch<< " , yaw: " << pitch << std::endl; + std::cout << "Init pos: " << initPos.x << initPos.y<< initPos.z << " , pos: " << translate.x< Date: Mon, 31 Oct 2022 15:06:08 +0800 Subject: [PATCH 12/57] Added GetEntityByName to EntityManager --- .../src/ECS_Base/Managers/SHEntityManager.cpp | 11 ++++++++++- SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp index bbf8d400..6ce4f277 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.cpp @@ -213,5 +213,14 @@ namespace SHADE return SHSerialization::DeserializeEntityToSceneFromString(data); }*/ - + EntityID SHEntityManager::GetEntityByName(std::string const& name) noexcept + { + EntityID result = MAX_EID; + for (auto& entity : entityVec) + { + if (entity->name == name) + result = entity->GetEID(); + } + return result; + } } diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h index f32ab2c4..911748bd 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h +++ b/SHADE_Engine/src/ECS_Base/Managers/SHEntityManager.h @@ -209,6 +209,8 @@ namespace SHADE //static EntityID DuplicateEntity(EntityID eid) noexcept; + static EntityID GetEntityByName(std::string const& name) noexcept; + protected: From b04565c9dcb557766f2b5be4095d0141df620265 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 15:07:10 +0800 Subject: [PATCH 13/57] Added implementation for scripts and component functions for scripts --- SHADE_Managed/src/Components/Component.cxx | 5 ++++ SHADE_Managed/src/Components/Component.hxx | 9 ++++++++ SHADE_Managed/src/Scripts/Script.cxx | 27 +++++++++++----------- SHADE_Managed/src/Scripts/Script.hxx | 9 ++++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/SHADE_Managed/src/Components/Component.cxx b/SHADE_Managed/src/Components/Component.cxx index a6afc5cc..7f56fad3 100644 --- a/SHADE_Managed/src/Components/Component.cxx +++ b/SHADE_Managed/src/Components/Component.cxx @@ -67,6 +67,11 @@ namespace SHADE ScriptStore::RemoveScript(owner.GetEntity()); } + BaseComponent::operator bool(BaseComponent^ c) + { + return c != nullptr; + } + /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Components/Component.hxx b/SHADE_Managed/src/Components/Component.hxx index 670e4e21..5ffa3952 100644 --- a/SHADE_Managed/src/Components/Component.hxx +++ b/SHADE_Managed/src/Components/Component.hxx @@ -101,6 +101,15 @@ namespace SHADE generic where T : ref class, Script void RemoveScript(); + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a component is null. + /// + /// Component to check. + static operator bool(BaseComponent^ c); + protected: /*-----------------------------------------------------------------------------*/ /* Constructors */ diff --git a/SHADE_Managed/src/Scripts/Script.cxx b/SHADE_Managed/src/Scripts/Script.cxx index ecd27325..d4004e03 100644 --- a/SHADE_Managed/src/Scripts/Script.cxx +++ b/SHADE_Managed/src/Scripts/Script.cxx @@ -18,6 +18,8 @@ of DigiPen Institute of Technology is prohibited. #include "Script.hxx" // Project Headers #include "Utility/Debug.hxx" +#include "ScriptStore.hxx" +#include "Engine/ECS.hxx" namespace SHADE { @@ -49,8 +51,7 @@ namespace SHADE generic void Script::RemoveComponent() { - throw gcnew System::NotImplementedException; - //ECS::RemoveComponent(owner.GetNativeEntity()); + owner.RemoveComponent(); } /*---------------------------------------------------------------------------------*/ @@ -59,37 +60,37 @@ namespace SHADE generic T Script::AddScript() { - throw gcnew System::NotImplementedException; - //return ScriptStore::AddScript(owner.GetEntity()); + return ScriptStore::AddScript(owner.GetEntity()); } generic T Script::GetScript() { - throw gcnew System::NotImplementedException; - //return ScriptStore::GetScript(owner.GetEntity()); + return ScriptStore::GetScript(owner.GetEntity()); } generic T Script::GetScriptInChildren() { - throw gcnew System::NotImplementedException; - //return ScriptStore::GetScriptInChildren(owner.GetEntity()); + return ScriptStore::GetScriptInChildren(owner.GetEntity()); } generic System::Collections::Generic::IEnumerable^ Script::GetScripts() { - throw gcnew System::NotImplementedException; - //return ScriptStore::GetScripts(owner.GetEntity()); + return ScriptStore::GetScripts(owner.GetEntity()); } generic void Script::RemoveScript() { - throw gcnew System::NotImplementedException; - //ScriptStore::RemoveScript(owner.GetEntity()); + ScriptStore::RemoveScript(owner.GetEntity()); } - + + Script::operator bool(Script^ s) + { + return s != nullptr; + } + /*---------------------------------------------------------------------------------*/ /* "All-time" Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/Script.hxx b/SHADE_Managed/src/Scripts/Script.hxx index cef9f4cd..bd336726 100644 --- a/SHADE_Managed/src/Scripts/Script.hxx +++ b/SHADE_Managed/src/Scripts/Script.hxx @@ -153,6 +153,15 @@ namespace SHADE generic where T : ref class, Script void RemoveScript(); + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a component is null. + /// + /// Component to check. + static operator bool(Script^ s); + internal: /*-----------------------------------------------------------------------------*/ /* "All-Time" Lifecycle Functions */ From 1d2b23d762d9aa6d30cb1ac92c88cf01c5f66e04 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 15:19:57 +0800 Subject: [PATCH 14/57] Fixed script deletion and OnDestroy never being called --- SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp index 5467fc56..a2981c06 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp @@ -54,7 +54,7 @@ namespace SHADE /* System Routine Functions - FrameCleanUpRoutine */ /*-----------------------------------------------------------------------------------*/ SHScriptEngine::FrameCleanUpRoutine::FrameCleanUpRoutine() - : SHSystemRoutine("Script Engine Frame Clean Up", false) + : SHSystemRoutine("Script Engine Frame Clean Up", true) {} void SHScriptEngine::FrameCleanUpRoutine::Execute(double) noexcept { From f91b1f00ad887b08c228ced6693875691140cc08 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 15:28:28 +0800 Subject: [PATCH 15/57] Added implementation for GameObject.Find() --- SHADE_Managed/src/Engine/GameObject.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 8c78e399..c9a3cebc 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -19,6 +19,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/Managers/SHEntityManager.h" // Project Headers #include "ECS.hxx" +#include "Utility/Convert.hxx" #include "Scripts/ScriptStore.hxx" namespace SHADE @@ -39,7 +40,13 @@ namespace SHADE System::Nullable GameObject::Find(System::String ^ name) { // Search the GameObjectLibrary for an Entity with the specified name - throw gcnew System::NotImplementedException(); + const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name)); + if (ENTITY_ID == MAX_EID) + { + return {}; + } + + return GameObject(ENTITY_ID); } /*---------------------------------------------------------------------------------*/ From 0e2b0177163d8f1d0cbec688a877874ec58a6476 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 15:39:04 +0800 Subject: [PATCH 16/57] View matrix decomposition and set view matrix View matrix decomposition does not decompose roll yet but there isn't much use case --- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 35 ++++++++++++++-------- SHADE_Engine/src/Camera/SHCameraSystem.h | 14 ++++----- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index be34ecf0..16f651e8 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -354,7 +354,7 @@ namespace SHADE } } - void SHCameraSystem::DecomposeViewMatrix(SHMatrix& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept + void SHCameraSystem::DecomposeViewMatrix(SHMatrix const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept { float initPitch = pitch; @@ -362,20 +362,29 @@ namespace SHADE SHVec3 translate3, scale; SHQuaternion quat; - SHMatrix viewInverse = viewMatrix; + //SHMatrix viewInverse = viewMatrix; - viewInverse.Decompose(translate3, quat, scale); + viewMatrix.Decompose(translate3, quat, scale); yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y); pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x); - SHVec4 translate = (viewMatrix * SHVec4(0.0f, 0.0f, 0.0f,1.0f) ); - - //float forwardLengthXZ = sqrt(viewMatrix(0,2) * viewMatrix(0,2) + viewMatrix(2, 2) * viewMatrix(2, 2)); - //yaw = SHMath::RadiansToDegrees( atan2f(viewMatrix(2,0), viewMatrix(2, 2))); - //pitch = SHMath::RadiansToDegrees( atan2f(viewMatrix(2, 1), forwardLengthXZ )); - //roll = SHMath::RadiansToDegrees( atan2f(viewMatrix(0, 1), viewMatrix(0,0))); - - //std::cout << "Init yaw: " << initPitch<< " , yaw: " << pitch << std::endl; - std::cout << "Init pos: " << initPos.x << initPos.y<< initPos.z << " , pos: " << translate.x< directorLibrary; std::vector directorHandleList; + + void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; + + public: SHCameraSystem(void) = default; virtual ~SHCameraSystem(void) = default; @@ -55,13 +60,8 @@ namespace SHADE void ClampCameraRotation(SHCameraComponent& camera) noexcept; void UpdateEditorCamera(double dt) noexcept; void SetMainCamera(EntityID eid, size_t directorIndex) noexcept; - void DecomposeViewMatrix(SHMatrix& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; - - protected: - - void UpdateCameraComponent(SHCameraComponent& camera) noexcept; - void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; - + void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; + void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept; }; From b7abfde3104608844b94facca2ae9d44a869eef7 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 15:54:54 +0800 Subject: [PATCH 17/57] Added Collision and Trigger Events --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 209 ++++++++++++++++++- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 79 ++++--- SHADE_Engine/src/Physics/SHPhysicsUtils.cpp | 93 +++++++++ SHADE_Engine/src/Physics/SHPhysicsUtils.h | 116 ++++++++++ 4 files changed, 454 insertions(+), 43 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsUtils.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsUtils.h diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 03241dd4..00cd0ed1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -99,6 +99,16 @@ namespace SHADE return 0; } + const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept + { + return collisionInfo; + } + + const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetTriggerInfo() const noexcept + { + return triggerInfo; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -187,6 +197,7 @@ namespace SHADE settings.defaultBounciness = 0.0f; world = factory.createPhysicsWorld(settings); + world->setEventListener(this); // Set up solvers world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES); @@ -316,7 +327,63 @@ namespace SHADE { system->SyncTransforms(); - // TODO(Diren): Handle trigger messages for scripting + // TODO(Kah Wei): Take Collision & Trigger messages here + + system->ClearInvalidCollisions(); + } + } + + void SHPhysicsSystem::onContact(const CallbackData& callbackData) + { + for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) + { + auto contactPair = callbackData.getContactPair(i); + SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair); + + // Find contact pair in container + auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e) + { + const bool ENTITY_MATCH = e.value[0] == newCollisionEvent.value[0]; + const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1]; + return ENTITY_MATCH && COLLIDERS_MATCH; + }); + + if (existingEvent == collisionInfo.end()) + { + // Add new event + collisionInfo.emplace_back(newCollisionEvent); + } + else + { + existingEvent->collisionState = newCollisionEvent.collisionState; + } + } + } + + void SHPhysicsSystem::onTrigger(const rp3d::OverlapCallback::CallbackData& callbackData) + { + for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i) + { + auto contactPair = callbackData.getOverlappingPair(i); + SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); + + // Find contact pair in container + auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e) + { + const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0]; + const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1]; + return ENTITY_MATCH && COLLIDERS_MATCH; + }); + + if (existingEvent == collisionInfo.end()) + { + // Add new event + triggerInfo.emplace_back(newTriggerEvent); + } + else + { + existingEvent->collisionState = newTriggerEvent.collisionState; + } } } @@ -468,6 +535,146 @@ namespace SHADE } } + void SHPhysicsSystem::ClearInvalidCollisions() noexcept + { + for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();) + { + if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT + || collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) + { + collisionInfoIter = collisionInfo.erase(collisionInfoIter); + } + else + { + ++collisionInfoIter; + } + } + + for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();) + { + if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT + || triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) + { + triggerInfoIter = triggerInfo.erase(triggerInfoIter); + } + else + { + ++triggerInfoIter; + } + } + } + + SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::CollisionCallback::ContactPair& cp) noexcept + { + static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t + { + for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) + { + const auto* collider = physicsObject.rp3dBody->getCollider(i); + if (collider->getEntity() == colliderID) + return i; + } + + return std::numeric_limits::max(); + }; + + SHCollisionEvent cInfo; + // Update collision state + cInfo.collisionState = static_cast(cp.getEventType()); + + // Match body and collider for collision event + const rp3d::Entity body1 = cp.getBody1()->getEntity(); + const rp3d::Entity body2 = cp.getBody2()->getEntity(); + const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); + const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); + + // Find and match both ids + bool matched[2] = { false, false }; + + for (auto& [entityID, physicsObject] : map) + { + // Match body 1 + if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) + { + cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); + + matched[SHCollisionEvent::ENTITY_A] = true; + } + + // Match body 2 + if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) + { + cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); + + matched[SHCollisionEvent::ENTITY_B] = true; + } + + if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) + return cInfo; + } + + return cInfo; + } + + SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::OverlapCallback::OverlapPair& cp) noexcept + { + static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t + { + for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) + { + const auto* collider = physicsObject.rp3dBody->getCollider(i); + if (collider->getEntity() == colliderID) + return i; + } + + return std::numeric_limits::max(); + }; + + SHCollisionEvent cInfo; + + // Match body and collider for collision event + const rp3d::Entity body1 = cp.getBody1()->getEntity(); + const rp3d::Entity body2 = cp.getBody2()->getEntity(); + const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); + const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); + + // Find and match both ids + bool matched[2] = { false, false }; + + + for (auto& [entityID, physicsObject] : map) + { + // Match body 1 + if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) + { + cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); + + matched[SHCollisionEvent::ENTITY_A] = true; + } + + // Match body 2 + if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) + { + cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); + + matched[SHCollisionEvent::ENTITY_B] = true; + } + + if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) + return cInfo; + } + + // Update collision state + cInfo.collisionState = static_cast(cp.getEventType()); + + return cInfo; + } + + SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) { const auto& EVENT_DATA = reinterpret_cast*>(addComponentEvent.get()); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index a3c3bea1..8d043a7e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -23,7 +23,7 @@ #include "Math/Transform/SHTransformComponent.h" #include "Scene/SHSceneGraph.h" #include "SHPhysicsObject.h" - +#include "SHPhysicsUtils.h" namespace SHADE @@ -32,7 +32,8 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHPhysicsSystem final : public SHSystem + class SH_API SHPhysicsSystem final : public SHSystem + , public rp3d::EventListener { public: /*---------------------------------------------------------------------------------*/ @@ -47,6 +48,8 @@ namespace SHADE bool sleepingEnabled; }; + using CollisionEvents = std::vector; + /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ @@ -57,13 +60,16 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] double GetFixedDT () const noexcept; + [[nodiscard]] double GetFixedDT () const noexcept; - [[nodiscard]] bool IsSleepingEnabled () const noexcept; + [[nodiscard]] bool IsSleepingEnabled () const noexcept; - [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; - [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; - [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; + [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; + [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + + [[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept; + [[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept; /*---------------------------------------------------------------------------------*/ @@ -82,16 +88,14 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; - //void AddRigidBody (EntityID entityID) noexcept; - //void AddCollider (EntityID entityID) noexcept; - //void RemoveRigidBody (EntityID entityID) noexcept; - //void RemoveCollider (EntityID entityID) noexcept; + void AddCollisionShape (EntityID entityID, SHCollider* collider); + void RemoveCollisionShape (EntityID entityID, int index); - void AddCollisionShape (EntityID entityID, SHCollider* collider); - void RemoveCollisionShape (EntityID entityID, int index); + void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override; + void onTrigger (const rp3d::OverlapCallback::CallbackData& callbackData) override; /*---------------------------------------------------------------------------------*/ /* System Routines */ @@ -156,49 +160,40 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - bool worldUpdated; + bool worldUpdated; - double interpolationFactor; - double fixedDT; - - rp3d::PhysicsWorld* world; - rp3d::PhysicsCommon factory; - - EntityObjectMap map; + double interpolationFactor; + double fixedDT; + rp3d::PhysicsWorld* world; + rp3d::PhysicsCommon factory; + EntityObjectMap map; + CollisionEvents collisionInfo; + CollisionEvents triggerInfo; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; - SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; - void DestroyPhysicsObject (EntityID entityID) noexcept; + + + SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; + SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + void DestroyPhysicsObject (EntityID entityID) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; void SyncRigidBodyComponents (std::vector& denseArray) noexcept; void SyncColliderComponents (std::vector& denseArray) noexcept; void SyncTransforms () noexcept; + void ClearInvalidCollisions () noexcept; + + SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept; + SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept; SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); }; - /*-----------------------------------------------------------------------------------*/ - /* Event Data Definitions */ - /*-----------------------------------------------------------------------------------*/ - - struct SHPhysicsColliderAddedEvent - { - EntityID entityID; - SHCollider::Type colliderType; - int colliderIndex; - }; - - struct SHPhysicsColliderRemovedEvent - { - EntityID entityID; - int colliderIndex; - }; + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp new file mode 100644 index 00000000..8d5bc956 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.cpp @@ -0,0 +1,93 @@ +/**************************************************************************************** + * \file SHPhysicsUtils.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for some Physics Utilities + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHPhysicsUtils.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHCollisionEvent::SHCollisionEvent() noexcept + : collisionState { State::INVALID } + { + ids[ENTITY_A] = MAX_EID; + ids[ENTITY_B] = MAX_EID; + ids[COLLIDER_A] = std::numeric_limits::max(); + ids[COLLIDER_B] = std::numeric_limits::max(); + } + + SHCollisionEvent::SHCollisionEvent(EntityID entityA, EntityID entityB) noexcept + : collisionState { State::INVALID } + { + ids[ENTITY_A] = entityA; + ids[ENTITY_B] = entityB; + ids[COLLIDER_A] = std::numeric_limits::max(); + ids[COLLIDER_B] = std::numeric_limits::max(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHCollisionEvent::operator==(const SHCollisionEvent& rhs) const noexcept + { + return value[0] == rhs.value[0] && value[1] == rhs.value[1]; + } + + bool SHCollisionEvent::operator!=(const SHCollisionEvent& rhs) const noexcept + { + return value[0] != rhs.value[0] || value[1] != rhs.value[1]; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + EntityID SHCollisionEvent::GetEntityA() const noexcept + { + return ids[ENTITY_A]; + } + + EntityID SHCollisionEvent::GetEntityB() const noexcept + { + return ids[ENTITY_B]; + } + + const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyA() const noexcept + { + return SHComponentManager::GetComponent_s(ids[ENTITY_A]); + } + + const SHRigidBodyComponent* SHCollisionEvent::GetRigidBodyB() const noexcept + { + return SHComponentManager::GetComponent_s(ids[ENTITY_B]); + } + + const SHCollider* SHCollisionEvent::GetColliderA() const noexcept + { + return &SHComponentManager::GetComponent(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]); + } + + const SHCollider* SHCollisionEvent::GetColliderB() const noexcept + { + return &SHComponentManager::GetComponent(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]); + } + + SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept + { + return collisionState; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsUtils.h b/SHADE_Engine/src/Physics/SHPhysicsUtils.h new file mode 100644 index 00000000..57f9c6fc --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsUtils.h @@ -0,0 +1,116 @@ +/**************************************************************************************** + * \file SHPhysicsUtils.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for some Physics Utilities + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Headers +#include "Components/SHColliderComponent.h" +#include "Components/SHRigidBodyComponent.h" + + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SHPhysicsColliderAddedEvent + { + EntityID entityID; + SHCollider::Type colliderType; + int colliderIndex; + }; + + struct SHPhysicsColliderRemovedEvent + { + EntityID entityID; + int colliderIndex; + }; + + class SH_API SHCollisionEvent + { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class State + { + ENTER + , STAY + , EXIT + + , TOTAL + , INVALID = -1 + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHCollisionEvent () noexcept; + SHCollisionEvent (EntityID entityA, EntityID entityB) noexcept; + + + SHCollisionEvent (const SHCollisionEvent& rhs) = default; + SHCollisionEvent (SHCollisionEvent&& rhs) = default; + ~SHCollisionEvent () = default; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + bool operator== (const SHCollisionEvent& rhs) const noexcept; + bool operator!= (const SHCollisionEvent& rhs) const noexcept; + + SHCollisionEvent& operator= (const SHCollisionEvent& rhs) = default; + SHCollisionEvent& operator= (SHCollisionEvent&& rhs) = default; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] EntityID GetEntityA () const noexcept; + [[nodiscard]] EntityID GetEntityB () const noexcept; + [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept; + [[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept; + [[nodiscard]] const SHCollider* GetColliderA () const noexcept; + [[nodiscard]] const SHCollider* GetColliderB () const noexcept; + [[nodiscard]] State GetCollisionState () const noexcept; + + private: + + static constexpr uint32_t ENTITY_A = 0; + static constexpr uint32_t ENTITY_B = 1; + static constexpr uint32_t COLLIDER_A = 2; + static constexpr uint32_t COLLIDER_B = 3; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + union + { + uint64_t value[2]; // EntityValue, ColliderIndexValue + uint32_t ids [4]; // EntityA, EntityB, ColliderIndexA, ColliderIndexB + }; + + State collisionState; + }; + + +} // namespace SHADE \ No newline at end of file From 3638828541701824556b34f9eab19602aee2e3ea Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 16:04:40 +0800 Subject: [PATCH 18/57] Fixed desync of rigid body velocities --- SHADE_Engine/src/Physics/SHCollider.h | 2 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 18 ++++-- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 67 +++++--------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 2 - 4 files changed, 31 insertions(+), 58 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index f760ffd0..65e35698 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -96,7 +96,7 @@ namespace SHADE void SetDensity (float density) noexcept; void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept; - void SetPositionOffset (const SHVec3& positionOffset) noexcept; + void SetPositionOffset (const SHVec3& posOffset) noexcept; private: /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 4d4d8cd7..36836404 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -172,11 +172,15 @@ namespace SHADE { SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") - if (rb->dirtyFlags == 0) - return; - auto* rigidBody = reinterpret_cast(rp3dBody); + // Sync velocities + rb->linearVelocity = rigidBody->getLinearVelocity(); + rb->angularVelocity = rigidBody->getAngularVelocity(); + + if (rb->dirtyFlags == 0) + return; + const uint16_t RB_FLAGS = rb->dirtyFlags; for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) { @@ -266,8 +270,12 @@ namespace SHADE if (!collider.dirty) continue; - // Update offsets auto* rp3dCollider = rp3dBody->getCollider(index); + + // Update trigger flag + rp3dCollider->setIsTrigger(collider.IsTrigger()); + + // Update offsets rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); switch (collider.GetType()) @@ -293,6 +301,8 @@ namespace SHADE default: break; } + // TODO(Diren): Update Material + collider.dirty = false; ++index; } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 00cd0ed1..454759e4 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -281,6 +281,14 @@ namespace SHADE rp3dRigidBody->setLinearVelocity(SHVec3::Zero); rp3dRigidBody->setAngularVelocity(SHVec3::Zero); } + + const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; + system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncRigidBody(rigidBodyComponent); } auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); @@ -288,13 +296,17 @@ namespace SHADE { colliderComponent->position = WORLD_POS; colliderComponent->orientation = WORLD_ROT; + + const bool COMPONENT_ACTIVE = colliderComponent->isActive; + system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncColliders(colliderComponent); } } } - - // Update bodies and colliders if component is dirty - system->SyncRigidBodyComponents(SHComponentManager::GetDense()); - system->SyncColliderComponents(SHComponentManager::GetDense()); } void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept @@ -427,53 +439,6 @@ namespace SHADE physicsObject->rp3dBody->setIsActive(componentActive); } - - void SHPhysicsSystem::SyncRigidBodyComponents(std::vector& denseArray) noexcept - { - if (denseArray.empty()) - return; - - for (auto& comp : denseArray) - { - const EntityID ENTITY_ID = comp.GetEID(); - - // Get physicsObject - auto* physicsObject = GetPhysicsObject(ENTITY_ID); - - // TODO(Diren): Check if active in hierarchy - const bool COMPONENT_ACTIVE = comp.isActive; - SyncActiveStates(physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject->SyncRigidBody(&comp); - } - } - - void SHPhysicsSystem::SyncColliderComponents(std::vector& denseArray) noexcept - { - if (denseArray.empty()) - return; - - for (auto& comp : denseArray) - { - const EntityID ENTITY_ID = comp.GetEID(); - - // Get physicsObject - auto* physicsObject = GetPhysicsObject(ENTITY_ID); - - // TODO(Diren): Check if active in hierarchy - const bool COMPONENT_ACTIVE = comp.isActive; - SyncActiveStates(physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject->SyncColliders(&comp); - } - } - void SHPhysicsSystem::SyncTransforms() noexcept { for (auto& [entityID, physicsObject] : map) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 8d043a7e..744615d1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -182,8 +182,6 @@ namespace SHADE void DestroyPhysicsObject (EntityID entityID) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; - void SyncRigidBodyComponents (std::vector& denseArray) noexcept; - void SyncColliderComponents (std::vector& denseArray) noexcept; void SyncTransforms () noexcept; void ClearInvalidCollisions () noexcept; From 2ffba202f764d3399cb6dfb49701d65d50e45d9f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 16:29:29 +0800 Subject: [PATCH 19/57] Added proper implementation of IsActiveInHierarchy() --- SHADE_Managed/src/Engine/GameObject.cxx | 9 ++++++++- SHADE_Managed/src/Scripts/ScriptStore.cxx | 10 +++------- TempScriptsFolder/PrintWhenActive.cs | 11 +++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 TempScriptsFolder/PrintWhenActive.cs diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index c9a3cebc..55d53d68 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -21,6 +21,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS.hxx" #include "Utility/Convert.hxx" #include "Scripts/ScriptStore.hxx" +#include "Utility/Debug.hxx" namespace SHADE { @@ -63,7 +64,13 @@ namespace SHADE } bool GameObject::IsActiveInHierarchy::get() { - return true; // TODO: Update once we have an equivalent on the Entity object + auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity()); + if (!node) + { + Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive."); + return false; + } + return node->IsActive(); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 1c732358..d7492fdc 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -667,14 +667,10 @@ namespace SHADE bool ScriptStore::isEntityActive(Entity entity) { - // Get native Entity - SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity); - - // Entity Validity Check - if (nativeEntity == nullptr) + // Invalid entity + if (!EntityUtils::IsValid(entity)) return false; - // Check active state - return nativeEntity->GetActive(); + return GameObject(entity).IsActiveInHierarchy; } } diff --git a/TempScriptsFolder/PrintWhenActive.cs b/TempScriptsFolder/PrintWhenActive.cs new file mode 100644 index 00000000..41afdd58 --- /dev/null +++ b/TempScriptsFolder/PrintWhenActive.cs @@ -0,0 +1,11 @@ +using SHADE; + +public class PrintWhenActive : Script +{ + public PrintWhenActive(GameObject gameObj) : base(gameObj) { } + + protected override void update() + { + Debug.Log("Active!"); + } +} \ No newline at end of file From 65013969a87bf9681321cd14ad687d5cfa798953 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 16:39:06 +0800 Subject: [PATCH 20/57] Added Camera LookAt and CameraArmComponent works now --- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 60 +++++++++++++++++++--- SHADE_Engine/src/Camera/SHCameraSystem.h | 2 +- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 16f651e8..a17a2132 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -182,7 +182,9 @@ namespace SHADE camera.offset = SHVec3{ 0.0f }; if (SHComponentManager::HasComponent(camera.GetEID())) { - camera.offset = SHComponentManager::GetComponent(camera.GetEID())->GetOffset(); + auto arm = SHComponentManager::GetComponent(camera.GetEID()); + camera.offset = arm->GetOffset(); + CameraLookAt(camera, camera.position); } SHVec3 view, right, UP; @@ -257,12 +259,7 @@ namespace SHADE SHVec3 target{ 0.0f,0.0f,-1.0f }; SHVec3 up = { 0.0f,1.0f,0.0f }; - if (SHComponentManager::HasComponent(camera.GetEID())) - { - auto arm = SHComponentManager::GetComponent(camera.GetEID()); - target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch + arm->GetPitch())); - target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw + arm->GetYaw())); - } + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); @@ -387,4 +384,53 @@ namespace SHADE DecomposeViewMatrix(viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position); camera.dirtyView = true; } + + void SHCameraSystem::CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept + { + + if (camera.position == target) + { + //lets off set it abit so the view is nt fked + target.z -= 0.0001f; + } + SHVec3 forward, right, upVec; + + SHVec3 up = { 0.0f,1.0f,0.0f }; + + + ////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); + + //target = SHVec3::Normalise(target); + + SHVec3::RotateZ(up, camera.roll); + up = SHVec3::Normalise(up); + + + forward = target - (camera.position + camera.offset); forward = SHVec3::Normalise(forward); + right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right); + upVec = SHVec3::Cross(forward, right); + + + SHMatrix viewMtx; + viewMtx = SHMatrix::Identity; + viewMtx(0, 0) = right[0]; + viewMtx(0, 1) = right[1]; + viewMtx(0, 2) = right[2]; + + viewMtx(1, 0) = upVec[0]; + viewMtx(1, 1) = upVec[1]; + viewMtx(1, 2) = upVec[2]; + + viewMtx(2, 0) = forward[0]; + viewMtx(2, 1) = forward[1]; + viewMtx(2, 2) = forward[2]; + + viewMtx(0, 3) = -right.Dot(camera.position + camera.offset); + viewMtx(1, 3) = -upVec.Dot(camera.position + camera.offset); + viewMtx(2, 3) = -forward.Dot(camera.position + camera.offset); + + + SetCameraViewMatrix(camera, viewMtx); + } + } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.h b/SHADE_Engine/src/Camera/SHCameraSystem.h index 6f7e7d1f..98fd442f 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.h +++ b/SHADE_Engine/src/Camera/SHCameraSystem.h @@ -62,7 +62,7 @@ namespace SHADE void SetMainCamera(EntityID eid, size_t directorIndex) noexcept; void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept; - + void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept; }; From f863f57466ad9887805f5e7357f7eb839afaed01 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 16:49:09 +0800 Subject: [PATCH 21/57] Triggers were being stored in the wrong container --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 211 +++++-------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 22 +- SHADE_Engine/src/Physics/SHPhysicsSystem.hpp | 84 ++++++++ 3 files changed, 150 insertions(+), 167 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.hpp diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 454759e4..4939323e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -257,7 +257,10 @@ namespace SHADE if (physicsObject.rp3dBody == nullptr) continue; - const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); + if (transformComponent && transformComponent->HasChanged()) { const auto WORLD_POS = transformComponent->GetWorldPosition(); @@ -266,46 +269,57 @@ namespace SHADE physicsObject.SetPosition(WORLD_POS); physicsObject.SetOrientation(WORLD_ROT); - auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + // Sync physics component transforms + if (rigidBodyComponent) { rigidBodyComponent->position = WORLD_POS; rigidBodyComponent->orientation = WORLD_ROT; - - // Clear all forces and velocities if editor is stopped - if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) - { - auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); - rp3dRigidBody->resetForce(); - rp3dRigidBody->resetTorque(); - rp3dRigidBody->setLinearVelocity(SHVec3::Zero); - rp3dRigidBody->setAngularVelocity(SHVec3::Zero); - } - - const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; - system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject.SyncRigidBody(rigidBodyComponent); } - auto* colliderComponent = SHComponentManager::GetComponent_s(entityID); if (colliderComponent) { colliderComponent->position = WORLD_POS; colliderComponent->orientation = WORLD_ROT; - - const bool COMPONENT_ACTIVE = colliderComponent->isActive; - system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE); - - if (!COMPONENT_ACTIVE) - continue; - - physicsObject.SyncColliders(colliderComponent); } } + + // Sync rigid bodies + + if (rigidBodyComponent) + { + // Clear all forces and velocities if editor is stopped + if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) + { + auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); + rp3dRigidBody->resetForce(); + rp3dRigidBody->resetTorque(); + rp3dRigidBody->setLinearVelocity(SHVec3::Zero); + rp3dRigidBody->setAngularVelocity(SHVec3::Zero); + } + + // Sync active states + const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; + SyncActiveStates(physicsObject, COMPONENT_ACTIVE); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncRigidBody(rigidBodyComponent); + } + + // Sync colliders + + if (colliderComponent) + { + const bool COMPONENT_ACTIVE = colliderComponent->isActive; + SyncActiveStates(physicsObject, colliderComponent->isActive); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncColliders(colliderComponent); + } } } @@ -350,25 +364,20 @@ namespace SHADE for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) { auto contactPair = callbackData.getContactPair(i); - SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair); + SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); // Find contact pair in container auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e) { - const bool ENTITY_MATCH = e.value[0] == newCollisionEvent.value[0]; - const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1]; + const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0]; + const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1]; return ENTITY_MATCH && COLLIDERS_MATCH; }); if (existingEvent == collisionInfo.end()) - { - // Add new event - collisionInfo.emplace_back(newCollisionEvent); - } + collisionInfo.emplace_back(newTriggerEvent); else - { - existingEvent->collisionState = newCollisionEvent.collisionState; - } + existingEvent->collisionState = newTriggerEvent.collisionState; } } @@ -387,15 +396,10 @@ namespace SHADE return ENTITY_MATCH && COLLIDERS_MATCH; }); - if (existingEvent == collisionInfo.end()) - { - // Add new event + if (existingEvent == triggerInfo.end()) triggerInfo.emplace_back(newTriggerEvent); - } else - { existingEvent->collisionState = newTriggerEvent.collisionState; - } } } @@ -432,11 +436,11 @@ namespace SHADE map.erase(entityID); } - void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept + void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject& physicsObject, bool componentActive) noexcept { - const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); + const bool RP3D_ACTIVE = physicsObject.rp3dBody->isActive(); if (RP3D_ACTIVE != componentActive) - physicsObject->rp3dBody->setIsActive(componentActive); + physicsObject.rp3dBody->setIsActive(componentActive); } void SHPhysicsSystem::SyncTransforms() noexcept @@ -529,117 +533,6 @@ namespace SHADE } } - SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::CollisionCallback::ContactPair& cp) noexcept - { - static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t - { - for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) - { - const auto* collider = physicsObject.rp3dBody->getCollider(i); - if (collider->getEntity() == colliderID) - return i; - } - - return std::numeric_limits::max(); - }; - - SHCollisionEvent cInfo; - // Update collision state - cInfo.collisionState = static_cast(cp.getEventType()); - - // Match body and collider for collision event - const rp3d::Entity body1 = cp.getBody1()->getEntity(); - const rp3d::Entity body2 = cp.getBody2()->getEntity(); - const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); - const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); - - // Find and match both ids - bool matched[2] = { false, false }; - - for (auto& [entityID, physicsObject] : map) - { - // Match body 1 - if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) - { - cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; - cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); - - matched[SHCollisionEvent::ENTITY_A] = true; - } - - // Match body 2 - if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) - { - cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; - cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); - - matched[SHCollisionEvent::ENTITY_B] = true; - } - - if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) - return cInfo; - } - - return cInfo; - } - - SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::OverlapCallback::OverlapPair& cp) noexcept - { - static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t - { - for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) - { - const auto* collider = physicsObject.rp3dBody->getCollider(i); - if (collider->getEntity() == colliderID) - return i; - } - - return std::numeric_limits::max(); - }; - - SHCollisionEvent cInfo; - - // Match body and collider for collision event - const rp3d::Entity body1 = cp.getBody1()->getEntity(); - const rp3d::Entity body2 = cp.getBody2()->getEntity(); - const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); - const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); - - // Find and match both ids - bool matched[2] = { false, false }; - - - for (auto& [entityID, physicsObject] : map) - { - // Match body 1 - if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) - { - cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; - cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); - - matched[SHCollisionEvent::ENTITY_A] = true; - } - - // Match body 2 - if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) - { - cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; - cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); - - matched[SHCollisionEvent::ENTITY_B] = true; - } - - if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) - return cInfo; - } - - // Update collision state - cInfo.collisionState = static_cast(cp.getEventType()); - - return cInfo; - } - - SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) { const auto& EVENT_DATA = reinterpret_cast*>(addComponentEvent.get()); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 744615d1..01f633a8 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -28,6 +28,12 @@ namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Concepts */ + /*-----------------------------------------------------------------------------------*/ + + + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -176,22 +182,22 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; void DestroyPhysicsObject (EntityID entityID) noexcept; - void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; + static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; void SyncTransforms () noexcept; void ClearInvalidCollisions () noexcept; - SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept; - SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept; - SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); + + template + || std::is_same_v>> + SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept; }; +} // namespace SHADE - - -} // namespace SHADE \ No newline at end of file +#include "SHPhysicsSystem.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp new file mode 100644 index 00000000..02569d14 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp @@ -0,0 +1,84 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.hpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for templated functions the Physics System + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Primary Header +#include "SHPhysicsSystem.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + template + SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const RP3DCollisionPair& cp) noexcept + { + static const auto MATCH_COLLIDER = [] + ( + const SHPhysicsObject& physicsObject + , const rp3d::Entity colliderID + )->uint32_t + { + for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i) + { + const auto* collider = physicsObject.rp3dBody->getCollider(i); + if (collider->getEntity() == colliderID) + return i; + } + + return std::numeric_limits::max(); + }; + + SHCollisionEvent cInfo; + + // Match body and collider for collision event + const rp3d::Entity body1 = cp.getBody1()->getEntity(); + const rp3d::Entity body2 = cp.getBody2()->getEntity(); + const rp3d::Entity collider1 = cp.getCollider1()->getEntity(); + const rp3d::Entity collider2 = cp.getCollider2()->getEntity(); + + // Find and match both ids + bool matched[2] = { false, false }; + + + for (auto& [entityID, physicsObject] : map) + { + // Match body 1 + if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1) + { + cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1); + + matched[SHCollisionEvent::ENTITY_A] = true; + } + + // Match body 2 + if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2) + { + cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID; + cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2); + + matched[SHCollisionEvent::ENTITY_B] = true; + } + + if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true) + return cInfo; + } + + // Update collision state + cInfo.collisionState = static_cast(cp.getEventType()); + + return cInfo; + } +} // namespace SHADE \ No newline at end of file From c6cc327141979a12b33c437dae2845351ef0808a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 16:53:34 +0800 Subject: [PATCH 22/57] M dumb. --- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 148 +++++++++---------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 36836404..8b556409 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -173,93 +173,93 @@ namespace SHADE SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") auto* rigidBody = reinterpret_cast(rp3dBody); - - // Sync velocities - rb->linearVelocity = rigidBody->getLinearVelocity(); - rb->angularVelocity = rigidBody->getAngularVelocity(); - - if (rb->dirtyFlags == 0) - return; - - const uint16_t RB_FLAGS = rb->dirtyFlags; - for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) + if (rb->dirtyFlags != 0) { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) + const uint16_t RB_FLAGS = rb->dirtyFlags; + for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) { - switch (i) + // Check if current dirty flag has been set to true + if (RB_FLAGS & 1U << i) { - case 0: // Gravity + switch (i) { - rigidBody->enableGravity(rb->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - const rp3d::Vector3 CONSTRAINTS + case 0: // Gravity { - rb->flags & 1U << 2 ? 0.0f : 1.0f, - rb->flags & 1U << 3 ? 0.0f : 1.0f, - rb->flags & 1U << 4 ? 0.0f : 1.0f - }; + rigidBody->enableGravity(rb->IsGravityEnabled()); + break; + } + case 1: // Sleeping + { + rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); + break; + } + case 2: // Linear Constraints + { + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 2 ? 0.0f : 1.0f, + rb->flags & 1U << 3 ? 0.0f : 1.0f, + rb->flags & 1U << 4 ? 0.0f : 1.0f + }; - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); - break; - } - case 3: // Angular Constraints - { - const rp3d::Vector3 CONSTRAINTS + rigidBody->setLinearLockAxisFactor(CONSTRAINTS); + break; + } + case 3: // Angular Constraints { - rb->flags & 1U << 5 ? 0.0f : 1.0f, - rb->flags & 1U << 6 ? 0.0f : 1.0f, - rb->flags & 1U << 7 ? 0.0f : 1.0f - }; + const rp3d::Vector3 CONSTRAINTS + { + rb->flags & 1U << 5 ? 0.0f : 1.0f, + rb->flags & 1U << 6 ? 0.0f : 1.0f, + rb->flags & 1U << 7 ? 0.0f : 1.0f + }; - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); - break; + rigidBody->setAngularLockAxisFactor(CONSTRAINTS); + break; + } + case 4: // Type + { + rigidBody->setType(static_cast(rb->GetType())); + break; + } + case 5: // Mass + { + rigidBody->setMass(rb->GetMass()); + break; + } + case 6: // Drag + { + rigidBody->setLinearDamping(rb->GetDrag()); + break; + } + case 7: // Angular Drag + { + rigidBody->setAngularDamping(rb->GetAngularDrag()); + break; + } + case 8: // Linear Velocity + { + rigidBody->setLinearVelocity(rb->GetLinearVelocity()); + break; + } + case 9: // Angular Velocity + { + rigidBody->setAngularVelocity(rb->GetAngularVelocity()); + break; + } + default: break; } - case 4: // Type - { - rigidBody->setType(static_cast(rb->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(rb->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(rb->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(rb->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(rb->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(rb->GetAngularVelocity()); - break; - } - default: break; } } - } - rb->dirtyFlags = 0; + rb->dirtyFlags = 0; + } + else + { + rb->linearVelocity = rigidBody->getLinearVelocity(); + rb->angularVelocity = rigidBody->getAngularVelocity(); + } } void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept From 883c5460bc78e9e32a7ef8f4621b862c6dc98872 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 17:23:03 +0800 Subject: [PATCH 23/57] Added a boolean for CameraArm to lock and unlock camera look at --- SHADE_Engine/src/Camera/SHCameraArmComponent.cpp | 5 +++-- SHADE_Engine/src/Camera/SHCameraArmComponent.h | 4 ++-- SHADE_Engine/src/Camera/SHCameraDirector.h | 3 ++- SHADE_Engine/src/Camera/SHCameraSystem.cpp | 7 ++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp index 3b4351fa..9cb221ff 100644 --- a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -7,7 +7,7 @@ namespace SHADE { SHCameraArmComponent::SHCameraArmComponent() - :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true) + :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true) { } @@ -62,6 +62,7 @@ RTTR_REGISTRATION registration::class_("Camera Arm Component") .property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch) .property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw) - .property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength); + .property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength) + .property("Look At Camera Origin", &SHCameraArmComponent::lookAtCameraOrigin); } \ No newline at end of file diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.h b/SHADE_Engine/src/Camera/SHCameraArmComponent.h index e3636b70..2b81a808 100644 --- a/SHADE_Engine/src/Camera/SHCameraArmComponent.h +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -22,8 +22,8 @@ namespace SHADE friend class SHCameraSystem; SHCameraArmComponent(); virtual ~SHCameraArmComponent() = default; - - + + bool lookAtCameraOrigin; //Getters //SHMatrix const& GetMatrix() const noexcept; SHVec3 const& GetOffset() const noexcept; diff --git a/SHADE_Engine/src/Camera/SHCameraDirector.h b/SHADE_Engine/src/Camera/SHCameraDirector.h index 5d09788b..6d5404c5 100644 --- a/SHADE_Engine/src/Camera/SHCameraDirector.h +++ b/SHADE_Engine/src/Camera/SHCameraDirector.h @@ -21,6 +21,7 @@ namespace SHADE EntityID mainCameraEID; EntityID transitionCameraEID; + SHMatrix GetViewMatrix() const noexcept; SHMatrix GetProjMatrix() const noexcept; @@ -35,7 +36,7 @@ namespace SHADE protected: SHMatrix viewMatrix; SHMatrix projMatrix; - + }; typedef Handle DirectorHandle; diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index a17a2132..d5bd414d 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -148,8 +148,8 @@ namespace SHADE { SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() }; - offset = SHVec3::RotateX(offset, (pivot.GetPitch())); - offset = SHVec3::RotateY(offset, (pivot.GetYaw())); + offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch()))); + offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(pivot.GetYaw()))); //pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch())) @@ -184,7 +184,8 @@ namespace SHADE { auto arm = SHComponentManager::GetComponent(camera.GetEID()); camera.offset = arm->GetOffset(); - CameraLookAt(camera, camera.position); + if(arm->lookAtCameraOrigin) + CameraLookAt(camera, camera.position); } SHVec3 view, right, UP; From a9c1bd7e7a4c92ed967719c5c87330ecdaea7ceb Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Mon, 31 Oct 2022 17:25:17 +0800 Subject: [PATCH 24/57] Added remove component broadcast to removeComponentOfEntity --- SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp index be78a146..75a86f37 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp @@ -40,6 +40,12 @@ namespace SHADE { comp->OnDestroy(); } + SHComponentRemovedEvent eventData; + eventData.eid = entityID; + eventData.removedComponentType = i; + + SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); + } @@ -53,6 +59,7 @@ namespace SHADE //entityHandle.RemoveHandle(entityID); + } From dc20317a70837800ef53872004fe67614f0f96d3 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 17:25:31 +0800 Subject: [PATCH 25/57] M dumb again. --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 100 +++++++++---------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 4 +- 2 files changed, 50 insertions(+), 54 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 4939323e..ac0eb792 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -363,21 +363,10 @@ namespace SHADE { for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) { - auto contactPair = callbackData.getContactPair(i); - SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); + const auto CONTACT_PAIR = callbackData.getContactPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR); - // Find contact pair in container - auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e) - { - const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0]; - const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1]; - return ENTITY_MATCH && COLLIDERS_MATCH; - }); - - if (existingEvent == collisionInfo.end()) - collisionInfo.emplace_back(newTriggerEvent); - else - existingEvent->collisionState = newTriggerEvent.collisionState; + UpdateEventContainers(NEW_EVENT, collisionInfo); } } @@ -385,21 +374,10 @@ namespace SHADE { for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i) { - auto contactPair = callbackData.getOverlappingPair(i); - SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair); + const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i); + const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR); - // Find contact pair in container - auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e) - { - const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0]; - const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1]; - return ENTITY_MATCH && COLLIDERS_MATCH; - }); - - if (existingEvent == triggerInfo.end()) - triggerInfo.emplace_back(newTriggerEvent); - else - existingEvent->collisionState = newTriggerEvent.collisionState; + UpdateEventContainers(NEW_EVENT, triggerInfo); } } @@ -495,42 +473,52 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* transformComponent = SHComponentManager::GetComponent(entityID); - transformComponent->SetWorldPosition(rp3dPos); - transformComponent->SetWorldOrientation(rp3dRot); + auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + + if (transformComponent != nullptr) + { + transformComponent->SetWorldPosition(rp3dPos); + transformComponent->SetWorldOrientation(rp3dRot); + } // Cache transforms physicsObject.prevTransform = CURRENT_TF; } } + void SHPhysicsSystem::UpdateEventContainers(const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept + { + const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e) + { + const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0]; + const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1]; + return ENTITY_MATCH && COLLIDERS_MATCH; + }); + + if (IT == container.end()) + container.emplace_back(collisionEvent); + else + IT->collisionState = collisionEvent.collisionState; + } + void SHPhysicsSystem::ClearInvalidCollisions() noexcept { - for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();) + static const auto CLEAR = [](CollisionEvents& container) { - if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT - || collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) + for (auto eventIter = container.begin(); eventIter != container.end();) { - collisionInfoIter = collisionInfo.erase(collisionInfoIter); - } - else - { - ++collisionInfoIter; - } - } + const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT + || eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID; - for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();) - { - if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT - || triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID) - { - triggerInfoIter = triggerInfo.erase(triggerInfoIter); + if (CLEAR_EVENT) + eventIter = container.erase(eventIter); + else + ++eventIter; } - else - { - ++triggerInfoIter; - } - } + }; + + CLEAR(collisionInfo); + CLEAR(triggerInfo); } SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent) @@ -621,6 +609,9 @@ namespace SHADE const EntityID ENTITY_ID = EVENT_DATA->data->eid; auto* physicsObject = GetPhysicsObject(ENTITY_ID); + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") if (REMOVED_ID == RIGID_BODY_ID) @@ -628,7 +619,6 @@ namespace SHADE world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); physicsObject->rp3dBody = nullptr; - auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); if (colliderComponent != nullptr) { // Preserve colliders as a collision body @@ -659,6 +649,10 @@ namespace SHADE auto* collider = physicsObject->rp3dBody->getCollider(i); physicsObject->rp3dBody->removeCollider(collider); } + + // Check for a rigidbody component + if (rigidBodyComponent == nullptr) + physicsObject->rp3dBody = nullptr; } if (physicsObject->rp3dBody == nullptr) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index 01f633a8..f564dc2d 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -188,7 +188,9 @@ namespace SHADE static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept; void SyncTransforms () noexcept; - void ClearInvalidCollisions () noexcept; + + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () noexcept; SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); From 797f4bfd75cdfbe1e126dad1a1a595df9322cfa2 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 17:35:52 +0800 Subject: [PATCH 26/57] Fixed shader changes --- Assets/Shaders/DeferredComposite_CS.shshaderb | Bin 4665 -> 4665 bytes .../DeferredComposite_CS.shshaderb.shmeta | 2 +- Assets/Shaders/TestCube_FS.shshaderb | Bin 2545 -> 2545 bytes Assets/Shaders/TestCube_FS.shshaderb.shmeta | 2 +- Assets/Shaders/TestCube_VS.shshaderb | Bin 3305 -> 3305 bytes Assets/Shaders/TestCube_VS.shshaderb.shmeta | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 15 +++------------ .../MiddleEnd/Interface/SHGraphicsSystem.h | 2 +- 8 files changed, 7 insertions(+), 16 deletions(-) diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index 889de5fb344289c281264b054407d97c317a7fff..4326daf10db596d391072bcf50ec14f892c4b0e6 100644 GIT binary patch delta 10 Rcmdm~vQvdoVI!l35C9W90@wfm delta 10 Rcmdm~vQveTX(OYB5C9UT0=fVI diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb.shmeta b/Assets/Shaders/DeferredComposite_CS.shshaderb.shmeta index 8f18b04a..62c2a3fe 100644 --- a/Assets/Shaders/DeferredComposite_CS.shshaderb.shmeta +++ b/Assets/Shaders/DeferredComposite_CS.shshaderb.shmeta @@ -1,3 +1,3 @@ Name: DeferredComposite_CS -ID: 42814284 +ID: 45072428 Type: 2 diff --git a/Assets/Shaders/TestCube_FS.shshaderb b/Assets/Shaders/TestCube_FS.shshaderb index b0113dc7799a94fb1c40720187c05a9b26a2617c..95b4f62ae89c1bd3dc23f684757a7298c60833a3 100644 GIT binary patch delta 10 Rcmew;{85-uU?bxPP5>7&1H}LU delta 10 Rcmew;{85;ZaU6?1GWGF diff --git a/Assets/Shaders/TestCube_FS.shshaderb.shmeta b/Assets/Shaders/TestCube_FS.shshaderb.shmeta index 42f270af..fbe098b1 100644 --- a/Assets/Shaders/TestCube_FS.shshaderb.shmeta +++ b/Assets/Shaders/TestCube_FS.shshaderb.shmeta @@ -1,3 +1,3 @@ Name: TestCube_FS -ID: 37450402 +ID: 46377769 Type: 2 diff --git a/Assets/Shaders/TestCube_VS.shshaderb b/Assets/Shaders/TestCube_VS.shshaderb index 03e23af37451b6c4c0791110541c7b6e31d07bbe..7a7b047a30087431f6c695dd50c78ecca6b992ca 100644 GIT binary patch delta 10 RcmaDU`BIXRaURequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // Load Built In Shaders - static constexpr AssetID VS_DEFAULT = 41688429; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); - static constexpr AssetID FS_DEFAULT = 37450402; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); - static constexpr AssetID CS_PURE_COPY = 34987209; copyComputeShader = SHResourceManager::LoadOrGet(CS_PURE_COPY); + static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); + static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet(FS_DEFAULT); + static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet(CS_COMPOSITE); } void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept @@ -183,16 +183,7 @@ namespace SHADE gBufferSubpass->AddColorOutput("Albedo"); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); - //// kirsch - //auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl"); - //gBufferNode->AddNodeCompute(kirschShader, { "Position", "Scene" }); - - //// copy - //auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl"); - //gBufferNode->AddNodeCompute(pureCopyShader, { "Position", "Scene" }); - // deferred composite - auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS"); gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" }); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 27c51dbe..3f899446 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -353,7 +353,7 @@ namespace SHADE // Built-In Shaders Handle defaultVertShader; Handle defaultFragShader; - Handle copyComputeShader; + Handle deferredCompositeShader; // Built-In Materials Handle defaultMaterial; From 5bb728663cab404fdc56aa3a27c027080127200c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 17:47:38 +0800 Subject: [PATCH 27/57] Materials are now serializable and deserializable --- .../MiddleEnd/Materials/SHMaterialSpec.h | 36 ++++++ SHADE_Engine/src/Resource/SHResourceManager.h | 7 ++ .../src/Resource/SHResourceManager.hpp | 69 ++++++++++ .../Serialization/SHSerializationHelper.hpp | 118 ++++++------------ 4 files changed, 150 insertions(+), 80 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialSpec.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialSpec.h b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialSpec.h new file mode 100644 index 00000000..338c34b2 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Materials/SHMaterialSpec.h @@ -0,0 +1,36 @@ +/************************************************************************************//*! +\file SHMaterialSpec.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the struct definition of SHMaterialSpec. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once +// Standard Library +#include +#include +#include +// Project Includes +#include "Assets/SHAssetMacros.h" + +namespace SHADE +{ + /*************************************************************************************/ + /*! + \brief + Describes a Material's serialized properties. A representation of a material that is + independent of GPU resources. + */ + /*************************************************************************************/ + struct SHMaterialSpec + { + AssetID vertexShader; + AssetID fragShader; + std::string subpassName; + YAML::Node properties; + }; +} diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index cd014da8..c2ee547e 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" +#include "Graphics/MiddleEnd/Interface/SHMaterial.h" namespace SHADE { @@ -47,6 +48,12 @@ namespace SHADE { using AssetType = SHShaderAsset; }; + template<> + struct SHResourceLoader + { + using AssetType = std::string; + }; + /// /// Static class responsible for loading and caching runtime resources from their diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index badb301f..eef46241 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -13,6 +13,8 @@ of DigiPen Institute of Technology is prohibited. #pragma once // Primary Include #include "SHResourceManager.h" +// External Dependencies +#include // Project Includes #include "Assets/SHAssetManager.h" #include "Assets/Asset Types/SHAssetIncludes.h" @@ -21,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Tools/SHLog.h" #include "Graphics/Shaders/SHVkShaderModule.h" #include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" namespace SHADE { @@ -179,7 +182,73 @@ namespace SHADE // Materials else if constexpr (std::is_same_v) { + // Get the data we need to construct + SHMaterialSpec matSpec = YAML::Node(assetData).as(); + // Load shaders + auto vertexShader = SHResourceManager::LoadOrGet(matSpec.vertexShader); + auto fragShader = SHResourceManager::LoadOrGet(matSpec.fragShader); + + // Ensure that both shaders are present + if (!(vertexShader && fragShader)) + { + SHLOG_ERROR("[SHResourceManager] Failed to load material as shaders failed to be loaded."); + return {}; + } + + // Grab subpass from worldRenderer + auto renderPass = gfxSystem->GetPrimaryRenderpass(); + if (!renderPass) + { + SHLOG_ERROR("[SHResourceManager] Failed to load material as RenderPass could not be found."); + return {}; + } + auto subPass = renderPass->GetSubpass(matSpec.subpassName); + if (!subPass) + { + SHLOG_ERROR("[SHResourceManager] Failed to load material as SubPass could not be found."); + return {}; + } + + // Create material + auto matHandle = gfxSystem->AddMaterial(vertexShader, fragShader, subPass); + + // Set properties for the material + Handle pipelineProperties = matHandle.GetShaderBlockInterface(); + for (int i = 0; i < static_cast(pipelineProperties->GetVariableCount()); ++i) + { + const std::string& PROP_NAME = pipelineProperties->GetVariableName(i); + const auto& PROP_NODE = matSpec.properties; + if (PROP_NODE) + { + const std::string& VAR_NAME = pipelineProperties->GetVariableName(i); + const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i); + switch (VARIABLE->type) + { + case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT: + matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + break; + case SHADE::SHShaderBlockInterface::Variable::Type::INT: + matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + break; + case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: + matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + break; + case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3: + matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + break; + case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4: + matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + break; + case SHADE::SHShaderBlockInterface::Variable::Type::OTHER: + default: + continue; + break; + } + } + } + + return matHandle; } } } diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index 06d4227b..2179d1cf 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -12,8 +12,11 @@ #include "Resource/SHResourceManager.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" +#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "SHSerializationTools.h" #include "Physics/Components/SHColliderComponent.h" +#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" +#include "Tools/SHLog.h" namespace YAML { @@ -310,88 +313,38 @@ namespace YAML return node; } - static bool decode(YAML::Node const& node, SHMaterial& rhs) - { - // Retrieve Shader Asset IDs - AssetID vertShaderId = 0; - AssetID fragShaderId = 0; - if (node[VERT_SHADER_YAML_TAG.data()]) - vertShaderId = node[VERT_SHADER_YAML_TAG.data()].as(); - if (node[FRAG_SHADER_YAML_TAG.data()]) - fragShaderId = node[FRAG_SHADER_YAML_TAG.data()].as(); + }; - // Ensure that both shaders are present - if (vertShaderId == 0 || fragShaderId == 0) - return false; // No pipeline + template<> + struct convert + { + static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader"; + static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader"; + static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass"; + static constexpr std::string_view PROPS_YAML_TAG = "Properties"; - // Get Shader Modules - Handle vertexShader, fragShader; - vertexShader = SHResourceManager::LoadOrGet(vertShaderId); - fragShader = SHResourceManager::LoadOrGet(fragShaderId); + static bool decode(YAML::Node const& node, SHMaterialSpec& rhs) + { + // Retrieve Shader Asset IDs + if (!node[VERT_SHADER_YAML_TAG.data()]) + return false; + rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as(); + if (!node[FRAG_SHADER_YAML_TAG.data()]) + return false; + rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as(); - // Get Pipeline Library - if (node[SUBPASS_YAML_TAG.data()]) - { - auto gfxSystem = SHSystemManager::GetSystem(); - if (!gfxSystem) - return false; + // Retrieve Subpass + if (!node[SUBPASS_YAML_TAG.data()]) + return false; + rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as(); - // Grab subpass from worldRenderer - auto renderPass = gfxSystem->GetPrimaryRenderpass(); - if (!renderPass) - return false; - auto subPass = renderPass->GetSubpass(node[SUBPASS_YAML_TAG.data()].as()); - if (!subPass) - return false; + // Retrieve + if (!node[PROPS_YAML_TAG.data()]) + return false; + rhs.properties = node[PROPS_YAML_TAG.data()]; - // Set Pipeline - rhs.SetPipeline(renderPass->GetOrCreatePipeline - ( - std::make_pair(vertexShader, fragShader), - subPass - )); - } - - if (node[PROPS_YAML_TAG.data()].IsDefined()) - { - // Loop through all properties - Handle pipelineProperties = rhs.GetShaderBlockInterface(); - const YAML::Node& PROPS_NODE = node[PROPS_YAML_TAG.data()]; - for (int i = 0; i < static_cast(pipelineProperties->GetVariableCount()); ++i) - { - const std::string& PROP_NAME = pipelineProperties->GetVariableName(i); - const auto& PROP_NODE = PROPS_NODE[PROP_NAME.data()]; - if (PROP_NODE) - { - const std::string& VAR_NAME = pipelineProperties->GetVariableName(i); - const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i); - switch (VARIABLE->type) - { - case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT: - rhs.SetProperty(VARIABLE->offset, PROP_NODE.as()); - break; - case SHADE::SHShaderBlockInterface::Variable::Type::INT: - rhs.SetProperty(VARIABLE->offset, PROP_NODE.as()); - break; - case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: - rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec2(PROP_NODE)); - break; - case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3: - rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec3(PROP_NODE)); - break; - case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4: - rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec4(PROP_NODE)); - break; - case SHADE::SHShaderBlockInterface::Variable::Type::OTHER: - default: - continue; - break; - } - } - } - } - return true; - } + return true; + } }; template<> @@ -404,7 +357,7 @@ namespace YAML { YAML::Node node; node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetMesh()).value_or(0); - node[MAT_YAML_TAG.data()] = 0; // TODO: Asset ID + node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID(rhs.GetMaterial()->GetBaseMaterial()).value_or(0); return node; } static bool decode(YAML::Node const& node, SHRenderable& rhs) @@ -415,12 +368,17 @@ namespace YAML } if (node[MAT_YAML_TAG.data()].IsDefined()) { - // TODO: Convert Asset ID To Material HAndle // Temporarily, use default material auto gfxSystem = SHSystemManager::GetSystem(); if (!gfxSystem) return false; - rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(gfxSystem->GetDefaultMaterial())); + Handle baseMat = SHResourceManager::LoadOrGet(node[MAT_YAML_TAG.data()].as()); + if (!baseMat) + { + baseMat = gfxSystem->GetDefaultMaterial(); + SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material."); + } + rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat)); } return true; } From a8cb36b46f705a9ad22f6166da92ed9925c84f25 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 17:55:32 +0800 Subject: [PATCH 28/57] Fixed component removal bug on application close --- .../src/ECS_Base/Managers/SHComponentManager.cpp | 12 ++++++------ SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp index 75a86f37..db0d733f 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp @@ -39,13 +39,13 @@ namespace SHADE if (comp) { comp->OnDestroy(); + + SHComponentRemovedEvent eventData; + eventData.eid = entityID; + eventData.removedComponentType = i; + + SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); } - SHComponentRemovedEvent eventData; - eventData.eid = entityID; - eventData.removedComponentType = i; - - SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); - } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index ac0eb792..53db5453 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -612,10 +612,17 @@ namespace SHADE auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") + SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!") if (REMOVED_ID == RIGID_BODY_ID) { + // Wake up all physics objects + for (auto& [entityID, object] : map) + { + if (SHComponentManager::HasComponent(entityID)) + reinterpret_cast(object.rp3dBody)->setIsSleeping(false); + } + world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); physicsObject->rp3dBody = nullptr; @@ -630,13 +637,6 @@ namespace SHADE for (auto& collider : colliderComponent->colliders) physicsObject->AddCollider(&collider); } - - // Wake up all physics objects - for (auto& [entityID, object] : map) - { - if (SHComponentManager::HasComponent(entityID)) - reinterpret_cast(object.rp3dBody)->setIsSleeping(false); - } } if (REMOVED_ID == COLLIDER_ID) From 2ca353a0b7c8dfe46dad7df1cacf5f0d7ccb03bc Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 18:18:06 +0800 Subject: [PATCH 29/57] Fixed compilation issues in SHResourceManager --- SHADE_Engine/src/Resource/SHResourceManager.h | 3 ++- SHADE_Engine/src/Resource/SHResourceManager.hpp | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index c2ee547e..61689420 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" +#include "Assets/Asset Types/SHMaterialAsset.h" namespace SHADE { @@ -51,7 +52,7 @@ namespace SHADE template<> struct SHResourceLoader { - using AssetType = std::string; + using AssetType = SHMaterialAsset; }; diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index eef46241..15834cdf 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -183,7 +183,7 @@ namespace SHADE else if constexpr (std::is_same_v) { // Get the data we need to construct - SHMaterialSpec matSpec = YAML::Node(assetData).as(); + SHMaterialSpec matSpec = YAML::Node(assetData.data).as(); // Load shaders auto vertexShader = SHResourceManager::LoadOrGet(matSpec.vertexShader); @@ -214,7 +214,7 @@ namespace SHADE auto matHandle = gfxSystem->AddMaterial(vertexShader, fragShader, subPass); // Set properties for the material - Handle pipelineProperties = matHandle.GetShaderBlockInterface(); + Handle pipelineProperties = matHandle->GetShaderBlockInterface(); for (int i = 0; i < static_cast(pipelineProperties->GetVariableCount()); ++i) { const std::string& PROP_NAME = pipelineProperties->GetVariableName(i); @@ -226,19 +226,19 @@ namespace SHADE switch (VARIABLE->type) { case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT: - matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::INT: - matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: - matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3: - matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4: - matHandle.SetProperty(VARIABLE->offset, PROP_NODE.as()); + matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as()); break; case SHADE::SHShaderBlockInterface::Variable::Type::OTHER: default: From ccbbdc6485819cfd1994fc9e18072697af8d6760 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 21:05:46 +0800 Subject: [PATCH 30/57] Added CollisionInfo and SHPhysicsSystemInterface --- .../src/Physics/SHPhysicsSystemInterface.cpp | 52 +++++++++++++++++ .../src/Physics/SHPhysicsSystemInterface.h | 42 ++++++++++++++ SHADE_Managed/src/Physics/CollisionInfo.hxx | 58 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h create mode 100644 SHADE_Managed/src/Physics/CollisionInfo.hxx diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp new file mode 100644 index 00000000..b36fa1fa --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp @@ -0,0 +1,52 @@ +/************************************************************************************//*! +\file SHPhysicsSystemInterface.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definitions of the functions of the static + SHPhysicsSystemInterface class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "SHPhysicsSystemInterface.h" +// Project Includes +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Physics/SHPhysicsSystem.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + const std::vector& SHPhysicsSystemInterface::GetCollisionInfo() noexcept + { + static std::vector emptyVec; + + auto phySystem = SHSystemManager::GetSystem(); + if (phySystem) + { + return phySystem->GetCollisionInfo(); + } + + SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get collision events. Empty vector returned instead."); + return emptyVec; + } + const std::vector& SHPhysicsSystemInterface::GetTriggerInfo() noexcept + { + static std::vector emptyVec; + + auto phySystem = SHSystemManager::GetSystem(); + if (phySystem) + { + return phySystem->GetTriggerInfo(); + } + + SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get trigger events. Empty vector returned instead."); + return emptyVec; + } +} diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h new file mode 100644 index 00000000..da164ee9 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h @@ -0,0 +1,42 @@ +/************************************************************************************//*! +\file SHPhysicsSystemInterface.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definition of the SHGraphicsSystemInterface static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// STL Includes +#include +// Project Includes +#include "SHPhysicsUtils.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + /// + /// Static class that wraps up certain functions in the SHPhysicsSystem so that + /// accessing it from SHADE_Managed would not cause issues due to C++20 features. + /// + class SH_API SHPhysicsSystemInterface final + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructor */ + /*---------------------------------------------------------------------------------*/ + SHPhysicsSystemInterface() = delete; + + /*---------------------------------------------------------------------------------*/ + /* Static Usage Functions */ + /*---------------------------------------------------------------------------------*/ + [[nodiscard]] static const std::vector& GetCollisionInfo() noexcept; + [[nodiscard]] static const std::vector& GetTriggerInfo() noexcept; + }; +} diff --git a/SHADE_Managed/src/Physics/CollisionInfo.hxx b/SHADE_Managed/src/Physics/CollisionInfo.hxx new file mode 100644 index 00000000..a486b0d0 --- /dev/null +++ b/SHADE_Managed/src/Physics/CollisionInfo.hxx @@ -0,0 +1,58 @@ +/************************************************************************************//*! +\file CollisionInfo.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definition of the managed CollisionInfo struct with the + definition of its properties and declaration of functions. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once +// Project Includes +#include "Engine/GameObject.hxx" +#include "Components/RigidBody.hxx" +#include "Components/Collider.hxx" + +namespace SHADE +{ + /// + /// Struct that describes a collision + /// + public value struct CollisionInfo + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// The GameObject whose collider you are colliding with. + /// + property GameObject GameObject; + /// + /// The Collider that you are colliding with. + /// + property Collider^ Collider + { + SHADE::Collider^ get(); + } + /// + /// The CollisionShape of the Collider that you are colliding with. + /// + property CollisionShape^ CollisionShape + { + SHADE::CollisionShape^ get(); + } + /// + /// The RigidBody that you are colliding with. + /// + property RigidBody^ RigidBody + { + SHADE::RigidBody^ get(); + } + }; +} From 27e71558ad129c9197013d167f6df97358cc9c83 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 21:26:12 +0800 Subject: [PATCH 31/57] SHPhysicsSystemInterface now uses a forward declaration for SHPhysicsUtils --- SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp | 1 + SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp index b36fa1fa..5343b9f1 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp @@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "ECS_Base/Managers/SHSystemManager.h" #include "Physics/SHPhysicsSystem.h" +#include "Physics/SHPhysicsUtils.h" namespace SHADE { diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h index da164ee9..b1960a6f 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h @@ -13,11 +13,14 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include -// Project Includes -#include "SHPhysicsUtils.h" namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHCollisionEvent; + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ From 40044cbbfe87fb34bb02c22207df8f04c71216cc Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 21:26:39 +0800 Subject: [PATCH 32/57] Added definitions for CollisionInfo properties --- SHADE_Managed/src/Physics/CollisionInfo.cxx | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 SHADE_Managed/src/Physics/CollisionInfo.cxx diff --git a/SHADE_Managed/src/Physics/CollisionInfo.cxx b/SHADE_Managed/src/Physics/CollisionInfo.cxx new file mode 100644 index 00000000..9048837f --- /dev/null +++ b/SHADE_Managed/src/Physics/CollisionInfo.cxx @@ -0,0 +1,34 @@ +/************************************************************************************//*! +\file CollisionInfo.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 31, 2022 +\brief Contains the definition of the functions of the managed CollisionInfo + struct. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "CollisionInfo.hxx" + +namespace SHADE +{ + Collider^ CollisionInfo::Collider::get() + { + return GameObject.GetComponent(); + } + + CollisionShape^ CollisionInfo::CollisionShape::get() + { + throw gcnew System::NotImplementedException(); + } + + RigidBody^ CollisionInfo::RigidBody::get() + { + return GameObject.GetComponent(); + } +} From 60c2c9facbad1b5980e05049e49c79b4d1f25d69 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 21:31:33 +0800 Subject: [PATCH 33/57] Added collision and trigger event functions for Script --- SHADE_Managed/src/Physics/CollisionInfo.cxx | 2 + SHADE_Managed/src/Physics/CollisionInfo.hxx | 12 ++- SHADE_Managed/src/Scripts/Script.cxx | 54 +++++++++++++- SHADE_Managed/src/Scripts/Script.hxx | 83 ++++++++++++++++++++- 4 files changed, 147 insertions(+), 4 deletions(-) diff --git a/SHADE_Managed/src/Physics/CollisionInfo.cxx b/SHADE_Managed/src/Physics/CollisionInfo.cxx index 9048837f..135760db 100644 --- a/SHADE_Managed/src/Physics/CollisionInfo.cxx +++ b/SHADE_Managed/src/Physics/CollisionInfo.cxx @@ -14,6 +14,8 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #include "SHpch.h" #include "CollisionInfo.hxx" +#include "Components/RigidBody.hxx" +#include "Components/Collider.hxx" namespace SHADE { diff --git a/SHADE_Managed/src/Physics/CollisionInfo.hxx b/SHADE_Managed/src/Physics/CollisionInfo.hxx index a486b0d0..40cb9ccc 100644 --- a/SHADE_Managed/src/Physics/CollisionInfo.hxx +++ b/SHADE_Managed/src/Physics/CollisionInfo.hxx @@ -15,11 +15,19 @@ of DigiPen Institute of Technology is prohibited. #pragma once // Project Includes #include "Engine/GameObject.hxx" -#include "Components/RigidBody.hxx" -#include "Components/Collider.hxx" namespace SHADE { + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + ref class RigidBody; + ref class Collider; + ref class CollisionShape; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ /// /// Struct that describes a collision /// diff --git a/SHADE_Managed/src/Scripts/Script.cxx b/SHADE_Managed/src/Scripts/Script.cxx index d4004e03..e476d69d 100644 --- a/SHADE_Managed/src/Scripts/Script.cxx +++ b/SHADE_Managed/src/Scripts/Script.cxx @@ -147,6 +147,48 @@ namespace SHADE SAFE_NATIVE_CALL_END(this) } + void Script::OnCollisionEnter(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onCollisionEnter(collision); + SAFE_NATIVE_CALL_END(this) + } + + void Script::OnCollisionStay(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onCollisionStay(collision); + SAFE_NATIVE_CALL_END(this) + } + + void Script::OnCollisionExit(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onCollisionExit(collision); + SAFE_NATIVE_CALL_END(this) + } + + void Script::OnTriggerEnter(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onTriggerEnter(collision); + SAFE_NATIVE_CALL_END(this) + } + + void Script::OnTriggerStay(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onTriggerStay(collision); + SAFE_NATIVE_CALL_END(this) + } + + void Script::OnTriggerExit(CollisionInfo collision) + { + SAFE_NATIVE_CALL_BEGIN + onTriggerExit(collision); + SAFE_NATIVE_CALL_END(this) + } + /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ @@ -169,4 +211,14 @@ namespace SHADE void Script::update() {} void Script::lateUpdate() {} void Script::onDestroy() {} -}// namespace PlushieAPI + + /*---------------------------------------------------------------------------------*/ + /* Virtual Event Functions */ + /*---------------------------------------------------------------------------------*/ + void Script::onTriggerEnter(CollisionInfo) {} + void Script::onTriggerStay(CollisionInfo) {} + void Script::onTriggerExit(CollisionInfo) {} + void Script::onCollisionEnter(CollisionInfo) {} + void Script::onCollisionStay(CollisionInfo) {} + void Script::onCollisionExit(CollisionInfo) {} +} diff --git a/SHADE_Managed/src/Scripts/Script.hxx b/SHADE_Managed/src/Scripts/Script.hxx index bd336726..afeaa8a0 100644 --- a/SHADE_Managed/src/Scripts/Script.hxx +++ b/SHADE_Managed/src/Scripts/Script.hxx @@ -15,6 +15,7 @@ of DigiPen Institute of Technology is prohibited. // Project Includes #include "Engine/GameObject.hxx" +#include "Physics/CollisionInfo.hxx" namespace SHADE { @@ -213,6 +214,46 @@ namespace SHADE /// void OnDestroy(); + /*-----------------------------------------------------------------------------*/ + /* Event Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Used to call onCollisionEnter(). This should be called when a collision is + /// detected between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnCollisionEnter(CollisionInfo collision); + /// + /// Used to call onCollisionStay(). This should be called when a collision is + /// persistent between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnCollisionStay(CollisionInfo collision); + /// + /// Used to call onCollisionExit(). This should be called when a collision ends + /// between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnCollisionExit(CollisionInfo collision); + /// + /// Used to call onTriggerEnter(). This should be called when a trigger-type + /// collision is detected between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnTriggerEnter(CollisionInfo collision); + /// + /// Used to call onTriggerStay(). This should be called when a trigger-type + /// collision is detected between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnTriggerStay(CollisionInfo collision); + /// + /// Used to call onTriggerExit(). This should be called when a trigger-type + /// collision is detected between the attached GameObject and another GameObject. + /// + /// Information on the collision event. + void OnTriggerExit(CollisionInfo collision); + protected: /*-----------------------------------------------------------------------------*/ /* Constructors */ @@ -273,6 +314,46 @@ namespace SHADE /// virtual void onDestroy(); + /*-----------------------------------------------------------------------------*/ + /* Virtual Event Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Called when the attached GameObject has a trigger Collider and collides with + /// another GameObject with a Collider in the first frame of collision. + /// + /// Information on the collision event. + virtual void onTriggerEnter(CollisionInfo info); + /// + /// Called when the attached GameObject has a trigger Collider and collides with + /// another GameObject with a Collider in subsequent frames of collision. + /// + /// Information on the collision event. + virtual void onTriggerStay(CollisionInfo info); + /// + /// Called when the attached GameObject has a trigger Collider and leaves a + /// collision with another GameObject with a Collider2D. + /// + /// Information on the collision event. + virtual void onTriggerExit(CollisionInfo info); + /// + /// Called when the attached GameObject has a Collider and collides with + /// another GameObject with a Collider in the first frame of collision. + /// + /// Information on the collision event. + virtual void onCollisionEnter(CollisionInfo info); + /// + /// Called when the attached GameObject has a Collider and collides with + /// another GameObject with a Collider in subsequent frames of collision. + /// + /// Information on the collision event. + virtual void onCollisionStay(CollisionInfo info); + /// + /// Called when the attached GameObject has a Collider and leaves a + /// collision with another GameObject with a Collider2D. + /// + /// Information on the collision event. + virtual void onCollisionExit(CollisionInfo info); + private: /*-----------------------------------------------------------------------------*/ /* Data Members */ @@ -280,4 +361,4 @@ namespace SHADE GameObject owner; }; -} // namespace PlushieAPI +} From f9810684ed33d2c29f89498a8274e7e04fdbeb22 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Mon, 31 Oct 2022 21:38:17 +0800 Subject: [PATCH 34/57] Added functions for execution of OnCollision*() and OnTrigger*() --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 11 +- SHADE_Engine/src/Scripting/SHScriptEngine.h | 6 ++ SHADE_Managed/src/Scripts/ScriptStore.cxx | 100 ++++++++++++++++-- SHADE_Managed/src/Scripts/ScriptStore.hxx | 4 + 4 files changed, 109 insertions(+), 12 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 21ce7b82..4a73342e 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -80,7 +80,10 @@ namespace SHADE { csScriptsExecuteFixedUpdate(); } - + void SHScriptEngine::ExecuteCollisionFunctions() + { + csScriptsExecutePhysicsEvents(); + } void SHScriptEngine::Exit() { // Do not allow deinitialization if not initialised @@ -377,6 +380,12 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "ExecuteLateUpdate" ); + csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", + "ExecuteCollisionFunctions" + ); csScriptsFrameCleanUp = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index c38e3618..9ddd617a 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -98,6 +98,11 @@ namespace SHADE /// void ExecuteFixedUpdates(); /// + /// Executes the OnCollision*()s and OnTrigger*()s of the Scripts that are attached + /// to Entities. + /// + void ExecuteCollisionFunctions(); + /// /// Shuts down the DotNetRuntime. /// void Exit() override; @@ -245,6 +250,7 @@ namespace SHADE CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; CsFuncPtr csScriptsExecuteUpdate = nullptr; CsFuncPtr csScriptsExecuteLateUpdate = nullptr; + CsFuncPtr csScriptsExecutePhysicsEvents = nullptr; CsFuncPtr csScriptsFrameCleanUp = nullptr; CsScriptManipFuncPtr csScriptsAdd = nullptr; CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index d7492fdc..48577f2c 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -28,6 +28,8 @@ of DigiPen Institute of Technology is prohibited. #include "Engine/Entity.hxx" #include "Serialisation/ReflectionUtilities.hxx" #include "Engine/Application.hxx" +#include "Physics/SHPhysicsSystemInterface.h" +#include "Physics/SHPhysicsUtils.h" namespace SHADE { @@ -71,7 +73,7 @@ namespace SHADE SAFE_NATIVE_CALL_BEGIN Script^ script; return AddScriptViaNameWithRef(entity, scriptName, script); - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") return false; } @@ -301,7 +303,7 @@ namespace SHADE removeScript(script); } scriptList->Clear(); - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy) { @@ -326,7 +328,7 @@ namespace SHADE startList.Remove(script); } scriptList->Clear(); - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } /*---------------------------------------------------------------------------------*/ @@ -365,7 +367,7 @@ namespace SHADE startList.AddRange(%inactiveStartList); inactiveStartList.Clear(); - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } void ScriptStore::FrameCleanUp() { @@ -386,7 +388,7 @@ namespace SHADE scripts.Remove(entity); } } - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } void ScriptStore::Exit() { @@ -410,7 +412,7 @@ namespace SHADE startList.Clear(); disposalQueue.Clear(); scriptTypeList = nullptr; - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } /*---------------------------------------------------------------------------------*/ @@ -439,7 +441,7 @@ namespace SHADE script->FixedUpdate(); } } - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } void ScriptStore::ExecuteUpdate() { @@ -456,7 +458,7 @@ namespace SHADE script->Update(); } } - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } void ScriptStore::ExecuteLateUpdate() { @@ -473,7 +475,83 @@ namespace SHADE script->LateUpdate(); } } - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") + } + + void ScriptStore::ExecuteCollisionFunctions() + { + SAFE_NATIVE_CALL_BEGIN + /* Collisions */ + const auto& collisions = SHPhysicsSystemInterface::GetCollisionInfo(); + for (const auto& collisionInfo : collisions) + { + const EntityID OWNER = collisionInfo.GetEntityA(); + + // Don't bother if this object has no scripts or is inactive + if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) + continue; + + // Construct the collision state object + CollisionInfo info; + info.GameObject = GameObject(OWNER); + + // Call all of the script's functions + auto entityScripts = scripts[OWNER]; + if (entityScripts->Count > 0) + { + for each (Script^ script in entityScripts) + { + switch (collisionInfo.GetCollisionState()) + { + case SHCollisionEvent::State::ENTER: + script->OnCollisionEnter(info); + break; + case SHCollisionEvent::State::STAY: + script->OnCollisionStay(info); + break; + case SHCollisionEvent::State::EXIT: + script->OnCollisionExit(info); + break; + } + } + } + } + /* Triggers */ + const auto& triggers = SHPhysicsSystemInterface::GetTriggerInfo(); + for (const auto& triggerInfo : triggers) + { + const EntityID OWNER = triggerInfo.GetEntityA(); + + // Don't bother if this object has no scripts or is inactive + if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) + continue; + + // Construct the collision state object + CollisionInfo info; + info.GameObject = GameObject(OWNER); + + // Call all of the script's functions + auto entityScripts = scripts[OWNER]; + if (entityScripts->Count > 0) + { + for each (Script ^ script in entityScripts) + { + switch (triggerInfo.GetCollisionState()) + { + case SHCollisionEvent::State::ENTER: + script->OnTriggerEnter(info); + break; + case SHCollisionEvent::State::STAY: + script->OnTriggerStay(info); + break; + case SHCollisionEvent::State::EXIT: + script->OnTriggerExit(info); + break; + } + } + } + } + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } bool ScriptStore::SerialiseScripts(Entity entity, System::IntPtr yamlNodePtr) @@ -509,7 +587,7 @@ namespace SHADE } return true; - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") return false; } @@ -559,7 +637,7 @@ namespace SHADE } return true; - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") return false; } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index 9aa66fcd..a4c6e824 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -233,6 +233,10 @@ namespace SHADE /// Executes LateUpdate() for all scripts. /// static void ExecuteLateUpdate(); + /// + /// Executes OnCollision*() and OnTrigger*() for all scripts. + /// + static void ExecuteCollisionFunctions(); /*-----------------------------------------------------------------------------*/ /* Serialisation Functions */ From caf6006c9e6dc9d793e253df25274d8a4cd83845 Mon Sep 17 00:00:00 2001 From: mushgunAX Date: Mon, 31 Oct 2022 22:06:28 +0800 Subject: [PATCH 35/57] Update C# Input Enums --- SHADE_Managed/src/Input/Input.hxx | 152 +++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) diff --git a/SHADE_Managed/src/Input/Input.hxx b/SHADE_Managed/src/Input/Input.hxx index f281e4c8..ec015e8b 100644 --- a/SHADE_Managed/src/Input/Input.hxx +++ b/SHADE_Managed/src/Input/Input.hxx @@ -31,10 +31,159 @@ namespace SHADE /// /// Represents the available supported keycodes that can be passed into the /// key-based Input functions. + /// + /// Attempting to follow https://docs.unity3d.com/ScriptReference/KeyCode.html + /// Win32 keycodes are shift-insensitive, i.e. 'A' and 'a' are the same keycode and '1' and '!' are the same keycode /// enum class KeyCode : int { + Backspace = static_cast(SHInputManager::SH_KEYCODE::BACKSPACE), + Delete = static_cast(SHInputManager::SH_KEYCODE::DEL), + Tab = static_cast(SHInputManager::SH_KEYCODE::TAB), + Clear = static_cast(SHInputManager::SH_KEYCODE::CLEAR), + Return = static_cast(SHInputManager::SH_KEYCODE::ENTER), + Pause = static_cast(SHInputManager::SH_KEYCODE::PAUSE), + Escape = static_cast(SHInputManager::SH_KEYCODE::ESCAPE), Space = static_cast(SHInputManager::SH_KEYCODE::SPACE), + Keypad0 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_0), + Keypad1 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_1), + Keypad2 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_2), + Keypad3 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_3), + Keypad4 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_4), + Keypad5 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_5), + Keypad6 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_6), + Keypad7 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_7), + Keypad8 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_8), + Keypad9 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_9), + KeypadPeriod = static_cast(SHInputManager::SH_KEYCODE::DECIMAL), + KeypadDivide = static_cast(SHInputManager::SH_KEYCODE::DIVIDE), + KeypadMultiply = static_cast(SHInputManager::SH_KEYCODE::MULTIPLY), + KeypadMinus = static_cast(SHInputManager::SH_KEYCODE::SUBTRACT), + KeypadPlus = static_cast(SHInputManager::SH_KEYCODE::ADD), + KeypadEnter = static_cast(SHInputManager::SH_KEYCODE::ENTER), + //KeypadEquals + UpArrow = static_cast(SHInputManager::SH_KEYCODE::UP_ARROW), + DownArrow = static_cast(SHInputManager::SH_KEYCODE::DOWN_ARROW), + RightArrow = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ARROW), + LeftArrow = static_cast(SHInputManager::SH_KEYCODE::LEFT_ARROW), + Insert = static_cast(SHInputManager::SH_KEYCODE::INSERT), + Home = static_cast(SHInputManager::SH_KEYCODE::HOME), + End = static_cast(SHInputManager::SH_KEYCODE::END), + PageUp = static_cast(SHInputManager::SH_KEYCODE::PAGE_UP), + PageDown = static_cast(SHInputManager::SH_KEYCODE::PAGE_DOWN), + F1 = static_cast(SHInputManager::SH_KEYCODE::F1), + F2 = static_cast(SHInputManager::SH_KEYCODE::F2), + F3 = static_cast(SHInputManager::SH_KEYCODE::F3), + F4 = static_cast(SHInputManager::SH_KEYCODE::F4), + F5 = static_cast(SHInputManager::SH_KEYCODE::F5), + F6 = static_cast(SHInputManager::SH_KEYCODE::F6), + F7 = static_cast(SHInputManager::SH_KEYCODE::F7), + F8 = static_cast(SHInputManager::SH_KEYCODE::F8), + F9 = static_cast(SHInputManager::SH_KEYCODE::F9), + F10 = static_cast(SHInputManager::SH_KEYCODE::F10), + F11 = static_cast(SHInputManager::SH_KEYCODE::F11), + F12 = static_cast(SHInputManager::SH_KEYCODE::F12), + F13 = static_cast(SHInputManager::SH_KEYCODE::F13), + F14 = static_cast(SHInputManager::SH_KEYCODE::F14), + F15 = static_cast(SHInputManager::SH_KEYCODE::F15), + F16 = static_cast(SHInputManager::SH_KEYCODE::F16), + F17 = static_cast(SHInputManager::SH_KEYCODE::F17), + F18 = static_cast(SHInputManager::SH_KEYCODE::F18), + F19 = static_cast(SHInputManager::SH_KEYCODE::F19), + F20 = static_cast(SHInputManager::SH_KEYCODE::F20), + F21 = static_cast(SHInputManager::SH_KEYCODE::F21), + F22 = static_cast(SHInputManager::SH_KEYCODE::F22), + F23 = static_cast(SHInputManager::SH_KEYCODE::F23), + F24 = static_cast(SHInputManager::SH_KEYCODE::F24), + Alpha0 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_0), + Alpha1 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_1), + Alpha2 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_2), + Alpha3 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_3), + Alpha4 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_4), + Alpha5 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_5), + Alpha6 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_6), + Alpha7 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_7), + Alpha8 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_8), + Alpha9 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_9), + //Exclaim + //DoubleQuote + //Hash + //Dollar + //Percent + //Ampersand + Quote = static_cast(SHInputManager::SH_KEYCODE::OEM_7), + //LeftParen + //RightParen + //Asterisk + //Plus + Comma = static_cast(SHInputManager::SH_KEYCODE::OEM_COMMA), + Minus = static_cast(SHInputManager::SH_KEYCODE::OEM_MINUS), + Period = static_cast(SHInputManager::SH_KEYCODE::OEM_PERIOD), + Slash = static_cast(SHInputManager::SH_KEYCODE::OEM_2), + //Colon + Semicolon = static_cast(SHInputManager::SH_KEYCODE::OEM_1), + //Less + Equals = static_cast(SHInputManager::SH_KEYCODE::OEM_PLUS), + //Greater + //Question + //At + LeftBracket = static_cast(SHInputManager::SH_KEYCODE::OEM_4), + Backslash = static_cast(SHInputManager::SH_KEYCODE::OEM_5), + RightBracket = static_cast(SHInputManager::SH_KEYCODE::OEM_6), + //Caret + //Underscore + BackQuote = static_cast(SHInputManager::SH_KEYCODE::OEM_3), + A = static_cast(SHInputManager::SH_KEYCODE::A), + B = static_cast(SHInputManager::SH_KEYCODE::B), + C = static_cast(SHInputManager::SH_KEYCODE::C), + D = static_cast(SHInputManager::SH_KEYCODE::D), + E = static_cast(SHInputManager::SH_KEYCODE::E), + F = static_cast(SHInputManager::SH_KEYCODE::F), + G = static_cast(SHInputManager::SH_KEYCODE::G), + H = static_cast(SHInputManager::SH_KEYCODE::H), + I = static_cast(SHInputManager::SH_KEYCODE::I), + J = static_cast(SHInputManager::SH_KEYCODE::J), + K = static_cast(SHInputManager::SH_KEYCODE::K), + L = static_cast(SHInputManager::SH_KEYCODE::L), + M = static_cast(SHInputManager::SH_KEYCODE::M), + N = static_cast(SHInputManager::SH_KEYCODE::N), + O = static_cast(SHInputManager::SH_KEYCODE::O), + P = static_cast(SHInputManager::SH_KEYCODE::P), + Q = static_cast(SHInputManager::SH_KEYCODE::Q), + R = static_cast(SHInputManager::SH_KEYCODE::R), + S = static_cast(SHInputManager::SH_KEYCODE::S), + T = static_cast(SHInputManager::SH_KEYCODE::T), + U = static_cast(SHInputManager::SH_KEYCODE::U), + V = static_cast(SHInputManager::SH_KEYCODE::V), + W = static_cast(SHInputManager::SH_KEYCODE::W), + X = static_cast(SHInputManager::SH_KEYCODE::X), + Y = static_cast(SHInputManager::SH_KEYCODE::Y), + Z = static_cast(SHInputManager::SH_KEYCODE::Z), + //LeftCurlyBracket + //Pipe + //RightCurlyBracket + //Tilde + NumLock = static_cast(SHInputManager::SH_KEYCODE::NUM_LOCK), + CapsLock = static_cast(SHInputManager::SH_KEYCODE::CAPS_LOCK), + ScrollLock = static_cast(SHInputManager::SH_KEYCODE::SCROLL_LOCK), + RightShift = static_cast(SHInputManager::SH_KEYCODE::RIGHT_SHIFT), + LeftShift = static_cast(SHInputManager::SH_KEYCODE::LEFT_SHIFT), + RightControl = static_cast(SHInputManager::SH_KEYCODE::RIGHT_CTRL), + LeftControl = static_cast(SHInputManager::SH_KEYCODE::LEFT_CTRL), + RightAlt = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ALT), + LeftAlt = static_cast(SHInputManager::SH_KEYCODE::LEFT_ALT), + LeftWindows = static_cast(SHInputManager::SH_KEYCODE::LEFT_WINDOWS), + RightWindows = static_cast(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS), + //AltGr + Help = static_cast(SHInputManager::SH_KEYCODE::HELP), + Print = static_cast(SHInputManager::SH_KEYCODE::PRINT), + SysReq = static_cast(SHInputManager::SH_KEYCODE::PRINT_SCREEN), + //Break + //Menu + //Mouse buttons use mouse codes, which are enums declared later + //TODO Controller input +#if 0 + Space = static_cast(SHInputManager::SH_KEYCODE::SPACE), //Apostrophe = static_cast(SHInputManager::SH_KEYCODE::APOSTROPHE), Comma = static_cast(SHInputManager::SH_KEYCODE::OEM_COMMA), Minus = static_cast(SHInputManager::SH_KEYCODE::OEM_MINUS), @@ -190,7 +339,8 @@ namespace SHADE JoystickButton6 = JoystickView, JoystickButton7 = JoystickMenu, JoystickButton8 = JoystickLeftStick, - JoystickButton9 = JoystickRightStick + JoystickButton9 = JoystickRightStick +#endif }; /// From 6e604fe7e9e93a1c4387d89b8d0f2b654898bce1 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 31 Oct 2022 23:18:20 +0800 Subject: [PATCH 36/57] Fixed bug with relative collider sizes --- SHADE_Application/src/Scenes/SBTestScene.cpp | 1 - .../Inspector/SHEditorComponentView.hpp | 2 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 26 +++++++++---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 23b57dfc..52f2dc7b 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -128,7 +128,6 @@ namespace Sandbox floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); auto* floorBox = floorCollider.AddBoundingBox(); - floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f); // Create blank entity with a script //testObj = SHADE::SHEntityManager::CreateEntity(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 521e1213..e3f93713 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -251,7 +251,7 @@ namespace SHADE SHEditorWidgets::DragVec3 ( "Half Extents", { "X", "Y", "Z" }, - [box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); }, + [box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); }, [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); } else if (collider->GetType() == SHCollider::Type::SPHERE) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 53db5453..053cda68 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -19,8 +19,9 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" #include "Math/SHMathHelpers.h" -#include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformComponent.h" +#include "Scene/SHSceneManager.h" +#include "Scripting/SHScriptEngine.h" namespace SHADE { @@ -325,38 +326,35 @@ namespace SHADE void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept { - auto* system = reinterpret_cast(GetSystem()); - fixedTimeStep = 1.0 / system->fixedDT; + auto* physicsSystem = reinterpret_cast(GetSystem()); + + fixedTimeStep = 1.0 / physicsSystem->fixedDT; accumulatedTime += dt; int count = 0; while (accumulatedTime > fixedTimeStep) { - system->world->update(static_cast(fixedTimeStep)); + physicsSystem->world->update(static_cast(fixedTimeStep)); accumulatedTime -= fixedTimeStep; ++count; } stats.numSteps = count; - system->worldUpdated = count > 0; + physicsSystem->worldUpdated = count > 0; - system->interpolationFactor = accumulatedTime / fixedTimeStep; + physicsSystem->interpolationFactor = accumulatedTime / fixedTimeStep; } void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept { - auto* system = reinterpret_cast(GetSystem()); + auto* physicsSystem = reinterpret_cast(GetSystem()); // Interpolate transforms for rendering - if (system->worldUpdated) - { - system->SyncTransforms(); + if (physicsSystem->worldUpdated) + physicsSystem->SyncTransforms(); - // TODO(Kah Wei): Take Collision & Trigger messages here - - system->ClearInvalidCollisions(); - } + physicsSystem->ClearInvalidCollisions(); } void SHPhysicsSystem::onContact(const CallbackData& callbackData) From e4cb8ede5af7e5336d84e3903403a1381b4eedcd Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 00:11:09 +0800 Subject: [PATCH 37/57] Added support for collision and trigger events in code properly --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 13 ++- SHADE_Managed/src/Scripts/ScriptStore.cxx | 108 ++++++++++--------- TempScriptsFolder/PhysicsTest.cs | 25 +++++ 3 files changed, 97 insertions(+), 49 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 53db5453..1d0cd10c 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -21,6 +21,7 @@ #include "Math/SHMathHelpers.h" #include "Scene/SHSceneManager.h" #include "Math/Transform/SHTransformComponent.h" +#include "Scripting/SHScriptEngine.h" namespace SHADE { @@ -353,7 +354,17 @@ namespace SHADE { system->SyncTransforms(); - // TODO(Kah Wei): Take Collision & Trigger messages here + // Collision & Trigger messages + auto scriptSys = SHSystemManager::GetSystem(); + if (scriptSys) + { + scriptSys->ExecuteFixedUpdates(); + scriptSys->ExecuteCollisionFunctions(); + } + else + { + SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!"); + } system->ClearInvalidCollisions(); } diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 48577f2c..407d0fa8 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -485,33 +485,39 @@ namespace SHADE const auto& collisions = SHPhysicsSystemInterface::GetCollisionInfo(); for (const auto& collisionInfo : collisions) { - const EntityID OWNER = collisionInfo.GetEntityA(); - - // Don't bother if this object has no scripts or is inactive - if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) - continue; - - // Construct the collision state object - CollisionInfo info; - info.GameObject = GameObject(OWNER); - - // Call all of the script's functions - auto entityScripts = scripts[OWNER]; - if (entityScripts->Count > 0) + auto entities = + { + std::make_pair(collisionInfo.GetEntityA(), collisionInfo.GetEntityB()), + std::make_pair(collisionInfo.GetEntityB(), collisionInfo.GetEntityA()) + }; + for (auto entity : entities) { - for each (Script^ script in entityScripts) + // Don't bother if this object has no scripts or is inactive + if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first)) + continue; + + // Construct the collision state object + CollisionInfo info; + info.GameObject = GameObject(entity.second); + + // Call all of the script's functions + auto entityScripts = scripts[entity.first]; + if (entityScripts->Count > 0) { - switch (collisionInfo.GetCollisionState()) + for each (Script ^ script in entityScripts) { - case SHCollisionEvent::State::ENTER: - script->OnCollisionEnter(info); - break; - case SHCollisionEvent::State::STAY: - script->OnCollisionStay(info); - break; - case SHCollisionEvent::State::EXIT: - script->OnCollisionExit(info); - break; + switch (collisionInfo.GetCollisionState()) + { + case SHCollisionEvent::State::ENTER: + script->OnCollisionEnter(info); + break; + case SHCollisionEvent::State::STAY: + script->OnCollisionStay(info); + break; + case SHCollisionEvent::State::EXIT: + script->OnCollisionExit(info); + break; + } } } } @@ -520,33 +526,39 @@ namespace SHADE const auto& triggers = SHPhysicsSystemInterface::GetTriggerInfo(); for (const auto& triggerInfo : triggers) { - const EntityID OWNER = triggerInfo.GetEntityA(); - - // Don't bother if this object has no scripts or is inactive - if (!isEntityActive(OWNER) || !scripts.ContainsKey(OWNER)) - continue; - - // Construct the collision state object - CollisionInfo info; - info.GameObject = GameObject(OWNER); - - // Call all of the script's functions - auto entityScripts = scripts[OWNER]; - if (entityScripts->Count > 0) + auto entities = + { + std::make_pair(triggerInfo.GetEntityA(), triggerInfo.GetEntityB()), + std::make_pair(triggerInfo.GetEntityB(), triggerInfo.GetEntityA()) + }; + for (auto entity : entities) { - for each (Script ^ script in entityScripts) + // Don't bother if this object has no scripts or is inactive + if (!isEntityActive(entity.first) || !scripts.ContainsKey(entity.first)) + continue; + + // Construct the collision state object + CollisionInfo info; + info.GameObject = GameObject(entity.second); + + // Call all of the script's functions + auto entityScripts = scripts[entity.first]; + if (entityScripts->Count > 0) { - switch (triggerInfo.GetCollisionState()) + for each (Script ^ script in entityScripts) { - case SHCollisionEvent::State::ENTER: - script->OnTriggerEnter(info); - break; - case SHCollisionEvent::State::STAY: - script->OnTriggerStay(info); - break; - case SHCollisionEvent::State::EXIT: - script->OnTriggerExit(info); - break; + switch (triggerInfo.GetCollisionState()) + { + case SHCollisionEvent::State::ENTER: + script->OnTriggerEnter(info); + break; + case SHCollisionEvent::State::STAY: + script->OnTriggerStay(info); + break; + case SHCollisionEvent::State::EXIT: + script->OnTriggerExit(info); + break; + } } } } diff --git a/TempScriptsFolder/PhysicsTest.cs b/TempScriptsFolder/PhysicsTest.cs index add5971d..5fe813b7 100644 --- a/TempScriptsFolder/PhysicsTest.cs +++ b/TempScriptsFolder/PhysicsTest.cs @@ -40,4 +40,29 @@ public class PhysicsTest : Script } Debug.Log($"{Transform.LocalPosition.y}"); } + + protected override void onCollisionEnter(CollisionInfo info) + { + Debug.Log($"Collision Enter: {info.GameObject.Name}"); + } + protected override void onCollisionStay(CollisionInfo info) + { + Debug.Log($"Collision Stay: {info.GameObject.Name}"); + } + protected override void onCollisionExit(CollisionInfo info) + { + Debug.Log($"Collision Exit: {info.GameObject.Name}"); + } + protected override void onTriggerEnter(CollisionInfo info) + { + Debug.Log($"Trigger Enter: {info.GameObject.Name}"); + } + protected override void onTriggerStay(CollisionInfo info) + { + Debug.Log($"Trigger Stay: {info.GameObject.Name}"); + } + protected override void onTriggerExit(CollisionInfo info) + { + Debug.Log($"Trigger Exit: {info.GameObject.Name}"); + } } \ No newline at end of file From 4e97392098540f4eb19ea40d8025c6e11274cf98 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 00:27:45 +0800 Subject: [PATCH 38/57] Added support for multiplying doubles with Vectors in C# --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 3 ++- SHADE_Managed/src/Math/Vector2.cxx | 16 ++++++++++++++++ SHADE_Managed/src/Math/Vector2.hxx | 16 ++++++++++++++++ SHADE_Managed/src/Math/Vector3.cxx | 18 ++++++++++++++++++ SHADE_Managed/src/Math/Vector3.hxx | 16 ++++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 0aee9706..e14b8baf 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -352,6 +352,7 @@ namespace SHADE // Interpolate transforms for rendering if (physicsSystem->worldUpdated) + { physicsSystem->SyncTransforms(); // Collision & Trigger messages @@ -366,7 +367,7 @@ namespace SHADE SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!"); } - system->ClearInvalidCollisions(); + physicsSystem->ClearInvalidCollisions(); } } diff --git a/SHADE_Managed/src/Math/Vector2.cxx b/SHADE_Managed/src/Math/Vector2.cxx index b110d4f8..42080d60 100644 --- a/SHADE_Managed/src/Math/Vector2.cxx +++ b/SHADE_Managed/src/Math/Vector2.cxx @@ -236,6 +236,22 @@ namespace SHADE lhs.y * rhs.y ); } + Vector2 Vector2::operator*(Vector2 lhs, double rhs) + { + return Vector2 + ( + lhs.x * static_cast(rhs), + lhs.y * static_cast(rhs) + ); + } + Vector2 Vector2::operator/(Vector2 lhs, double rhs) + { + return Vector2 + ( + lhs.x / static_cast(rhs), + lhs.y / static_cast(rhs) + ); + } Vector2 Vector2::operator*(Vector2 lhs, float rhs) { return Vector2 diff --git a/SHADE_Managed/src/Math/Vector2.hxx b/SHADE_Managed/src/Math/Vector2.hxx index 94b1989f..4877696b 100644 --- a/SHADE_Managed/src/Math/Vector2.hxx +++ b/SHADE_Managed/src/Math/Vector2.hxx @@ -361,6 +361,22 @@ namespace SHADE /// Vector2 to multiply with. /// Scalar to multiply with. /// The result of the scalar multiplication. + static Vector2 operator*(Vector2 lhs, double rhs); + /// + /// Calculates the division of a Vector2 with a scalar value and returns + /// the result. + /// + /// Scalar to divide with. + /// Vector2 to divide with. + /// The result of the scalar division. + static Vector2 operator/(Vector2 lhs, double rhs); + /// + /// Calculates the multiplication of a Vector2 with a scalar value and returns + /// the result. + /// + /// Vector2 to multiply with. + /// Scalar to multiply with. + /// The result of the scalar multiplication. static Vector2 operator*(Vector2 lhs, float rhs); /// /// Calculates the division of a Vector2 with a scalar value and returns diff --git a/SHADE_Managed/src/Math/Vector3.cxx b/SHADE_Managed/src/Math/Vector3.cxx index adbb4d3a..83adbb38 100644 --- a/SHADE_Managed/src/Math/Vector3.cxx +++ b/SHADE_Managed/src/Math/Vector3.cxx @@ -237,6 +237,24 @@ namespace SHADE lhs.z * rhs.z ); } + Vector3 Vector3::operator*(Vector3 lhs, double rhs) + { + return Vector3 + ( + lhs.x * static_cast(rhs), + lhs.y * static_cast(rhs), + lhs.z * static_cast(rhs) + ); + } + Vector3 Vector3::operator/(Vector3 lhs, double rhs) + { + return Vector3 + ( + lhs.x / static_cast(rhs), + lhs.y / static_cast(rhs), + lhs.z / static_cast(rhs) + ); + } Vector3 Vector3::operator*(Vector3 lhs, float rhs) { return Vector3 diff --git a/SHADE_Managed/src/Math/Vector3.hxx b/SHADE_Managed/src/Math/Vector3.hxx index 70cff88f..4cdf653e 100644 --- a/SHADE_Managed/src/Math/Vector3.hxx +++ b/SHADE_Managed/src/Math/Vector3.hxx @@ -375,6 +375,22 @@ namespace SHADE /// Vector3 to multiply with. /// Scalar to multiply with. /// The result of the scalar multiplication. + static Vector3 operator*(Vector3 lhs, double rhs); + /// + /// Calculates the division of a Vector3 with a scalar value and returns + /// the result. + /// + /// Scalar to divide with. + /// Vector3 to divide with. + /// The result of the scalar division. + static Vector3 operator/(Vector3 lhs, double rhs); + /// + /// Calculates the multiplication of a Vector3 with a scalar value and returns + /// the result. + /// + /// Vector3 to multiply with. + /// Scalar to multiply with. + /// The result of the scalar multiplication. static Vector3 operator*(Vector3 lhs, float rhs); /// /// Calculates the division of a Vector3 with a scalar value and returns From c08afcb804ff4d5d1e8586fb24f6d3ea39e050e6 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 00:37:09 +0800 Subject: [PATCH 39/57] Fixed incorrect FixedUpdate() execution and added Time.FixedDeltaTime --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 10 +++++++++- .../src/Physics/SHPhysicsSystemInterface.cpp | 12 ++++++++++++ SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h | 1 + SHADE_Managed/src/Engine/Time.cxx | 7 +++++++ SHADE_Managed/src/Engine/Time.hxx | 13 ++++++++----- TempScriptsFolder/PhysicsTest.cs | 5 +++++ 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index e14b8baf..91fc0674 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -327,6 +327,11 @@ namespace SHADE void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept { auto* physicsSystem = reinterpret_cast(GetSystem()); + auto scriptSys = SHSystemManager::GetSystem(); + if (!scriptSys) + { + SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!"); + } fixedTimeStep = 1.0 / physicsSystem->fixedDT; accumulatedTime += dt; @@ -334,6 +339,10 @@ namespace SHADE int count = 0; while (accumulatedTime > fixedTimeStep) { + if (scriptSys) + { + scriptSys->ExecuteFixedUpdates(); + } physicsSystem->world->update(static_cast(fixedTimeStep)); accumulatedTime -= fixedTimeStep; @@ -359,7 +368,6 @@ namespace SHADE auto scriptSys = SHSystemManager::GetSystem(); if (scriptSys) { - scriptSys->ExecuteFixedUpdates(); scriptSys->ExecuteCollisionFunctions(); } else diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp index 5343b9f1..4b292340 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp @@ -50,4 +50,16 @@ namespace SHADE SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get trigger events. Empty vector returned instead."); return emptyVec; } + + double SHPhysicsSystemInterface::GetFixedDT() noexcept + { + auto phySystem = SHSystemManager::GetSystem(); + if (phySystem) + { + return phySystem->GetFixedDT(); + } + + SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get fixed delta time. 0.0 returned instead."); + return 0.0; + } } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h index b1960a6f..da6a0433 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h @@ -41,5 +41,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ [[nodiscard]] static const std::vector& GetCollisionInfo() noexcept; [[nodiscard]] static const std::vector& GetTriggerInfo() noexcept; + [[nodiscard]] static double GetFixedDT() noexcept; }; } diff --git a/SHADE_Managed/src/Engine/Time.cxx b/SHADE_Managed/src/Engine/Time.cxx index ff0628e7..dfdec367 100644 --- a/SHADE_Managed/src/Engine/Time.cxx +++ b/SHADE_Managed/src/Engine/Time.cxx @@ -14,6 +14,9 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ // Precompiled Headers #include "SHpch.h" +// External Dependencies +#include "FRC/SHFramerateController.h" +#include "Physics/SHPhysicsSystemInterface.h" // Primary Header #include "Time.hxx" @@ -26,4 +29,8 @@ namespace SHADE { return SHFrameRateController::GetRawDeltaTime(); } + double Time::FixedDeltaTime::get() + { + return SHPhysicsSystemInterface::GetFixedDT(); + } } \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/Time.hxx b/SHADE_Managed/src/Engine/Time.hxx index 969eea03..774d85f0 100644 --- a/SHADE_Managed/src/Engine/Time.hxx +++ b/SHADE_Managed/src/Engine/Time.hxx @@ -14,8 +14,6 @@ of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once -#include "FRC/SHFramerateController.h" - namespace SHADE { /// @@ -29,13 +27,18 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /// /// Time taken to process the previous frame. - /// Note, is affected by TimeScale. Use UnscaledDeltaTime if you wish to retrieve - /// real world time. This is also affected by MaxDeltaTime clamping that - /// UnscaledDeltaTime is subject to. /// static property double DeltaTime { double get(); } + /// + /// Time taken for Physics simulations. You should use this for operations + /// within Script.FixedUpdate() + /// + static property double FixedDeltaTime + { + double get(); + } }; } \ No newline at end of file diff --git a/TempScriptsFolder/PhysicsTest.cs b/TempScriptsFolder/PhysicsTest.cs index 5fe813b7..c2f707cf 100644 --- a/TempScriptsFolder/PhysicsTest.cs +++ b/TempScriptsFolder/PhysicsTest.cs @@ -41,6 +41,11 @@ public class PhysicsTest : Script Debug.Log($"{Transform.LocalPosition.y}"); } + protected override void fixedUpdate() + { + Debug.Log("Fixed Update"); + } + protected override void onCollisionEnter(CollisionInfo info) { Debug.Log($"Collision Enter: {info.GameObject.Name}"); From 220e1a7d8b538221a6d2632db96e789d4c66059f Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 1 Nov 2022 00:44:37 +0800 Subject: [PATCH 40/57] Fixed asset creation broken logic loop --- .../src/Assets/Libraries/Loaders/SHTextBasedLoader.h | 4 ++++ SHADE_Engine/src/Assets/SHAssetManager.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h index 80771058..b74c6c94 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHTextBasedLoader.h @@ -11,6 +11,10 @@ #pragma once #include "SHAssetLoader.h" +#include "Assets/Asset Types/SHPrefabAsset.h" +#include "Assets/Asset Types/SHSceneAsset.h" +#include "Assets/Asset Types/SHMaterialAsset.h" + namespace SHADE { struct SHTextBasedLoader : SHAssetLoader diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 682eb9ec..d3076e6c 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -151,19 +151,26 @@ namespace SHADE ****************************************************************************/ AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept { + SHAssetData* data = nullptr; std::string newPath{ ASSET_ROOT }; switch (type) { case AssetType::PREFAB: newPath += PREFAB_FOLDER; + auto prefab = new SHPrefabAsset(); + data = prefab; break; case AssetType::SCENE: newPath += SCENE_FOLDER; + auto scene = new SHSceneAsset(); + data = scene; break; case AssetType::MATERIAL: newPath += MATERIAL_FOLDER; + auto material = new SHMaterialAsset(); + data = material; break; default: @@ -189,6 +196,8 @@ namespace SHADE ) }); + assetData.emplace(id, data); + return id; } From a8f5d021d3634fc34f3b6767acdbb9f47e724b7b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Tue, 1 Nov 2022 00:50:57 +0800 Subject: [PATCH 41/57] Switch case initialisation error fix --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index d3076e6c..4897fc42 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -157,20 +157,17 @@ namespace SHADE { case AssetType::PREFAB: newPath += PREFAB_FOLDER; - auto prefab = new SHPrefabAsset(); - data = prefab; + data = new SHPrefabAsset(); break; case AssetType::SCENE: newPath += SCENE_FOLDER; - auto scene = new SHSceneAsset(); - data = scene; + data = new SHSceneAsset(); break; case AssetType::MATERIAL: newPath += MATERIAL_FOLDER; - auto material = new SHMaterialAsset(); - data = material; + data = new SHMaterialAsset(); break; default: From b35ca86ae91b2f0bd3212e46dafcca331b1e72fe Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 00:53:15 +0800 Subject: [PATCH 42/57] BatcherDispatcher should now account for mesh changes properly --- .../src/Graphics/MiddleEnd/Batching/SHBatch.cpp | 11 +++++------ .../src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp | 6 +++--- .../Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 1bda7c90..22d1875b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -74,11 +74,12 @@ namespace SHADE void SHBatch::Remove(const SHRenderable* renderable) { - // Check if we have a SubBatch with the same mesh yet + // Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh) + Handle prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh(); auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch) - { - return batch.Mesh == renderable->GetMesh(); - }); + { + return batch.Mesh == prevSubBatchMesh; + }); // Attempt to remove if it exists if (subBatch == subBatches.end()) @@ -88,9 +89,7 @@ namespace SHADE // Check if other renderables in subBatches contain the same material instance bool matUnused = true; - Handle matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial(); - for (const auto& sb : subBatches) { // Check material usage diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 434e7163..df389879 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -37,9 +37,9 @@ namespace SHADE // Check if we have a batch with the same pipeline first auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); + { + return batch.GetPipeline() == PIPELINE; + }); // Create one if not found diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 97380fa3..16e2b1e8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -709,8 +709,8 @@ namespace SHADE if (!renderable.HasChanged()) continue; - // Remove from old material's SuperBatch - Handle prevMaterial = renderable.GetPrevMaterial(); + // Remove from the SuperBatch it is previously in (prevMat if mat has changed) + Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); if (prevMaterial) { Handle oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); From a9de63a0535d9d5fbbe614edbd59199e7d553f06 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 02:40:48 +0800 Subject: [PATCH 43/57] Simplified RigidBody Interface --- .../Components/SHRigidBodyComponent.cpp | 317 +++++++++++++----- .../Physics/Components/SHRigidBodyComponent.h | 31 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 94 ------ SHADE_Engine/src/Physics/SHPhysicsObject.h | 1 - SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 2 - 5 files changed, 245 insertions(+), 200 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index c1969557..369d26a5 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -18,6 +18,7 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/SHMathHelpers.h" #include "Physics/SHPhysicsSystem.h" namespace SHADE @@ -28,21 +29,9 @@ namespace SHADE SHRigidBodyComponent::SHRigidBodyComponent() noexcept : type { Type::DYNAMIC } - , flags { 0 } - , dirtyFlags { 0 } , interpolate { true } , rp3dBody { nullptr } - , mass { 1.0f } - , drag { 0.01f } - , angularDrag { 0.01f } - { - // Set default flags: Gravity & Sleeping enabled - flags |= 1U << 0; - flags |= 1U << 1; - - // Set all dirty flags to true - dirtyFlags = 1023; - } + {} /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ @@ -50,12 +39,24 @@ namespace SHADE bool SHRigidBodyComponent::IsGravityEnabled() const noexcept { - return flags & (1U << 0); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->isGravityEnabled(); } bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept { - return flags & (1U << 1); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->isAllowedToSleep(); } bool SHRigidBodyComponent::IsInterpolating() const noexcept @@ -70,67 +71,151 @@ namespace SHADE float SHRigidBodyComponent::GetMass() const noexcept { - return mass; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getMass(); } float SHRigidBodyComponent::GetDrag() const noexcept { - return drag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getLinearDamping(); } float SHRigidBodyComponent::GetAngularDrag() const noexcept { - return angularDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getAngularDamping(); } bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { - return flags & (1U << 2); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.x, 0.0f); } bool SHRigidBodyComponent::GetFreezePositionY() const noexcept { - return flags & (1U << 3); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.y, 0.0f); } bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept { - return flags & (1U << 4); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.z, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept { - return flags & (1U << 5); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.x, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept { - return flags & (1U << 6); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.y, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept { - return flags & (1U << 7); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f); } - const SHVec3& SHRigidBodyComponent::GetForce() const noexcept + SHVec3 SHRigidBodyComponent::GetForce() const noexcept { - return force; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->getForce(); } - const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept + SHVec3 SHRigidBodyComponent::GetTorque() const noexcept { - return torque; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getTorque(); } - const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept + SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept { - return linearVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getLinearVelocity(); } - const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept + SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept { - return angularVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getAngularVelocity(); } const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept @@ -157,8 +242,15 @@ namespace SHADE if (type == newType) return; - dirtyFlags |= 1U << 4; type = newType; + + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setType(static_cast(type)); } void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept @@ -171,8 +263,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << FLAG_POS; - enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->enableGravity(enableGravity); } void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept @@ -185,92 +282,127 @@ namespace SHADE return; } - dirtyFlags |= 1U << 1; - isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setIsAllowedToSleep(isAllowedToSleep); } void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept { - static constexpr int FLAG_POS = 2; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.x = freezePositionX ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept { - static constexpr int FLAG_POS = 3; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.y = freezePositionY ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept { - static constexpr int FLAG_POS = 4; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.z = freezePositionZ ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept { - static constexpr int FLAG_POS = 5; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.x = freezeRotationX ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept { - static constexpr int FLAG_POS = 6; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.y = freezeRotationY ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept { - static constexpr int FLAG_POS = 7; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.z = freezeRotationZ ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept @@ -283,11 +415,16 @@ namespace SHADE if (type != Type::DYNAMIC) { SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) - return; + return; } - dirtyFlags |= 1U << 5; - mass = newMass; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setMass(newMass); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept @@ -298,8 +435,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 6; - drag = newDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearDamping(newDrag); } void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept @@ -310,8 +452,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 7; - angularDrag = newAngularDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearDamping(newAngularDrag); } void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept @@ -322,8 +469,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 8; - linearVelocity = newLinearVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearVelocity(newLinearVelocity); } void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept @@ -334,8 +486,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 9; - angularVelocity = newAngularVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setAngularVelocity(newAngularVelocity); } /*-----------------------------------------------------------------------------------*/ @@ -346,7 +503,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -357,7 +514,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -368,7 +525,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -379,7 +536,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -390,7 +547,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -401,7 +558,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -412,7 +569,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -423,7 +580,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 3c5dd4f9..ba7d2dd9 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -94,10 +94,10 @@ namespace SHADE [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; - [[nodiscard]] const SHVec3& GetForce () const noexcept; - [[nodiscard]] const SHVec3& GetTorque () const noexcept; - [[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept; - [[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept; + [[nodiscard]] SHVec3 GetForce () const noexcept; + [[nodiscard]] SHVec3 GetTorque () const noexcept; + [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; + [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; [[nodiscard]] const SHVec3& GetPosition () const noexcept; [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; @@ -149,28 +149,13 @@ namespace SHADE static constexpr size_t NUM_FLAGS = 8; static constexpr size_t NUM_DIRTY_FLAGS = 16; - Type type; - - // rX rY rZ pX pY pZ slp g - uint8_t flags; - // 0 0 0 0 0 0 aV lV aD d m t ag lc slp g - uint16_t dirtyFlags; - bool interpolate; + Type type; + bool interpolate; reactphysics3d::RigidBody* rp3dBody; - float mass; - float drag; - float angularDrag; - - SHVec3 force; - SHVec3 linearVelocity; - - SHVec3 torque; - SHVec3 angularVelocity; - - SHVec3 position; - SHQuaternion orientation; + SHVec3 position; + SHQuaternion orientation; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 8b556409..c7c9f631 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -168,100 +168,6 @@ namespace SHADE rp3dBody->removeCollider(collider); } - void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept - { - SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") - - auto* rigidBody = reinterpret_cast(rp3dBody); - if (rb->dirtyFlags != 0) - { - const uint16_t RB_FLAGS = rb->dirtyFlags; - for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) - { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) - { - switch (i) - { - case 0: // Gravity - { - rigidBody->enableGravity(rb->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - const rp3d::Vector3 CONSTRAINTS - { - rb->flags & 1U << 2 ? 0.0f : 1.0f, - rb->flags & 1U << 3 ? 0.0f : 1.0f, - rb->flags & 1U << 4 ? 0.0f : 1.0f - }; - - - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); - break; - } - case 3: // Angular Constraints - { - const rp3d::Vector3 CONSTRAINTS - { - rb->flags & 1U << 5 ? 0.0f : 1.0f, - rb->flags & 1U << 6 ? 0.0f : 1.0f, - rb->flags & 1U << 7 ? 0.0f : 1.0f - }; - - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); - break; - } - case 4: // Type - { - rigidBody->setType(static_cast(rb->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(rb->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(rb->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(rb->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(rb->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(rb->GetAngularVelocity()); - break; - } - default: break; - } - } - } - - rb->dirtyFlags = 0; - } - else - { - rb->linearVelocity = rigidBody->getLinearVelocity(); - rb->angularVelocity = rigidBody->getAngularVelocity(); - } - } - void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { int index = 0; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 67e5ec64..64caacdb 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -72,7 +72,6 @@ namespace SHADE int AddCollider (SHCollider* collider); void RemoveCollider (int index); - void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; void SyncColliders (SHColliderComponent* c) const noexcept; private: diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 053cda68..de63f029 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -305,8 +305,6 @@ namespace SHADE if (!COMPONENT_ACTIVE) continue; - - physicsObject.SyncRigidBody(rigidBodyComponent); } // Sync colliders From da690e4395a40ad7b53a120efaa1716dcdfa0d0e Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 02:40:48 +0800 Subject: [PATCH 44/57] Simplified RigidBody Implementation --- .../Components/SHRigidBodyComponent.cpp | 317 +++++++++++++----- .../Physics/Components/SHRigidBodyComponent.h | 31 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 94 ------ SHADE_Engine/src/Physics/SHPhysicsObject.h | 1 - SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 2 - 5 files changed, 245 insertions(+), 200 deletions(-) diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index c1969557..369d26a5 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -18,6 +18,7 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" +#include "Math/SHMathHelpers.h" #include "Physics/SHPhysicsSystem.h" namespace SHADE @@ -28,21 +29,9 @@ namespace SHADE SHRigidBodyComponent::SHRigidBodyComponent() noexcept : type { Type::DYNAMIC } - , flags { 0 } - , dirtyFlags { 0 } , interpolate { true } , rp3dBody { nullptr } - , mass { 1.0f } - , drag { 0.01f } - , angularDrag { 0.01f } - { - // Set default flags: Gravity & Sleeping enabled - flags |= 1U << 0; - flags |= 1U << 1; - - // Set all dirty flags to true - dirtyFlags = 1023; - } + {} /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ @@ -50,12 +39,24 @@ namespace SHADE bool SHRigidBodyComponent::IsGravityEnabled() const noexcept { - return flags & (1U << 0); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->isGravityEnabled(); } bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept { - return flags & (1U << 1); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->isAllowedToSleep(); } bool SHRigidBodyComponent::IsInterpolating() const noexcept @@ -70,67 +71,151 @@ namespace SHADE float SHRigidBodyComponent::GetMass() const noexcept { - return mass; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getMass(); } float SHRigidBodyComponent::GetDrag() const noexcept { - return drag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getLinearDamping(); } float SHRigidBodyComponent::GetAngularDrag() const noexcept { - return angularDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return 0.0f; + } + + return rp3dBody->getAngularDamping(); } bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { - return flags & (1U << 2); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.x, 0.0f); } bool SHRigidBodyComponent::GetFreezePositionY() const noexcept { - return flags & (1U << 3); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.y, 0.0f); } bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept { - return flags & (1U << 4); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor(); + return SHMath::CompareFloat(LINEAR_CONSTRAINTS.z, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept { - return flags & (1U << 5); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.x, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept { - return flags & (1U << 6); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.y, 0.0f); } bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept { - return flags & (1U << 7); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor(); + return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f); } - const SHVec3& SHRigidBodyComponent::GetForce() const noexcept + SHVec3 SHRigidBodyComponent::GetForce() const noexcept { - return force; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return false; + } + + return rp3dBody->getForce(); } - const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept + SHVec3 SHRigidBodyComponent::GetTorque() const noexcept { - return torque; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getTorque(); } - const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept + SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept { - return linearVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getLinearVelocity(); } - const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept + SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept { - return angularVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return SHVec3::Zero; + } + + return rp3dBody->getAngularVelocity(); } const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept @@ -157,8 +242,15 @@ namespace SHADE if (type == newType) return; - dirtyFlags |= 1U << 4; type = newType; + + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setType(static_cast(type)); } void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept @@ -171,8 +263,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << FLAG_POS; - enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->enableGravity(enableGravity); } void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept @@ -185,92 +282,127 @@ namespace SHADE return; } - dirtyFlags |= 1U << 1; - isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setIsAllowedToSleep(isAllowedToSleep); } void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept { - static constexpr int FLAG_POS = 2; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.x = freezePositionX ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept { - static constexpr int FLAG_POS = 3; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.y = freezePositionY ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept { - static constexpr int FLAG_POS = 4; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 2; - freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto linearConstraints = rp3dBody->getLinearLockAxisFactor(); + linearConstraints.z = freezePositionZ ? 0.0f : 1.0f; + rp3dBody->setLinearLockAxisFactor(linearConstraints); } void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept { - static constexpr int FLAG_POS = 5; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.x = freezeRotationX ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept { - static constexpr int FLAG_POS = 6; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.y = freezeRotationY ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept { - static constexpr int FLAG_POS = 7; - if (type == Type::STATIC) { SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID()) return; } - dirtyFlags |= 1U << 3; - freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS); + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + auto angularConstraints = rp3dBody->getAngularLockAxisFactor(); + angularConstraints.z = freezeRotationZ ? 0.0f : 1.0f; + rp3dBody->setAngularLockAxisFactor(angularConstraints); } void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept @@ -283,11 +415,16 @@ namespace SHADE if (type != Type::DYNAMIC) { SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) - return; + return; } - dirtyFlags |= 1U << 5; - mass = newMass; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setMass(newMass); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept @@ -298,8 +435,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 6; - drag = newDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearDamping(newDrag); } void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept @@ -310,8 +452,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 7; - angularDrag = newAngularDrag; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearDamping(newAngularDrag); } void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept @@ -322,8 +469,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 8; - linearVelocity = newLinearVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setLinearVelocity(newLinearVelocity); } void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept @@ -334,8 +486,13 @@ namespace SHADE return; } - dirtyFlags |= 1U << 9; - angularVelocity = newAngularVelocity; + if (rp3dBody == nullptr) + { + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) + return; + } + + rp3dBody->setAngularVelocity(newAngularVelocity); } /*-----------------------------------------------------------------------------------*/ @@ -346,7 +503,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -357,7 +514,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -368,7 +525,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -379,7 +536,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -390,7 +547,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -401,7 +558,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -412,7 +569,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } @@ -423,7 +580,7 @@ namespace SHADE { if (rp3dBody == nullptr) { - SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID()) + SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID()) return; } diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 3c5dd4f9..ba7d2dd9 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -94,10 +94,10 @@ namespace SHADE [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; - [[nodiscard]] const SHVec3& GetForce () const noexcept; - [[nodiscard]] const SHVec3& GetTorque () const noexcept; - [[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept; - [[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept; + [[nodiscard]] SHVec3 GetForce () const noexcept; + [[nodiscard]] SHVec3 GetTorque () const noexcept; + [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; + [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; [[nodiscard]] const SHVec3& GetPosition () const noexcept; [[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; @@ -149,28 +149,13 @@ namespace SHADE static constexpr size_t NUM_FLAGS = 8; static constexpr size_t NUM_DIRTY_FLAGS = 16; - Type type; - - // rX rY rZ pX pY pZ slp g - uint8_t flags; - // 0 0 0 0 0 0 aV lV aD d m t ag lc slp g - uint16_t dirtyFlags; - bool interpolate; + Type type; + bool interpolate; reactphysics3d::RigidBody* rp3dBody; - float mass; - float drag; - float angularDrag; - - SHVec3 force; - SHVec3 linearVelocity; - - SHVec3 torque; - SHVec3 angularVelocity; - - SHVec3 position; - SHQuaternion orientation; + SHVec3 position; + SHQuaternion orientation; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 8b556409..c7c9f631 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -168,100 +168,6 @@ namespace SHADE rp3dBody->removeCollider(collider); } - void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept - { - SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!") - - auto* rigidBody = reinterpret_cast(rp3dBody); - if (rb->dirtyFlags != 0) - { - const uint16_t RB_FLAGS = rb->dirtyFlags; - for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i) - { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) - { - switch (i) - { - case 0: // Gravity - { - rigidBody->enableGravity(rb->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - const rp3d::Vector3 CONSTRAINTS - { - rb->flags & 1U << 2 ? 0.0f : 1.0f, - rb->flags & 1U << 3 ? 0.0f : 1.0f, - rb->flags & 1U << 4 ? 0.0f : 1.0f - }; - - - rigidBody->setLinearLockAxisFactor(CONSTRAINTS); - break; - } - case 3: // Angular Constraints - { - const rp3d::Vector3 CONSTRAINTS - { - rb->flags & 1U << 5 ? 0.0f : 1.0f, - rb->flags & 1U << 6 ? 0.0f : 1.0f, - rb->flags & 1U << 7 ? 0.0f : 1.0f - }; - - rigidBody->setAngularLockAxisFactor(CONSTRAINTS); - break; - } - case 4: // Type - { - rigidBody->setType(static_cast(rb->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(rb->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(rb->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(rb->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(rb->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(rb->GetAngularVelocity()); - break; - } - default: break; - } - } - } - - rb->dirtyFlags = 0; - } - else - { - rb->linearVelocity = rigidBody->getLinearVelocity(); - rb->angularVelocity = rigidBody->getAngularVelocity(); - } - } - void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { int index = 0; diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 67e5ec64..64caacdb 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -72,7 +72,6 @@ namespace SHADE int AddCollider (SHCollider* collider); void RemoveCollider (int index); - void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; void SyncColliders (SHColliderComponent* c) const noexcept; private: diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 053cda68..de63f029 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -305,8 +305,6 @@ namespace SHADE if (!COMPONENT_ACTIVE) continue; - - physicsObject.SyncRigidBody(rigidBodyComponent); } // Sync colliders From 68be65f3419b1e8bc4e4a631eff933930d880d89 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 14:08:47 +0800 Subject: [PATCH 45/57] Fixed bug where collisions were reported in the wrong state --- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 5 ----- SHADE_Engine/src/Physics/SHPhysicsSystem.hpp | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index f564dc2d..dd399f96 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -28,11 +28,6 @@ namespace SHADE { - /*-----------------------------------------------------------------------------------*/ - /* Concepts */ - /*-----------------------------------------------------------------------------------*/ - - /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp index 02569d14..957fb3aa 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.hpp @@ -42,6 +42,9 @@ namespace SHADE SHCollisionEvent cInfo; + // Update collision state + cInfo.collisionState = static_cast(cp.getEventType()); + // Match body and collider for collision event const rp3d::Entity body1 = cp.getBody1()->getEntity(); const rp3d::Entity body2 = cp.getBody2()->getEntity(); @@ -76,9 +79,6 @@ namespace SHADE return cInfo; } - // Update collision state - cInfo.collisionState = static_cast(cp.getEventType()); - return cInfo; } } // namespace SHADE \ No newline at end of file From d82bc8833fa26ae870f9c9c24a53809fb6a887d1 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Tue, 1 Nov 2022 14:20:03 +0800 Subject: [PATCH 46/57] Camera C# interface --- SHADE_Managed/Camera.cxx | 120 ++++++++++++++++++++++++++++++++ SHADE_Managed/Camera.hxx | 69 ++++++++++++++++++ TempScriptsFolder/CameraTest.cs | 9 +++ 3 files changed, 198 insertions(+) create mode 100644 SHADE_Managed/Camera.cxx create mode 100644 SHADE_Managed/Camera.hxx create mode 100644 TempScriptsFolder/CameraTest.cs diff --git a/SHADE_Managed/Camera.cxx b/SHADE_Managed/Camera.cxx new file mode 100644 index 00000000..f90e2bfe --- /dev/null +++ b/SHADE_Managed/Camera.cxx @@ -0,0 +1,120 @@ +#include "SHpch.h" + +#include "Camera.hxx" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Camera/SHCameraSystem.h" + + +namespace SHADE +{ + Camera::Camera(Entity entity) + :Component(entity) + { + + } + + + float Camera::Pitch::get() + { + return (GetNativeComponent()->GetPitch()); + } + + void Camera::Pitch::set(float val) + { + GetNativeComponent()->SetPitch(val); + } + float Camera::Yaw::get() + { + return (GetNativeComponent()->GetYaw()); + } + + void Camera::Yaw::set(float val) + { + GetNativeComponent()->SetYaw(val); + } + float Camera::Roll::get() + { + return (GetNativeComponent()->GetRoll()); + } + + void Camera::Roll::set(float val) + { + GetNativeComponent()->SetRoll(val); + } + float Camera::Width::get() + { + return (GetNativeComponent()->GetWidth()); + } + + void Camera::Width::set(float val) + { + GetNativeComponent()->SetWidth(val); + } + float Camera::Height::get() + { + return (GetNativeComponent()->GetHeight()); + } + + void Camera::Height::set(float val) + { + GetNativeComponent()->SetHeight(val); + } + float Camera::Near::get() + { + return (GetNativeComponent()->GetNear()); + } + + void Camera::Near::set(float val) + { + GetNativeComponent()->SetNear(val); + } + float Camera::Far::get() + { + return (GetNativeComponent()->GetFar()); + } + + void Camera::Far::set(float val) + { + GetNativeComponent()->SetFar(val); + } + float Camera::FOV::get() + { + return (GetNativeComponent()->GetFOV()); + } + + void Camera::FOV::set(float val) + { + GetNativeComponent()->SetFOV(val); + } + + Vector3 Camera::Position::get() + { + return Convert::ToCLI(GetNativeComponent()->GetPosition()); + } + + void Camera::Position::set(Vector3 val) + { + GetNativeComponent()->SetPosition(Convert::ToNative(val)); + } + + void Camera::SetMainCamera(size_t directorIndex) + { + auto system = SHSystemManager::GetSystem(); + system->SetMainCamera(GetNativeComponent()->GetEID(), directorIndex); + } + + void Camera::SetMainCamera() + { + SetMainCamera(0); + } + + void Camera::LookAt(Vector3 targetPosition) + { + auto system = SHSystemManager::GetSystem(); + system->CameraLookAt(*GetNativeComponent(), Convert::ToNative(targetPosition)); + } + + + + +} \ No newline at end of file diff --git a/SHADE_Managed/Camera.hxx b/SHADE_Managed/Camera.hxx new file mode 100644 index 00000000..e5a017b3 --- /dev/null +++ b/SHADE_Managed/Camera.hxx @@ -0,0 +1,69 @@ +#pragma once + +// Project Includes +#include "Components/Component.hxx" +#include "Math/Vector3.hxx" +#include "Math/Quaternion.hxx" +// External Dependencies +#include "Camera/SHCameraComponent.h" + +namespace SHADE +{ + public ref class Camera : public Component + { + internal: + Camera(Entity entity); + + public: + property float Pitch + { + float get(); + void set(float val); + } + property float Yaw + { + float get(); + void set(float val); + } + property float Roll + { + float get(); + void set(float val); + } + property float Width + { + float get(); + void set(float val); + } + property float Height + { + float get(); + void set(float val); + } + property float Near + { + float get(); + void set(float val); + } + property float Far + { + float get(); + void set(float val); + } + property float FOV + { + float get(); + void set(float val); + } + property Vector3 Position + { + Vector3 get(); + void set(Vector3 val); + } + + + void SetMainCamera(size_t directorIndex); + void SetMainCamera(); + void LookAt(Vector3 targetPosition); + }; +} \ No newline at end of file diff --git a/TempScriptsFolder/CameraTest.cs b/TempScriptsFolder/CameraTest.cs new file mode 100644 index 00000000..867f3dcc --- /dev/null +++ b/TempScriptsFolder/CameraTest.cs @@ -0,0 +1,9 @@ +using System; +using SHADE; + +namespace SHADE_Scripting +{ + class CameraTest :Script + { + } +} From d5cadfe8ed1c3903bc050909c6fe94dbdb30acf3 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Tue, 1 Nov 2022 14:21:43 +0800 Subject: [PATCH 47/57] Removed Component event now runs after the component has been removed from the sparse set --- .../ECS_Base/Managers/SHComponentManager.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp index 75a86f37..8a715a49 100644 --- a/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp +++ b/SHADE_Engine/src/ECS_Base/Managers/SHComponentManager.cpp @@ -33,19 +33,19 @@ namespace SHADE return; } + std::vector eventVec; + for (uint32_t i = 0; i < componentSet.Size(); ++i) { SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID)); if (comp) { comp->OnDestroy(); + SHComponentRemovedEvent eventData; + eventData.eid = entityID; + eventData.removedComponentType = i; + eventVec.push_back(eventData); } - SHComponentRemovedEvent eventData; - eventData.eid = entityID; - eventData.removedComponentType = i; - - SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); - } @@ -57,6 +57,12 @@ namespace SHADE componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID)); + for (auto& eventData : eventVec) + { + SHEventManager::BroadcastEvent(eventData, SH_COMPONENT_REMOVED_EVENT); + } + + //entityHandle.RemoveHandle(entityID); From 35771a619a3dddcd1d1b27040f89c2fc66b0b2a2 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 14:46:56 +0800 Subject: [PATCH 48/57] Adjusted for new component removal method --- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 24 +++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index e7eed326..b1248509 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -630,19 +630,17 @@ namespace SHADE auto* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); auto* colliderComponent = SHComponentManager::GetComponent_s(ENTITY_ID); - SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!") - - if (REMOVED_ID == RIGID_BODY_ID) + // Wake up all physics objects + for (auto& [entityID, object] : map) { - // Wake up all physics objects - for (auto& [entityID, object] : map) - { - if (SHComponentManager::HasComponent(entityID)) - reinterpret_cast(object.rp3dBody)->setIsSleeping(false); - } + if (SHComponentManager::HasComponent(entityID)) + reinterpret_cast(object.rp3dBody)->setIsSleeping(false); + } + if (REMOVED_ID == RIGID_BODY_ID && physicsObject != nullptr) + { world->destroyRigidBody(reinterpret_cast(physicsObject->rp3dBody)); - physicsObject->rp3dBody = nullptr; + physicsObject->rp3dBody = nullptr; if (colliderComponent != nullptr) { @@ -657,7 +655,7 @@ namespace SHADE } } - if (REMOVED_ID == COLLIDER_ID) + if (REMOVED_ID == COLLIDER_ID && physicsObject != nullptr) { // Remove all colliders const int NUM_COLLIDERS = static_cast(physicsObject->rp3dBody->getNbColliders()); @@ -673,8 +671,8 @@ namespace SHADE physicsObject->rp3dBody = nullptr; } - if (physicsObject->rp3dBody == nullptr) - DestroyPhysicsObject(ENTITY_ID); + if (physicsObject != nullptr && physicsObject->rp3dBody == nullptr) + DestroyPhysicsObject(ENTITY_ID); } return EVENT_DATA->handle; From e1587c7252c56f44258e4c8ba305064c77c6a8d4 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 14:56:03 +0800 Subject: [PATCH 49/57] Fixed SetMesh() not working and loading of mesh and textures --- .../Inspector/SHEditorComponentView.hpp | 1 + .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 17 ++++++-- .../src/Resource/SHResourceManager.cpp | 17 ++++++-- SHADE_Engine/src/Resource/SHResourceManager.h | 39 ++++++------------- .../src/Resource/SHResourceManager.hpp | 4 +- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index e3f93713..fdc94d1f 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -358,6 +358,7 @@ namespace SHADE [component](AssetID const& id) { component->SetMesh(SHResourceManager::LoadOrGet(id)); + SHResourceManager::FinaliseChanges(); }, SHDragDrop::DRAG_RESOURCE); } else diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 16e2b1e8..007c8639 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -106,10 +106,7 @@ namespace SHADE descPool = device->CreateDescriptorPools(); // Create generic command buffer - //transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); - transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // Load Built In Shaders static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); @@ -621,10 +618,14 @@ namespace SHADE void SHGraphicsSystem::BuildMeshBuffers() { + transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + device->WaitIdle(); transferCmdBuffer->BeginRecording(); meshLibrary.BuildBuffers(device, transferCmdBuffer); transferCmdBuffer->EndRecording(); graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); + device->WaitIdle(); + transferCmdBuffer.Free(); transferCmdBuffer = {}; } /*---------------------------------------------------------------------------------*/ @@ -649,10 +650,14 @@ namespace SHADE void SHGraphicsSystem::BuildTextures() { + graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + device->WaitIdle(); texLibrary.BuildTextures ( device, graphicsTexCmdBuffer, graphicsQueue, descPool ); + device->WaitIdle(); + graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {}; } #pragma endregion ADD_REMOVE @@ -692,6 +697,7 @@ namespace SHADE void SHGraphicsSystem::EndRoutine::Execute(double) noexcept { reinterpret_cast(system)->EndRender(); + SHResourceManager::FinaliseChanges(); } /*-----------------------------------------------------------------------------------*/ @@ -709,6 +715,11 @@ namespace SHADE if (!renderable.HasChanged()) continue; + if (!renderable.GetMesh()) + { + SHLOG_CRITICAL("NULL Mesh provided!"); + } + // Remove from the SuperBatch it is previously in (prevMat if mat has changed) Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); if (prevMaterial) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.cpp b/SHADE_Engine/src/Resource/SHResourceManager.cpp index 156c31c7..dad9fd9f 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.cpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.cpp @@ -21,9 +21,11 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHResourceHub SHResourceManager::resourceHub; std::unordered_map>> SHResourceManager::handlesMap; - std::unordered_map SHResourceManager::assetIdMap; + std::unordered_map SHResourceManager::assetIdMap; std::unordered_map> SHResourceManager::typedFreeFuncMap; std::vector SHResourceManager::loadedAssetData; + bool SHResourceManager::textureChanged = false; + bool SHResourceManager::meshChanged = false; /*-----------------------------------------------------------------------------------*/ /* Function Definitions */ @@ -63,8 +65,17 @@ namespace SHADE SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem(); if (gfxSystem == nullptr) throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed."); - gfxSystem->BuildMeshBuffers(); - gfxSystem->BuildTextures(); + + if (meshChanged) + { + gfxSystem->BuildMeshBuffers(); + meshChanged = false; + } + if (textureChanged) + { + gfxSystem->BuildTextures(); + textureChanged = false; + } // Free CPU Resources for (auto assetId : loadedAssetData) diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 61689420..e5e303e1 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -28,33 +28,15 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { + /// + /// Template structs that maps a resource to their loaded asset representation type. + /// template - struct SHResourceLoader - { - using AssetType = void; - }; - - template<> - struct SHResourceLoader - { - using AssetType = SHMeshAsset; - }; - template<> - struct SHResourceLoader - { - using AssetType = SHTextureAsset; - }; - template<> - struct SHResourceLoader - { - using AssetType = SHShaderAsset; - }; - template<> - struct SHResourceLoader - { - using AssetType = SHMaterialAsset; - }; - + struct SHResourceLoader { using AssetType = void; }; + template<> struct SHResourceLoader { using AssetType = SHMeshAsset; }; + template<> struct SHResourceLoader { using AssetType = SHTextureAsset; }; + template<> struct SHResourceLoader { using AssetType = SHShaderAsset; }; + template<> struct SHResourceLoader { using AssetType = SHMaterialAsset; }; /// /// Static class responsible for loading and caching runtime resources from their @@ -97,7 +79,7 @@ namespace SHADE /// Handle to the resource to unload. static void Unload(AssetID assetId); /// - /// Needs to be called to finalise all changes to loads. + /// Needs to be called to finalise all changes to loads, unless at runtime. /// static void FinaliseChanges(); @@ -147,6 +129,9 @@ namespace SHADE static std::unordered_map> typedFreeFuncMap; // Pointers to temp CPU resources static std::vector loadedAssetData; + // Dirty Flags + static bool meshChanged; + static bool textureChanged; /*---------------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 15834cdf..1623d70a 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -54,7 +54,7 @@ namespace SHADE } auto handle = load(assetId, *assetData); - Handle genericHandle = Handle(); + Handle genericHandle = Handle(handle); typedHandleMap.get().emplace(assetId, genericHandle); typedAssetIdMap.get().emplace(genericHandle, assetId); return handle; @@ -139,6 +139,7 @@ namespace SHADE if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); + meshChanged = true; return gfxSystem->AddMesh ( @@ -155,6 +156,7 @@ namespace SHADE else if constexpr (std::is_same_v) { loadedAssetData.emplace_back(assetId); + textureChanged = true; return gfxSystem->AddTexture ( From 4dcd60f23953698be8b07eab01e9107df383f391 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 15:10:47 +0800 Subject: [PATCH 50/57] Added rotation offsets to colliders --- .../Inspector/SHEditorComponentView.hpp | 21 ++++++++++++++++++- .../Math/Transform/SHTransformComponent.cpp | 6 +++--- SHADE_Engine/src/Physics/SHCollider.cpp | 15 ++++++++++++- SHADE_Engine/src/Physics/SHCollider.h | 5 ++++- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 8 ++++--- 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index e3f93713..6862aea4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -274,8 +274,27 @@ namespace SHADE } { - SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f }); + SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f }); SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); }); + SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, + [&collider] + { + auto offset = collider->GetRotationOffset(); + offset.x = SHMath::RadiansToDegrees(offset.x); + offset.y = SHMath::RadiansToDegrees(offset.y); + offset.z = SHMath::RadiansToDegrees(offset.z); + return offset; + }, + [&collider](SHVec3 const& vec) + { + const SHVec3 vecInRad + { + SHMath::DegreesToRadians(vec.x) + , SHMath::DegreesToRadians(vec.y) + , SHMath::DegreesToRadians(vec.z) + }; + collider->SetRotationOffset(vecInRad); + }); SHEditorWidgets::EndPanel(); } if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp index 43742855..fa0befa3 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformComponent.cpp @@ -185,7 +185,7 @@ RTTR_REGISTRATION using namespace rttr; registration::class_("Transform Component") - .property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate")) - .property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload(&SHTransformComponent::SetLocalRotation) ) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true)) - .property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale")); + .property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate")) + .property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload(&SHTransformComponent::SetLocalRotation)) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true)) + .property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale")); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollider.cpp index 9488042d..6cea3dc1 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollider.cpp @@ -17,6 +17,7 @@ #include "Math/Geometry/SHBoundingSphere.h" #include "Math/Transform/SHTransformComponent.h" #include "Math/SHMathHelpers.h" +#include "Reflection/SHReflectionMetadata.h" namespace SHADE { @@ -158,6 +159,11 @@ namespace SHADE return positionOffset; } + const SHVec3& SHCollider::GetRotationOffset() const noexcept + { + return rotationOffset; + } + SHShape* SHCollider::GetShape() noexcept { dirty = true; @@ -275,6 +281,12 @@ namespace SHADE } } + void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept + { + dirty = true; + rotationOffset = rotOffset; + } + /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -316,5 +328,6 @@ RTTR_REGISTRATION ); registration::class_("Collider") - .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset); + .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset) + .property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true)); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index 65e35698..8cc233c4 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -80,6 +80,7 @@ namespace SHADE [[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; + [[nodiscard]] const SHVec3& GetRotationOffset () const noexcept; [[nodiscard]] SHShape* GetShape () noexcept; @@ -96,7 +97,8 @@ namespace SHADE void SetDensity (float density) noexcept; void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept; - void SetPositionOffset (const SHVec3& posOffset) noexcept; + void SetPositionOffset (const SHVec3& posOffset) noexcept; + void SetRotationOffset (const SHVec3& rotOffset) noexcept; private: /*---------------------------------------------------------------------------------*/ @@ -110,6 +112,7 @@ namespace SHADE SHShape* shape; SHPhysicsMaterial material; SHVec3 positionOffset; + SHVec3 rotationOffset; /*---------------------------------------------------------------------------------*/ /* Function Members */ diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index c7c9f631..37c1269e 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -130,6 +130,8 @@ namespace SHADE int SHPhysicsObject::AddCollider(SHCollider* collider) { + const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() }; + switch (collider->GetType()) { case SHCollider::Type::BOX: @@ -137,7 +139,7 @@ namespace SHADE const auto* box = reinterpret_cast(collider->GetShape()); rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); - rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity }); + rp3dBody->addCollider(newBox, OFFSETS); break; } case SHCollider::Type::SPHERE: @@ -145,7 +147,7 @@ namespace SHADE const auto* sphere = reinterpret_cast(collider->GetShape()); rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius()); - rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity }); + rp3dBody->addCollider(newSphere, OFFSETS); break; } // TODO(Diren): Add more collider shapes @@ -182,7 +184,7 @@ namespace SHADE rp3dCollider->setIsTrigger(collider.IsTrigger()); // Update offsets - rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); + rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), collider.GetRotationOffset())); switch (collider.GetType()) { From 69e625014d98fee061863e1d2e50482ff475b058 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 15:25:19 +0800 Subject: [PATCH 51/57] Added EntityID retrieval from GameObject --- SHADE_Managed/src/Engine/GameObject.cxx | 4 ++++ SHADE_Managed/src/Engine/GameObject.hxx | 7 +++++++ TempScriptsFolder/PhysicsTest.cs | 1 - 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 55d53d68..f4c16f4f 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -72,6 +72,10 @@ namespace SHADE } return node->IsActive(); } + Entity GameObject::EntityId::get() + { + return entity; + } /*---------------------------------------------------------------------------------*/ /* GameObject Property Functions */ diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 723d9cec..8eaa67f3 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -86,6 +86,13 @@ namespace SHADE { bool get(); } + /// + /// Native Entity ID value for this GameObject. + /// + property Entity EntityId + { + Entity get(); + } /*-----------------------------------------------------------------------------*/ /* GameObject Property Functions */ diff --git a/TempScriptsFolder/PhysicsTest.cs b/TempScriptsFolder/PhysicsTest.cs index c2f707cf..cc01615d 100644 --- a/TempScriptsFolder/PhysicsTest.cs +++ b/TempScriptsFolder/PhysicsTest.cs @@ -38,7 +38,6 @@ public class PhysicsTest : Script RigidBody.AddForce(Force); Debug.Log($"Jump!"); } - Debug.Log($"{Transform.LocalPosition.y}"); } protected override void fixedUpdate() From 00ee8a4641c24b8f0e04094c2c9815e7f993ed41 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 15:29:12 +0800 Subject: [PATCH 52/57] Added compiled documentation for C# interfaces --- bin/Debug/SHADE_CSharp.xml | 1029 ++++++ bin/Debug/SHADE_Managed.xml | 6250 +++++++++++++++++++++++++++++++++ bin/Release/SHADE_CSharp.xml | 1029 ++++++ bin/Release/SHADE_Managed.xml | 6250 +++++++++++++++++++++++++++++++++ 4 files changed, 14558 insertions(+) create mode 100644 bin/Debug/SHADE_CSharp.xml create mode 100644 bin/Debug/SHADE_Managed.xml create mode 100644 bin/Release/SHADE_CSharp.xml create mode 100644 bin/Release/SHADE_Managed.xml diff --git a/bin/Debug/SHADE_CSharp.xml b/bin/Debug/SHADE_CSharp.xml new file mode 100644 index 00000000..daeaa3c5 --- /dev/null +++ b/bin/Debug/SHADE_CSharp.xml @@ -0,0 +1,1029 @@ + + + + SHADE_CSharp + + + + + Interface for a CallbackAction that all variants inherit from. + + + + + Whether or not this CallbackAction is runtime assigned. If it is, then the + TargetMethodName and TargetObject properties are invalid. + + + + + Name of the method that this CallbackAction is using. + + + + + Object which the specified target method is called on. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 1 parameter. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 2 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 3 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 4 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 5 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 6 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 7 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 8 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 9 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 10 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Interface for a CallbackEvent that all variants inherit from. + + + + + Registers an empty ICallbackAction. + + + + + Registers an ICallbackAction with the event such that it will be called in + future + + ICallbackAction to register with. + + + + Deregisters an ICallbackAction that was previously added. This should + only emit a warning if an action that was not previous added was + provided. + + ICallbackAction to remove. + + + + Iterable set of ICallbackActions that were registered to this event. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + diff --git a/bin/Debug/SHADE_Managed.xml b/bin/Debug/SHADE_Managed.xml new file mode 100644 index 00000000..7b653116 --- /dev/null +++ b/bin/Debug/SHADE_Managed.xml @@ -0,0 +1,6250 @@ + + + + "SHADE_Managed" + + + + +Retrieves the duration that the specified key has not been held or was last +not been held for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has been held or was last held +for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has not been held or was last +not been held for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has been held or was last held +for. + + The key to check. + Time in seconds that the key was held. + + + +Sets the position of the mouse cursor relative to the top left corner of the +window. + + +Position of the mouse in window pixel coordinates to set. + + + + +Checks if a specified mouse button is no longer pressed and was pressed +before. + + MouseCode of the mouse button to check. + +True during the frame the user releases the given mouse button. + + + + +Checks if a specified mouse button is pressed and was not pressed before. + + MouseCode of the mouse button to check. + +True during the frame the user pressed the given mouse button. + + + + +Checks if a specified mouse button is being held down. +This will also be true if GetMouseButtonDown() is true. + + MouseCode of the mouse button to check. + True while the user holds down the mouse button specified. + + + +Checks if a specified key is no longer pressed pressed and was pressed +before. + + KeyCode of the key to check. + +True during the frame the user releases the key identified by name. + + + + +Checks if a specified key is pressed and was not pressed before. + + KeyCode of the key to check. + +True during the frame the user starts pressing down the key specified. + + + + +Checks if a specified key is being held down. +This will also be true if GetKeyDown() is true. + + KeyCode of the key to check. + True while the user holds down the key specified. + + + +Amnount of vertical mouse scroll in this frame. + + + + +Mouse position in screen coordinates relative to the top left of the window. +This value is a Vector3 for compatibility with functions that have Vector3 +arguments. The z component of the Vector3 is always 0 + + + + +Represents the available supported mouse keycodes that can be passed into the +mouse-button-based Input functions. + + + + +Represents the available supported keycodes that can be passed into the +key-based Input functions. + +Attempting to follow https://docs.unity3d.com/ScriptReference/KeyCode.html +Win32 keycodes are shift-insensitive, i.e. 'A' and 'a' are the same keycode and '1' and '!' are the same keycode + + + + +Static class responsible for providing access to Input-related functionality. + + + + +Simple attribute to mark that a field in a Script should be serialised. + + + + +Cleans up all required components for managed code. + + + + +Reloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. +Equivalent to calling UnloadScriptAssembly() and then LoadScriptAssembly(). + + + + +Loads the managed script assembly. Ensure this is only called after +UnloadScriptAssembly() has been called. + + + + +Unloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Initialises all required components for managed code. + + + + +Name of the Managed Library that contains the C# scripts written externally. + + + + +Static class that contains the functions for interfacing with the core +PlushieEngine written in C++ for managing the lifecycle of managed code. + + + + +Default Constructor + + + + +Custom AssemblyLoadContext marked as collectible so that it can be unloaded. + + + + +Time taken for Physics simulations. You should use this for operations +within Script.FixedUpdate() + + + + +Time taken to process the previous frame. + + + + +Static class that contains the functions for working with time. + + + + +Static class that wraps up certain functions in the SHPhysicsSystem so that +accessing it from SHADE_Managed would not cause issues due to C++20 features. + + + + +Constructor for a Tooltip attribute that fills in the description. + + Text to be shown when a field is hovered. + + + +Description that is to be shown in the Tooltip. + + + + +Simple attribute to provide a field in a script with a tooltip. + + + + +Checks if a specified file exists. + + File path to the file to check. + True if the file exists + + + +Deletes the folder and all files in it as specified by the file path. + + File path to the file to delete. + + + +Deletes the file as specified by the file path. + + File path to the file to delete. + + + +Reads the file via the specified path that represents a build log of error +and warning messages. + + +File path to the build log of script builds done by BuildScriptAssembly() to +dump and process. + + + + +Registers events for the scripting system + + + + +Loads all the function pointers to CLR code that we need to execute. + + + + +Generates a .csproj file for editing and compiling the C# scripts. + + File path to the generated file. + + + +Utilises execution of a external batch file for invoking the dotnet build +tool to compile C# scripts in the Assets folder into the SHADE_Scripting +C# assembly DLL. + + +Whether or not a debug build will be built. Only debug built C# assemblies +can be debugged. + + +Whether or not we are reloading the assembly, if so, unload and then reload it. + + Whether or not the build succeeded. + + + +Performs a redo for script inspector changes if it exists. + + + + +Performs an undo for script inspector changes if it exists. + + + + +Renders the set of attached Scripts for the specified Entity into the +inspector. +
+This function is meant for consumption from native code in the inspector +rendering code. +
+ The Entity to render the Scripts of. +
+ + +Creates scripts and sets fields for the specified Entity based on the specified +YAML node. + + The Entity to deserialise a Script on to. + +YAML Node that contains the serialised script data. + + True if successfully deserialised. + + + +Performs serialization of all scripts for the specified entity into the +YAML::Node specified. This node will contain all serialised scripts after +calling this function. + + The Entity to Serialise. + +YAML Node that will store the serialised scripts. + + True if successfully serialised. + + + +Removes all Scripts attached to the specified Entity. Unlike +RemoveAllScripts(), this removes all the scripts immediately. +Does not do anything if the specified Entity is invalid or does not have any +Scripts attached. + + The entity to remove the scripts from. + +Whether or not to call OnDestroy on the scripts. This is ignored if not in +play mode. + + + + +Removes all Scripts attached to the specified Entity. Does not do anything +if the specified Entity is invalid or does not have any Scripts +attached. + + The entity to remove the scripts from. + + + +Adds a Script to a specified Entity. Note that while you can call this +multiple times on a specified Entity, it will work for all intents and +purposes but GetScript<T>() (C# only) currently only +gives you the first Script added of the specified type. + + The entity to add a script to. + Type name of the script to add. + +True if successfully added. False otherwise with the error logged to the +console. + + + + +Shuts down the DotNetRuntime. + + + + +Executes the OnCollision*()s and OnTrigger*()s of the Scripts that are attached +to Entities. + + + + +Executes the FixedUpdate()s of the Scripts that are attached to +Entities. + + + + +Reloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Unloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Loads the managed script assembly. Ensure this is only called after +UnloadScriptAssembly() has been called. + + + + +Initialises the DotNetRuntime and retrieves function pointers to all +functions on the CLR used to interface with the engine. + + + + +Manages initialisation of the DotNetRuntime and interfacing with CLR code written +and executed on .NET. + + + + +Deserialises a YAML node that contains a map of Scripts and copies the +deserialised data into the specified object if there are matching fields. + + +The JSON string that contains the data to copy into this Script object. + + The object to copy deserialised data into. + + + +Creates a JSON node that represents the specified object and its associated +serialisable fields. Public fields and fields marked with the SerialiseField +attribute will be serialised. + + The object to serialise. + + + +Checks if a specified field is a candidate for serialisation. This means that +the field is public or private with the [SerialiseField] attribute. + + The field to check. + +True if the specified field is a candidate for serialisation. + + + + +Retrieves a set of all non-static (instance) fields from a specified object. + + The object to get non-static fields from. + Immutable list of non-static fields. + + + +Contains useful static functions for working with Reflection. + + + +Converts the node to a YAML string. + + +Emits the node to the given output stream. + + +Emits the node to the given {@link Emitter}. If there is an error in writing, +{@link Emitter#good} will return false. + + + + Loads the input file as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + @throws {@link BadFile} if the file cannot be loaded. + + + + Loads the input stream as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input file as a single YAML document. + + @throws {@link ParserException} if it is malformed. + @throws {@link BadFile} if the file cannot be loaded. + + + + Loads the input stream as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + +Handles a "TAG" directive, which should be of the form 'handle prefix', +where 'handle' is converted to 'prefix' in the file. + + + +Handles a "YAML" directive, which should be of the form 'major.minor' (like +a version number). + + + +Reads any directives that are next in the queue, setting the internal +{@code m_pDirectives} state. + + + + Handles the next document by calling events on the {@code eventHandler}. + + @throw a ParserException on error. + @return false if there are no more documents + + + +Resets the parser with the given input stream. Any existing state is +erased. + + + +Evaluates to true if the parser has some valid input to be read. + + +Constructs a parser from the given input stream. The input stream must +live as long as the parser. + + + +Constructs an empty parser (with no input. + + +A parser turns a stream of bytes into one stream of "events" per YAML +document in the input stream. + + + + +Renders a context menu when right clicked for the scripts + + The Entity to render the Scripts of. + The Script to render the inspector for. + + + +Renders a field specified into the inspector. + + The field to render. + +The object that contains the data of the field to render. + + + + +Renders a single specified Script's inspector. + + The Entity to render the Scripts of. + The Script to render the inspector for. + +Indices used internally to differentiate each rendered Script +inspector. This is required to open and close each Script's inspector +independently from each other. + + + + +Redoes the last script inspector change if there is any. + + + + +Undoes the last script inspector change if there is any. + + + + +Renders a dropdown button that allows for the addition of PlushieScripts +onto the specified Entity. + + The Entity to add PlushieScripts to. + + + +Renders the set of attached Scripts for the specified Entity into the +inspector. +
+This function is meant for consumption from native code in the inspector +rendering code. +
+ The Entity to render the Scripts of. +
+ + +Static class for Editor-related functions + + + + +Processes a YAML node that contains a list of multiple scripts to be loaded +into the specified Entity. +

+This function should only be called from native unmanaged code. +
+ +The Entity to attach the deserialised Scripts to. + + +Pointer to the YAML::Node that contains serialized script data. + + +
+ + +Populates a YAML node with the scripts for a specified Entity. +

+This function should only be called from native unmanaged code. +
+ The Entity to Serialise. + +Pointer to a YAML::Node that will be populated with all of the serialised +scripts and their associated fields. + + +True if serialisation is successful. False if the buffer is too small for +the serialised output. + +
+ + +Executes OnCollision*() and OnTrigger*() for all scripts. + + + + +Executes LateUpdate() for all scripts. + + + + +Executes Update() for all scripts. + + + + +Executes FixedUpdate() for all scripts. + + + + +Retrieves a immutable list of available scripts that can be added. + + Immutable list of available scripts that can be added. + + + +Cleans up data stored in the ScriptStore to free up memory for garbage +collection. + + + + +Cleans up scripts that were marked for deletion. This calls the OnDestroy() +for these Scripts. + + + + +Sets up scripts that were marked for initialization. This calls the Awake() +and Start() for Scripts that have yet to have done so. + + + + +Initializes the ScriptStore to allocate and pre-populate reflection data. + + + + +Removes all Scripts attached to the specified Entity. Unlike +RemoveAllScripts(), this removes all the scripts immediately. +Does not do anything if the specified Entity is invalid or does not have any +Scripts attached. + + The entity to remove the scripts from. + +Whether or not to call OnDestroy on the scripts.This is ignored if not in +play mode. + + + + +Removes all Scripts attached to the specified Entity. Does not do anything +if the specified Entity is invalid or does not have any Scripts +attached. + + The entity to remove the scripts from. + + + +Removes a specific script from the + + The entity to remove the script from. + The script to remove. + True if successfully removed. False otherwise. + + + +Removes all Scripts of the specified type from the specified Entity. + + +Type of script to remove. +This needs to be a default constructable Script. + + The entity to remove the script from. + +If the specified Entity is invalid. + + + + +Retrieves an immutable list of all scripts attached to a specified Entity. + + +The entity which the scripts to retrieve are attached. + + +Immutable list of references to scripts attached to the specified Entity. +This can also be null if there are no scripts at all or an invalid Entity +was specified. + + + + +Retrieves a immutable list of scripts from the specified Entity that +matches the specified type. +
+Note that this function allocates. It should be used sparingly. +
+ +Type of scripts to get. +This needs to be a default constructable Script. + + +The entity which the scripts to retrieve are attached. + + +Immutable list of references to scripts of the specified type. + +
+ + +Retrieves the first Script from the specified Entity's children that matches +the specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + +The entity which the script to retrieve is attached. + + +Reference to the script. This can be null if no script of the specified +type is attached. + + +If the specified Entity is invalid. + + + + +Retrieves the first Script from the specified Entity that matches the +specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + +The entity which the script to retrieve is attached. + + +Reference to the script. This can be null if no script of the specified +type is attached. + + +If the specified Entity is invalid. + + + + +Adds a Script to a specified Entity. +
+This function is meant for consumption from native code or for serialisation +purposes. If you are writing in C# or C++/CLI and not doing serialisation, +use AddScript<T>() instead as it is faster. +
+ The entity to add a script to. + The entity to add a script to. + +Out parameter handle to the Script that was created. + + +True if successfully added. False otherwise with the error logged to the +console. + +
+ + +Adds a Script to a specified Entity. +
+This function is meant for consumption from native code. If you are writing +in C# or C++/CLI, use AddScript<T>() instead as it is faster. +
+ The entity to add a script to. + The entity to add a script to. + +True if successfully added. False otherwise with the error logged to the +console. + +
+ + +Adds a Script to a specified Entity. + + +Type of script to add. +This needs to be a default constructable PlushieScript. + + The entity to add a script to. + Reference to the script added. + +If the specified Entity is invalid. + + + + +Responsible for managing all scripts attached to Entities as well as executing +all lifecycle functions of scripts. + + + + +Checks if two Colors are not approximately equal. + + Color to compare. + Another Color to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Colors are approximately equal. + + Color to compare. + Another Color to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Color with a scalar value and returns +the result. + + Scalar to divide with. + Color to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Color with a scalar value and returns +the result. + + Color to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Colors and returns the +result. + + Color to multiply with. + Another Color to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Color from another Color and returns the result. + + Color to subtract from. + Another Color to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Colors together and returns the result. + + Color to add. + Another Color to add. + The result of lhs added to rhs + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Color, returned when t = 0.0. + The end Color, returned when t = 1.0. + Value used to interpolate between a and b. + The interpolated Color. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Color, returned when t = 0.0. + The end Color, returned when t = 1.0. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector3. + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Alpha component of the colour. Ranges from 0.0f to 1.0f. + + + + +Blue component of the colour. Ranges from 0.0f to 1.0f. + + + + +Green component of the colour. Ranges from 0.0f to 1.0f. + + + + +Red component of the colour. Ranges from 0.0f to 1.0f. + + + + +Constructor to construct a Color with the specified components. + + Red component to set. + Green component to set. + Blue component to set. + Alpha component to set. + + + +Constructor to construct a Color with the specified components with the +alpha component set to 1.0f. + + Red component to set. + Green component to set. + Blue component to set. + + + +Constructor to construct a Color with the specified components with the +blue and alpha component set to 1.0f. + + Red component to set. + Green component to set. + + + +Constructor to construct a Color with the specified components with the +green, blue and alpha component set to 1.0f. + + Red component to set. + + + +Pure yellow, mix of pure red and green. + + + + +Pure magenta, mix of pure red and blue. + + + + +Pure cyan, mix of pure green and blue. + + + + +Pure blue. + + + + +Pure green. + + + + +Pure red. + + + + +Pure white. + + + + +Dark Gray, darker than gray. + + + + +Gray, halfway between black and white. + + + + +Light Gray, lighter than gray. + + + + +Pure black. + + + + +A static class that contains a set of default Colors. + + + + +CLR version of the the SHADE Engine's Color struct which describes a Color +encoded using floating point numbers that range from 0.0f to 1.0f. + + + + +Creates a inline button widget. +
+Wraps up ImGui::Button(). +
+ Text to display. + True if button was pressed. +
+ + +Creates a small inline button widget. +
+Wraps up ImGui::SmallButton(). +
+ Text to display. + True if button was pressed. +
+ + +Creates a visual text widget. +
+Wraps up ImGui::Text(). +
+ Text to display. +
+ + +Creates a menu item in the list of items for a mini popup. +
+Wraps up ImGui::MenuItem(). +
+ Label used to identify this widget. + Whether or not the menu item was selected. +
+ + +Opens the popup that was defined with the specified label. +
+Wraps up ImGui::OpenPopup(). +
+
+ + +Marks the end of a definition of a mini pop up that can show options. +
+Wraps up ImGui::EndPopup(). +
+
+ + +Marks the start of a definition of a mini pop up that can show options. +
+Wraps up ImGui::BeginPopup(). +
+ Label used to identify this widget. + Whether or not the pop up is open. +
+ + +Creates a collapsing title header. +
+Wraps up ImGui::CollapsingHeader(). +
+ Label for the header. + True if the header is open, false otherwise. +
+ + +Unindents the widgets rendered after this call. +
+Wraps up ImGui::Unindent(). +
+
+ + +Indents the widgets rendered after this call. +
+Wraps up ImGui::Indent(). +
+
+ + +Marks the end of a stack of ImGui widgets from the last PushID() call. +
+Wraps up ImGui::PopID(). +
+
+ + +Marks the start of a stack of ImGui widgets with the specified id. +
+Wraps up ImGui::PushID(). +
+ Integer-based ID. +
+ + +Marks the start of a stack of ImGui widgets with the specified id. +
+Wraps up ImGui::PushID(). +
+ String-based ID. +
+ + +Maximum length of a string supported by InputTextField() + + + + +Static class that contains useful functions for Editor UI using ImGui. + + + + +Redoes the last undo-ed command if it exists. + + + + +Undos the last added command if it exists. + + + + +Adds a command onto the stack. + + + + + +True if there is a redoable action in the stack. + + + + +True if there is an undoable action in the stack. + + + + +Command for the stack that represents a data modification. + + + + +Class that is able to store a stack of actions that can be done and redone. + + + + +To be called from native code when a Collision Shape has been changed. + + +The entity which has it's collision shape changed. + + + + +To be called from native code when a collision shape has been removed. + + The entity which has it's collision shape removed. + + + +Retrieves a ColliderBound at the specified index in the ColliderBound list +and casts it to the appropriate type. + + Type of the ColliderBound to cast to. + Index to retrieve a ColliderBound from. + ColliderBound for the specified index. + + + +Retrieves a ColliderBound at the specified index in the ColliderBound list. + + Index to retrieve a ColliderBound from. + ColliderBound for the specified index. + + + +Total number of ColliderShapes in the Collider component. + + + + +Constructs a Collider Component that represents a native SHColliderComponent +component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the the SHADE Engine's SHColliderComponent. +A single Collider component can contain one or multiple Collider Bounds. + + + + + + + + + + +Radius of the Bounding Sphere formed by this bound. + + + + +Center of the Bounding Sphere formed by this bound. + + + + +Sphere-shaped Collider Bound. + + + + + + + + + + +Position of the top right front corner of the Bounding Box formed by this +bound. + + + + +Position of the bottom left back corner of the Bounding Box formed by this +bound. + + + + +Half of the scale of the Bounding Box formed by this bound. + + + + +Center of the Bounding Box formed by this bound. + + + + +Box-shaped Collider Bound. + + + + +Computes a Raycast and checks if there is a collision with any object. + + The ray to cast. + Maximum distance for the raycast check. + True if the ray intersects with an object in the scene. + + + +Checks if the specified point is within this shape's bounds. + + Point to test with. + True if the point is in the shape's bounds. + + + +Base interface for all Collider Shapes. + + + +@brief The density of the collider that determines the mass of the collision shape + if it is automatically computed. Must be a positive number. + + + +@brief The bounciness factor of the physics object., clamped between [0,1].
+ 0 means the object will never bounce. + 1 means the object never loses energy on a bounce. + +
+ +@brief The friction coefficient of the physics object., clamped between [0,1].
+ 0 means the object will never experience friction. + 1 means the friction force against the object is equal to the applied force. + +
+ +@brief Sets the mass density of the physics material. +@param newDensity The density value to set. Always made positive. + + + +@brief Sets the bounciness factor of the physics material. +@param newBounciness The bounciness value to set. Clamped between [0,1]. + + + +@brief Sets the friction coefficient of the physics material. +@param newFriction The friction value to set. Clamped between [0,1]. + + + +@brief Default constructor for a physics material. +@param friction The friction of the material. Clamped between [0,1]. Defaults to 0.4. +@param bounciness The bounciness of the material. Clamped between [0,1]. +@param density The mass density of the material. Always made positive. + + + + +Closes the current window, and depending on the implementation, should also +close the application. + + + + +Retrieves the current window fullscreen status. + + The current window fullscreen status.. + + + +Retrieves the current window height. + + The current window height. + + + +Retrieves the current window width. + + The current window width. + + + +Static class that wraps up certain functions in the SHGraphicsSystem so that +accessing it from SHADE_Managed would not cause issues due to C++20 features. + + + + @brief Perform ImGui and ImGui Backend Render + + + + + @brief Start new frame for editor + + + + + @brief Initialise Backend for ImGui (SDL and Vulkan backend) + + @param sdlWindow Pointer to SDL_Window + + + + @brief Set the Style for the editor + + @param style Desired style + + + + @brief Safely shutdown the editor + + + + + @brief Update the editor and add to ImGui DrawList + + @param dt Delta-time of the frame + + + + @brief Initialise the editor + + @param sdlWindow pointer to SDL_Window object created in application + + + + @brief Style options + + + + + @brief SHEditor static class contains editor variables and implementation of editor functions. + + + + + Get the YUV conversion mode, returning the correct mode for the resolution + when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + + \since This function is available since SDL 2.0.8. + + + + Get the YUV conversion mode + + \since This function is available since SDL 2.0.8. + + + + Set the YUV conversion mode + + \since This function is available since SDL 2.0.8. + + + + Perform low-level surface scaled blitting only. + + This is a semi-private function and it performs low-level surface blitting, + assuming the input rectangles have already been clipped. + + \param src the SDL_Surface structure to be copied from + \param srcrect the SDL_Rect structure representing the rectangle to be + copied + \param dst the SDL_Surface structure that is the blit target + \param dstrect the SDL_Rect structure representing the rectangle that is + copied into + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitScaled + + + + Perform a scaled surface copy to a destination surface. + + SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is + merely a macro for this function with a less confusing name. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitScaled + + + + Perform bilinear scaling between two surfaces of the same format, 32BPP. + + \since This function is available since SDL 2.0.16. + + + + Perform a fast, low quality, stretch blit between two surfaces of the same + format. + + Please use SDL_BlitScaled() instead. + + \since This function is available since SDL 2.0.0. + + + + Perform low-level surface blitting only. + + This is a semi-private blit function and it performs low-level surface + blitting, assuming the input rectangles have already been clipped. + + Unless you know what you're doing, you should be using SDL_BlitSurface() + instead. + + \param src the SDL_Surface structure to be copied from + \param srcrect the SDL_Rect structure representing the rectangle to be + copied, or NULL to copy the entire surface + \param dst the SDL_Surface structure that is the blit target + \param dstrect the SDL_Rect structure representing the rectangle that is + copied into + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + + + + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \returns 0 if the blit is successful, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + + Perform a fast blit from the source surface to the destination surface. + + SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a + macro for this function with a less confusing name. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + + + + Perform a fast fill of a set of rectangles with a specific color. + + `color` should be a pixel of the format used by the surface, and can be + generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + alpha component then the destination is simply filled with that alpha + information, no blending takes place. + + If there is a clip rectangle set on the destination (set via + SDL_SetClipRect()), then this function will fill based on the intersection + of the clip rectangle and `rect`. + + \param dst the SDL_Surface structure that is the drawing target + \param rects an array of SDL_Rects representing the rectangles to fill. + \param count the number of rectangles in the array + \param color the color to fill with + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FillRect + + + + Perform a fast fill of a rectangle with a specific color. + + `color` should be a pixel of the format used by the surface, and can be + generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + alpha component then the destination is simply filled with that alpha + information, no blending takes place. + + If there is a clip rectangle set on the destination (set via + SDL_SetClipRect()), then this function will fill based on the intersection + of the clip rectangle and `rect`. + + \param dst the SDL_Surface structure that is the drawing target + \param rect the SDL_Rect structure representing the rectangle to fill, or + NULL to fill the entire surface + \param color the color to fill with + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FillRects + + + + Premultiply the alpha on a block of pixels. + + This is safe to use with src == dst, but not for other overlapping areas. + + This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. + + \param width the width of the block to convert, in pixels + \param height the height of the block to convert, in pixels + \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + \param src a pointer to the source pixels + \param src_pitch the pitch of the source pixels, in bytes + \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + \param dst a pointer to be filled in with premultiplied pixel data + \param dst_pitch the pitch of the destination pixels, in bytes + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.18. + + + + Copy a block of pixels of one format to another format. + + \param width the width of the block to copy, in pixels + \param height the height of the block to copy, in pixels + \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + \param src a pointer to the source pixels + \param src_pitch the pitch of the source pixels, in bytes + \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + \param dst a pointer to be filled in with new pixel data + \param dst_pitch the pitch of the destination pixels, in bytes + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + + + Copy an existing surface to a new surface of the specified format enum. + + This function operates just like SDL_ConvertSurface(), but accepts an + SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, + it might be easier to call but it doesn't have access to palette + information for the destination surface, in case that would be important. + + \param src the existing SDL_Surface structure to convert + \param pixel_format the SDL_PixelFormatEnum that the new surface is + optimized for + \param flags the flags are unused and should be set to 0; this is a + leftover from SDL 1.2's API + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + \sa SDL_ConvertSurface + \sa SDL_CreateRGBSurface + + + + Copy an existing surface to a new surface of the specified format. + + This function is used to optimize images for faster *repeat* blitting. This + is accomplished by converting the original and storing the result as a new + surface. The new, optimized surface can then be used as the source for + future blits, making them faster. + + \param src the existing SDL_Surface structure to convert + \param fmt the SDL_PixelFormat structure that the new surface is optimized + for + \param flags the flags are unused and should be set to 0; this is a + leftover from SDL 1.2's API + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + \sa SDL_ConvertSurfaceFormat + \sa SDL_CreateRGBSurface + + + + Get the clipping rectangle for a surface. + + When `surface` is the destination of a blit, only the area within the clip + rectangle is drawn into. + + \param surface the SDL_Surface structure representing the surface to be + clipped + \param rect an SDL_Rect structure filled in with the clipping rectangle for + the surface + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_SetClipRect + + + + Set the clipping rectangle for a surface. + + When `surface` is the destination of a blit, only the area within the clip + rectangle is drawn into. + + Note that blits are automatically clipped to the edges of the source and + destination surfaces. + + \param surface the SDL_Surface structure to be clipped + \param rect the SDL_Rect structure representing the clipping rectangle, or + NULL to disable clipping + \returns SDL_TRUE if the rectangle intersects the surface, otherwise + SDL_FALSE and blits will be completely clipped. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_GetClipRect + + + + Get the blend mode used for blit operations. + + \param surface the SDL_Surface structure to query + \param blendMode a pointer filled in with the current SDL_BlendMode + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_SetSurfaceBlendMode + + + + Set the blend mode used for blit operations. + + To copy a surface to another surface (or texture) without blending with the + existing data, the blendmode of the SOURCE surface should be set to + `SDL_BLENDMODE_NONE`. + + \param surface the SDL_Surface structure to update + \param blendMode the SDL_BlendMode to use for blit blending + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceBlendMode + + + + Get the additional alpha value used in blit operations. + + \param surface the SDL_Surface structure to query + \param alpha a pointer filled in with the current alpha value + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceColorMod + \sa SDL_SetSurfaceAlphaMod + + + + Set an additional alpha value used in blit operations. + + When this surface is blitted, during the blit operation the source alpha + value is modulated by this alpha value according to the following formula: + + `srcA = srcA * (alpha / 255)` + + \param surface the SDL_Surface structure to update + \param alpha the alpha value multiplied into blit operations + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceAlphaMod + \sa SDL_SetSurfaceColorMod + + + + Get the additional color value multiplied into blit operations. + + \param surface the SDL_Surface structure to query + \param r a pointer filled in with the current red color value + \param g a pointer filled in with the current green color value + \param b a pointer filled in with the current blue color value + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceAlphaMod + \sa SDL_SetSurfaceColorMod + + + + Set an additional color value multiplied into blit operations. + + When this surface is blitted, during the blit operation each source color + channel is modulated by the appropriate color value according to the + following formula: + + `srcC = srcC * (color / 255)` + + \param surface the SDL_Surface structure to update + \param r the red color value multiplied into blit operations + \param g the green color value multiplied into blit operations + \param b the blue color value multiplied into blit operations + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceColorMod + \sa SDL_SetSurfaceAlphaMod + + + + Get the color key (transparent pixel) for a surface. + + The color key is a pixel of the format used by the surface, as generated by + SDL_MapRGB(). + + If the surface doesn't have color key enabled this function returns -1. + + \param surface the SDL_Surface structure to query + \param key a pointer filled in with the transparent pixel + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_SetColorKey + + + + Returns whether the surface has a color key + + It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + + \param surface the SDL_Surface structure to query + \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.9. + + \sa SDL_SetColorKey + \sa SDL_GetColorKey + + + + Set the color key (transparent pixel) in a surface. + + The color key defines a pixel value that will be treated as transparent in + a blit. For example, one can use this to specify that cyan pixels should be + considered transparent, and therefore not rendered. + + It is a pixel of the format used by the surface, as generated by + SDL_MapRGB(). + + RLE acceleration can substantially speed up blitting of images with large + horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. + + \param surface the SDL_Surface structure to update + \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key + \param key the transparent pixel + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_GetColorKey + + + + Returns whether the surface is RLE enabled + + It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + + \param surface the SDL_Surface structure to query + \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.14. + + \sa SDL_SetSurfaceRLE + + + + Save a surface to a file. + + Convenience macro. + + Set the RLE acceleration hint for a surface. + + If RLE is enabled, color key and alpha blending blits are much faster, but + the surface must be locked before directly accessing the pixels. + + \param surface the SDL_Surface structure to optimize + \param flag 0 to disable, non-zero to enable RLE acceleration + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_LockSurface + \sa SDL_UnlockSurface + + + + Load a surface from a file. + + Convenience macro. + + Save a surface to a seekable SDL data stream in BMP format. + + Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + BMP directly. Other RGB formats with 8-bit or higher get converted to a + 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + not supported. + + \param surface the SDL_Surface structure containing the image to be saved + \param dst a data stream to save to + \param freedst non-zero to close the stream after being written + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_LoadBMP_RW + \sa SDL_SaveBMP + + + + Load a BMP image from a seekable SDL data stream. + + The new surface should be freed with SDL_FreeSurface(). Not doing so will + result in a memory leak. + + src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. + Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap + from a file, convert it to an SDL_Surface and then close the file. + + \param src the data stream for the surface + \param freesrc non-zero to close the stream after being read + \returns a pointer to a new SDL_Surface structure or NULL if there was an + error; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeSurface + \sa SDL_RWFromFile + \sa SDL_LoadBMP + \sa SDL_SaveBMP_RW + + + + Release a surface after directly accessing the pixels. + + \param surface the SDL_Surface structure to be unlocked + + \since This function is available since SDL 2.0.0. + + \sa SDL_LockSurface + + + + Set up a surface for directly accessing the pixels. + + Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to + and read from `surface->pixels`, using the pixel format stored in + `surface->format`. Once you are done accessing the surface, you should use + SDL_UnlockSurface() to release it. + + Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to + 0, then you can read and write to the surface at any time, and the pixel + format of the surface will not change. + + \param surface the SDL_Surface structure to be locked + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_MUSTLOCK + \sa SDL_UnlockSurface + + + + Set the palette used by a surface. + + A single palette can be shared with many surfaces. + + \param surface the SDL_Surface structure to update + \param palette the SDL_Palette structure to use + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + + + Free an RGB surface. + + It is safe to pass NULL to this function. + + \param surface the SDL_Surface to free. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_LoadBMP + \sa SDL_LoadBMP_RW + + + + Allocate a new RGB surface with with a specific pixel format and existing + pixel data. + + This function operates mostly like SDL_CreateRGBSurfaceFrom(), except + instead of providing pixel color masks, you provide it with a predefined + format from SDL_PixelFormatEnum. + + No copy is made of the pixel data. Pixel data is not managed automatically; + you must free the surface before you free the pixel data. + + \param pixels a pointer to existing pixel data + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param pitch the pitch of the surface in bytes + \param format the SDL_PixelFormatEnum for the new surface's pixel format. + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.5. + + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + + Allocate a new RGB surface with existing pixel data. + + This function operates mostly like SDL_CreateRGBSurface(), except it does + not allocate memory for the pixel data, instead the caller provides an + existing buffer of data for the surface to use. + + No copy is made of the pixel data. Pixel data is not managed automatically; + you must free the surface before you free the pixel data. + + \param pixels a pointer to existing pixel data + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param pitch the pitch of the surface in bytes + \param Rmask the red mask for the pixels + \param Gmask the green mask for the pixels + \param Bmask the blue mask for the pixels + \param Amask the alpha mask for the pixels + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + + Allocate a new RGB surface with a specific pixel format. + + This function operates mostly like SDL_CreateRGBSurface(), except instead + of providing pixel color masks, you provide it with a predefined format + from SDL_PixelFormatEnum. + + \param flags the flags are unused and should be set to 0 + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param format the SDL_PixelFormatEnum for the new surface's pixel format. + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.5. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_FreeSurface + + + + Allocate a new RGB surface. + + If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. + If `depth` is greater than 8 bits, the pixel format is set using the + [RGBA]mask parameters. + + The [RGBA]mask parameters are the bitmasks used to extract that color from + a pixel. For instance, `Rmask` being 0xFF000000 means the red data is + stored in the most significant byte. Using zeros for the RGB masks sets a + default value, based on the depth. For example: + + ```c++ + SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); + ``` + + However, using zero for the Amask results in an Amask of 0. + + By default surfaces with an alpha mask are set up for blending as with: + + ```c++ + SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) + ``` + + You can change this by calling SDL_SetSurfaceBlendMode() and selecting a + different `blendMode`. + + \param flags the flags are unused and should be set to 0 + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param Rmask the red mask for the pixels + \param Gmask the green mask for the pixels + \param Bmask the blue mask for the pixels + \param Amask the alpha mask for the pixels + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + +Reference count -- used when freeing surface + + +info for fast blit mapping to other surfaces + + +clipping information + + +list of BlitMap that hold a reference to this surface + + +information needed for surfaces requiring locks + + +Application data associated with the surface + + + \brief A collection of pixels used in software blitting. + + \note This structure should be treated as read-only, except for \c pixels, + which, if not NULL, contains the raw pixel data for the surface. + + +\brief The type of function used for surface blitting functions. + + + + Compose a custom blend mode for renderers. + + The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept + the SDL_BlendMode returned by this function if the renderer supports it. + + A blend mode controls how the pixels from a drawing operation (source) get + combined with the pixels from the render target (destination). First, the + components of the source and destination pixels get multiplied with their + blend factors. Then, the blend operation takes the two products and + calculates the result that will get stored in the render target. + + Expressed in pseudocode, it would look like this: + + ```c + dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); + dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); + ``` + + Where the functions `colorOperation(src, dst)` and `alphaOperation(src, + dst)` can return one of the following: + + - `src + dst` + - `src - dst` + - `dst - src` + - `min(src, dst)` + - `max(src, dst)` + + The red, green, and blue components are always multiplied with the first, + second, and third components of the SDL_BlendFactor, respectively. The + fourth component is not used. + + The alpha component is always multiplied with the fourth component of the + SDL_BlendFactor. The other components are not used in the alpha + calculation. + + Support for these blend modes varies for each renderer. To check if a + specific SDL_BlendMode is supported, create a renderer and pass it to + either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will + return with an error if the blend mode is not supported. + + This list describes the support of custom blend modes for each renderer in + SDL 2.0.6. All renderers support the four blend modes listed in the + SDL_BlendMode enumeration. + + - **direct3d**: Supports all operations with all factors. However, some + factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and + `SDL_BLENDOPERATION_MAXIMUM`. + - **direct3d11**: Same as Direct3D 9. + - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL + 2.0.6. + - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + factors. Color and alpha factors need to be the same. OpenGL ES 1 + implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` + and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha + operations being different from each other. May support color and alpha + factors being different from each other. + - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, + `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` + operations with all factors. + - **psp**: No custom blend mode support. + - **software**: No custom blend mode support. + + Some renderers do not provide an alpha component for the default render + target. The `SDL_BLENDFACTOR_DST_ALPHA` and + `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this + case. + + \param srcColorFactor the SDL_BlendFactor applied to the red, green, and + blue components of the source pixels + \param dstColorFactor the SDL_BlendFactor applied to the red, green, and + blue components of the destination pixels + \param colorOperation the SDL_BlendOperation used to combine the red, + green, and blue components of the source and + destination pixels + \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of + the source pixels + \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of + the destination pixels + \param alphaOperation the SDL_BlendOperation used to combine the alpha + component of the source and destination pixels + \returns an SDL_BlendMode that represents the chosen factors and + operations. + + \since This function is available since SDL 2.0.6. + + \sa SDL_SetRenderDrawBlendMode + \sa SDL_GetRenderDrawBlendMode + \sa SDL_SetTextureBlendMode + \sa SDL_GetTextureBlendMode + + + + Calculate the intersection of a rectangle and line segment with float + precision. + + This function is used to clip a line segment to a rectangle. A line segment + contained entirely within the rectangle or that does not intersect will + remain unchanged. A line segment that crosses the rectangle at either or + both ends will be clipped to the boundary of the rectangle and the new + coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + + \param rect an SDL_FRect structure representing the rectangle to intersect + \param X1 a pointer to the starting X-coordinate of the line + \param Y1 a pointer to the starting Y-coordinate of the line + \param X2 a pointer to the ending X-coordinate of the line + \param Y2 a pointer to the ending Y-coordinate of the line + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + + + Calculate a minimal rectangle enclosing a set of points with float + precision. + + If `clip` is not NULL then only points inside of the clipping rectangle are + considered. + + \param points an array of SDL_FPoint structures representing points to be + enclosed + \param count the number of structures in the `points` array + \param clip an SDL_FRect used for clipping or NULL to enclose all points + \param result an SDL_FRect structure filled in with the minimal enclosing + rectangle + \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + points were outside of the clipping rectangle. + + \since This function is available since SDL 2.0.22. + + + + Calculate the union of two rectangles with float precision. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \param result an SDL_FRect structure filled in with the union of rectangles + `A` and `B` + + \since This function is available since SDL 2.0.22. + + + + Calculate the intersection of two rectangles with float precision. + + If `result` is NULL then this function will return SDL_FALSE. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \param result an SDL_FRect structure filled in with the intersection of + rectangles `A` and `B` + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + \sa SDL_HasIntersectionF + + + + Determine whether two rectangles intersect with float precision. + + If either pointer is NULL the function will return SDL_FALSE. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + \sa SDL_IntersectRect + + + + Returns true if the two rectangles are equal, using a default epsilon. + + \since This function is available since SDL 2.0.22. + + + + Returns true if the two rectangles are equal, within some given epsilon. + + \since This function is available since SDL 2.0.22. + + + +Returns true if the rectangle has no area. + + + +Returns true if point resides inside a rectangle. + + + + Calculate the intersection of a rectangle and line segment. + + This function is used to clip a line segment to a rectangle. A line segment + contained entirely within the rectangle or that does not intersect will + remain unchanged. A line segment that crosses the rectangle at either or + both ends will be clipped to the boundary of the rectangle and the new + coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + + \param rect an SDL_Rect structure representing the rectangle to intersect + \param X1 a pointer to the starting X-coordinate of the line + \param Y1 a pointer to the starting Y-coordinate of the line + \param X2 a pointer to the ending X-coordinate of the line + \param Y2 a pointer to the ending Y-coordinate of the line + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + + + Calculate a minimal rectangle enclosing a set of points. + + If `clip` is not NULL then only points inside of the clipping rectangle are + considered. + + \param points an array of SDL_Point structures representing points to be + enclosed + \param count the number of structures in the `points` array + \param clip an SDL_Rect used for clipping or NULL to enclose all points + \param result an SDL_Rect structure filled in with the minimal enclosing + rectangle + \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + points were outside of the clipping rectangle. + + \since This function is available since SDL 2.0.0. + + + + Calculate the union of two rectangles. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \param result an SDL_Rect structure filled in with the union of rectangles + `A` and `B` + + \since This function is available since SDL 2.0.0. + + + + Calculate the intersection of two rectangles. + + If `result` is NULL then this function will return SDL_FALSE. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \param result an SDL_Rect structure filled in with the intersection of + rectangles `A` and `B` + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + \sa SDL_HasIntersection + + + + Determine whether two rectangles intersect. + + If either pointer is NULL the function will return SDL_FALSE. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + \sa SDL_IntersectRect + + + +Returns true if the two rectangles are equal. + + + +Returns true if the rectangle has no area. + + + +Returns true if point resides inside a rectangle. + + + + A rectangle, with the origin at the upper left (floating point). + + \sa SDL_FRectEmpty + \sa SDL_FRectEquals + \sa SDL_FRectEqualsEpsilon + \sa SDL_HasIntersectionF + \sa SDL_IntersectFRect + \sa SDL_IntersectFRectAndLine + \sa SDL_UnionFRect + \sa SDL_EncloseFPoints + \sa SDL_PointInFRect + + + + A rectangle, with the origin at the upper left (integer). + + \sa SDL_RectEmpty + \sa SDL_RectEquals + \sa SDL_HasIntersection + \sa SDL_IntersectRect + \sa SDL_IntersectRectAndLine + \sa SDL_UnionRect + \sa SDL_EnclosePoints + + + + The structure that defines a point (floating point) + + \sa SDL_EncloseFPoints + \sa SDL_PointInFRect + + + + Use this function to write 64 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE64 + + + + Use this function to write 64 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE64 + + + + Use this function to write 32 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE32 + + + + Use this function to write 32 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE32 + + + + Use this function to write 16 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE16 + + + + Use this function to write 16 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE16 + + + + \name Write endian functions + + Write an item of native format to the specified endianness. + + Use this function to write a byte to an SDL_RWops. + + \param dst the SDL_RWops to write to + \param value the byte value to write + \returns 1 on success or 0 on failure; call SDL_GetError() for more + information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadU8 + + + + Use this function to read 64 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 64 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE64 + + + + Use this function to read 64 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 64 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE64 + + + + Use this function to read 32 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 32 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE32 + + + + Use this function to read 32 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 32 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE32 + + + + Use this function to read 16 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 16 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE16 + + + + Use this function to read 16 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 16 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE16 + + + + \name Read endian functions + + Read an item of the specified endianness and return in native format. + + Use this function to read a byte from an SDL_RWops. + + \param src the SDL_RWops to read from + \returns the read byte on success or 0 on failure; call SDL_GetError() for + more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteU8 + + + + Load all the data from a file path. + + The data is allocated with a zero byte at the end (null terminated) for + convenience. This extra byte is not included in the value reported via + `datasize`. + + The data should be freed with SDL_free(). + + Prior to SDL 2.0.10, this function was a macro wrapping around + SDL_LoadFile_RW. + + \param file the path to read all available data from + \param datasize if not NULL, will store the number of bytes read + \returns the data, or NULL if there was an error. + + \since This function is available since SDL 2.0.10. + + + + Load all the data from an SDL data stream. + + The data is allocated with a zero byte at the end (null terminated) for + convenience. This extra byte is not included in the value reported via + `datasize`. + + The data should be freed with SDL_free(). + + \param src the SDL_RWops to read all available data from + \param datasize if not NULL, will store the number of bytes read + \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning + \returns the data, or NULL if there was an error. + + \since This function is available since SDL 2.0.6. + + + + Close and free an allocated SDL_RWops structure. + + SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any + resources used by the stream and frees the SDL_RWops itself with + SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to + flush to its output (e.g. to disk). + + Note that if this fails to flush the stream to disk, this function reports + an error, but the SDL_RWops is still invalid once this function returns. + + Prior to SDL 2.0.10, this function was a macro. + + \param context SDL_RWops structure to close + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Write to an SDL_RWops data stream. + + This function writes exactly `num` objects each of size `size` from the + area pointed at by `ptr` to the stream. If this fails for any reason, it'll + return less than `num` to demonstrate how far the write progressed. On + success, it returns `num`. + + SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's + `write` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param ptr a pointer to a buffer containing data to write + \param size the size of an object to write, in bytes + \param num the number of objects to write + \returns the number of objects written, which will be less than **num** on + error; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + + + + Read from a data source. + + This function reads up to `maxnum` objects each of size `size` from the + data source to the area pointed at by `ptr`. This function may read less + objects than requested. It will return zero when there has been an error or + the data stream is completely read. + + SDL_RWread() is actually a function wrapper that calls the SDL_RWops's + `read` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param ptr a pointer to a buffer to read data into + \param size the size of each object to read, in bytes + \param maxnum the maximum number of objects to be read + \returns the number of objects read, or 0 at error or end of file; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Determine the current read/write offset in an SDL_RWops data stream. + + SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` + method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify + application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a SDL_RWops data stream object from which to get the current + offset + \returns the current offset in the stream, or -1 if the information can not + be determined. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Seek within an SDL_RWops data stream. + + This function seeks to byte `offset`, relative to `whence`. + + `whence` may be any of the following values: + + - `RW_SEEK_SET`: seek from the beginning of data + - `RW_SEEK_CUR`: seek relative to current read point + - `RW_SEEK_END`: seek relative to the end of data + + If this stream can not seek, it will return -1. + + SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's + `seek` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param offset an offset in bytes, relative to **whence** location; can be + negative + \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` + \returns the final offset in the data stream after the seek or -1 on error. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWtell + \sa SDL_RWwrite + + + + Use this function to get the size of the data stream in an SDL_RWops. + + Prior to SDL 2.0.10, this function was a macro. + + \param context the SDL_RWops to get the size of the data stream from + \returns the size of the data stream in the SDL_RWops on success, -1 if + unknown or a negative error code on failure; call SDL_GetError() + for more information. + + \since This function is available since SDL 2.0.10. + + + + Use this function to free an SDL_RWops structure allocated by + SDL_AllocRW(). + + Applications do not need to use this function unless they are providing + their own SDL_RWops implementation. If you just need a SDL_RWops to + read/write a common data source, you should use the built-in + implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and + call the **close** method on those SDL_RWops pointers when you are done + with them. + + Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is + invalid as soon as this function returns. Any extra memory allocated during + creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must + be responsible for managing that memory in their **close** method. + + \param area the SDL_RWops structure to be freed + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocRW + + + + Use this function to allocate an empty, unpopulated SDL_RWops structure. + + Applications do not need to use this function unless they are providing + their own SDL_RWops implementation. If you just need a SDL_RWops to + read/write a common data source, you should use the built-in + implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. + + You must free the returned pointer with SDL_FreeRW(). Depending on your + operating system and compiler, there may be a difference between the + malloc() and free() your program uses and the versions SDL calls + internally. Trying to mix the two can cause crashing such as segmentation + faults. Since all SDL_RWops must free themselves when their **close** + method is called, all SDL_RWops must be allocated through this function, so + they can all be freed correctly with SDL_FreeRW(). + + \returns a pointer to the allocated memory on success, or NULL on failure; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeRW + + + + Use this function to prepare a read-only memory buffer for use with RWops. + + This function sets up an SDL_RWops struct based on a memory area of a + certain size. It assumes the memory area is not writable. + + Attempting to write to this RWops stream will report an error without + writing to the memory buffer. + + This memory buffer is not copied by the RWops; the pointer you provide must + remain valid until you close the stream. Closing the stream will not free + the original buffer. + + If you need to write to a memory buffer, you should use SDL_RWFromMem() + with a writable buffer of memory instead. + + \param mem a pointer to a read-only buffer to feed an SDL_RWops stream + \param size the buffer size, in bytes + \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + + + + Use this function to prepare a read-write memory buffer for use with + SDL_RWops. + + This function sets up an SDL_RWops struct based on a memory area of a + certain size, for both read and write access. + + This memory buffer is not copied by the RWops; the pointer you provide must + remain valid until you close the stream. Closing the stream will not free + the original buffer. + + If you need to make sure the RWops never writes to the memory buffer, you + should use SDL_RWFromConstMem() with a read-only buffer of memory instead. + + \param mem a pointer to a buffer to feed an SDL_RWops stream + \param size the buffer size, in bytes + \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + + Use this function to create an SDL_RWops structure from a standard I/O file + pointer (stdio.h's `FILE*`). + + This function is not available on Windows, since files opened in an + application on that platform cannot be used by a dynamically linked + library. + + On some platforms, the first parameter is a `void*`, on others, it's a + `FILE*`, depending on what system headers are available to SDL. It is + always intended to be the `FILE*` type from the C runtime's stdio.h. + + \param fp the `FILE*` that feeds the SDL_RWops stream + \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, + SDL_FALSE to leave the `FILE*` open when the RWops is + closed + \returns a pointer to the SDL_RWops structure that is created, or NULL on + failure; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + + \name RWFrom functions + + Functions to create SDL_RWops structures from various data streams. + + Use this function to create a new SDL_RWops structure for reading from + and/or writing to a named file. + + The `mode` string is treated roughly the same as in a call to the C + library's fopen(), even if SDL doesn't happen to use fopen() behind the + scenes. + + Available `mode` strings: + + - "r": Open a file for reading. The file must exist. + - "w": Create an empty file for writing. If a file with the same name + already exists its content is erased and the file is treated as a new + empty file. + - "a": Append to a file. Writing operations append data at the end of the + file. The file is created if it does not exist. + - "r+": Open a file for update both reading and writing. The file must + exist. + - "w+": Create an empty file for both reading and writing. If a file with + the same name already exists its content is erased and the file is + treated as a new empty file. + - "a+": Open a file for reading and appending. All writing operations are + performed at the end of the file, protecting the previous content to be + overwritten. You can reposition (fseek, rewind) the internal pointer to + anywhere in the file for reading, but writing operations will move it + back to the end of file. The file is created if it does not exist. + + **NOTE**: In order to open a file as a binary file, a "b" character has to + be included in the `mode` string. This additional "b" character can either + be appended at the end of the string (thus making the following compound + modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the + letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). + Additional characters may follow the sequence, although they should have no + effect. For example, "t" is sometimes appended to make explicit the file is + a text file. + + This function supports Unicode filenames, but they must be encoded in UTF-8 + format, regardless of the underlying operating system. + + As a fallback, SDL_RWFromFile() will transparently open a matching filename + in an Android app's `assets`. + + Closing the SDL_RWops will close the file handle SDL is holding internally. + + \param file a UTF-8 string representing the filename to open + \param mode an ASCII string representing the mode to be used for opening + the file. + \returns a pointer to the SDL_RWops structure that is created, or NULL on + failure; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + +Return the size of the file in this rwops, or -1 if unknown + + + Seek to \c offset relative to \c whence, one of stdio's whence values: + RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + + \return the final offset in the data stream, or -1 on error. + + + Read up to \c maxnum objects each of size \c size from the data + stream to the area pointed at by \c ptr. + + \return the number of objects read, or 0 at error or end of file. + + + Write exactly \c num objects each of size \c size from the area + pointed at by \c ptr to data stream. + + \return the number of objects written, or 0 at error or end of file. + + + Close and free an allocated SDL_RWops structure. + + \return 0 if successful or -1 on write error when flushing data. + + + + Clear any previous error message for this thread. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetError + \sa SDL_SetError + + + + Get the last error message that was set for the current thread. + + This allows the caller to copy the error string into a provided buffer, but + otherwise operates exactly the same as SDL_GetError(). + + \param errstr A buffer to fill with the last error message that was set for + the current thread + \param maxlen The size of the buffer pointed to by the errstr parameter + \returns the pointer passed in as the `errstr` parameter. + + \since This function is available since SDL 2.0.14. + + \sa SDL_GetError + + + + Retrieve a message about the last error that occurred on the current + thread. + + It is possible for multiple errors to occur before calling SDL_GetError(). + Only the last error is returned. + + The message is only applicable when an SDL function has signaled an error. + You must check the return values of SDL function calls to determine when to + appropriately call SDL_GetError(). You should *not* use the results of + SDL_GetError() to decide if an error has occurred! Sometimes SDL will set + an error string even when reporting success. + + SDL will *not* clear the error string for successful API calls. You *must* + check return values for failure cases before you can assume the error + string applies. + + Error strings are set per-thread, so an error set in a different thread + will not interfere with the current thread's operation. + + The returned string is internally allocated and must not be freed by the + application. + + \returns a message with information about the specific error that occurred, + or an empty string if there hasn't been an error message set since + the last call to SDL_ClearError(). The message is only applicable + when an SDL function has signaled an error. You must check the + return values of SDL function calls to determine when to + appropriately call SDL_GetError(). + + \since This function is available since SDL 2.0.0. + + \sa SDL_ClearError + \sa SDL_SetError + + + + Calculate a 256 entry gamma ramp for a gamma value. + + \param gamma a gamma value where 0.0 is black and 1.0 is identity + \param ramp an array of 256 values filled in with the gamma ramp + + \since This function is available since SDL 2.0.0. + + \sa SDL_SetWindowGammaRamp + + + + Get RGBA values from a pixel in the specified format. + + This function uses the entire 8-bit [0..255] range when converting color + components from pixel formats with less than 8-bits per RGB component + (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + + If the surface has no alpha component, the alpha will be returned as 0xff + (100% opaque). + + \param pixel a pixel value + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r a pointer filled in with the red component + \param g a pointer filled in with the green component + \param b a pointer filled in with the blue component + \param a a pointer filled in with the alpha component + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_MapRGB + \sa SDL_MapRGBA + + + + Get RGB values from a pixel in the specified format. + + This function uses the entire 8-bit [0..255] range when converting color + components from pixel formats with less than 8-bits per RGB component + (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + + \param pixel a pixel value + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r a pointer filled in with the red component + \param g a pointer filled in with the green component + \param b a pointer filled in with the blue component + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGBA + \sa SDL_MapRGB + \sa SDL_MapRGBA + + + + Map an RGBA quadruple to a pixel value for a given pixel format. + + This function maps the RGBA color value to the specified pixel format and + returns the pixel value best approximating the given RGBA color value for + the given pixel format. + + If the specified pixel format has no alpha component the alpha value will + be ignored (as it will be in formats with a palette). + + If the format has a palette (8-bit) the index of the closest matching color + in the palette will be returned. + + If the pixel format bpp (color depth) is less than 32-bpp then the unused + upper bits of the return value can safely be ignored (e.g., with a 16-bpp + format the return value can be assigned to a Uint16, and similarly a Uint8 + for an 8-bpp format). + + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r the red component of the pixel in the range 0-255 + \param g the green component of the pixel in the range 0-255 + \param b the blue component of the pixel in the range 0-255 + \param a the alpha component of the pixel in the range 0-255 + \returns a pixel value + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_GetRGBA + \sa SDL_MapRGB + + + + Map an RGB triple to an opaque pixel value for a given pixel format. + + This function maps the RGB color value to the specified pixel format and + returns the pixel value best approximating the given RGB color value for + the given pixel format. + + If the format has a palette (8-bit) the index of the closest matching color + in the palette will be returned. + + If the specified pixel format has an alpha component it will be returned as + all 1 bits (fully opaque). + + If the pixel format bpp (color depth) is less than 32-bpp then the unused + upper bits of the return value can safely be ignored (e.g., with a 16-bpp + format the return value can be assigned to a Uint16, and similarly a Uint8 + for an 8-bpp format). + + \param format an SDL_PixelFormat structure describing the pixel format + \param r the red component of the pixel in the range 0-255 + \param g the green component of the pixel in the range 0-255 + \param b the blue component of the pixel in the range 0-255 + \returns a pixel value + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_GetRGBA + \sa SDL_MapRGBA + + + + Free a palette created with SDL_AllocPalette(). + + \param palette the SDL_Palette structure to be freed + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + + + + Set a range of colors in a palette. + + \param palette the SDL_Palette structure to modify + \param colors an array of SDL_Color structures to copy into the palette + \param firstcolor the index of the first palette entry to modify + \param ncolors the number of entries to modify + \returns 0 on success or a negative error code if not all of the colors + could be set; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + \sa SDL_CreateRGBSurface + + + + Set the palette for a pixel format structure. + + \param format the SDL_PixelFormat structure that will use the palette + \param palette the SDL_Palette structure that will be used + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + \sa SDL_FreePalette + + + + Create a palette structure with the specified number of color entries. + + The palette entries are initialized to white. + + \param ncolors represents the number of color entries in the color palette + \returns a new SDL_Palette structure on success or NULL on failure (e.g. if + there wasn't enough memory); call SDL_GetError() for more + information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreePalette + + + + Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). + + \param format the SDL_PixelFormat structure to free + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + + + + Create an SDL_PixelFormat structure corresponding to a pixel format. + + Returned structure may come from a shared global cache (i.e. not newly + allocated), and hence should not be modified, especially the palette. Weird + errors such as `Blit combination not supported` may occur. + + \param pixel_format one of the SDL_PixelFormatEnum values + \returns the new SDL_PixelFormat structure or NULL on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeFormat + + + + Convert a bpp value and RGBA masks to an enumerated pixel format. + + This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't + possible. + + \param bpp a bits per pixel value; usually 15, 16, or 32 + \param Rmask the red mask for the format + \param Gmask the green mask for the format + \param Bmask the blue mask for the format + \param Amask the alpha mask for the format + \returns one of the SDL_PixelFormatEnum values + + \since This function is available since SDL 2.0.0. + + \sa SDL_PixelFormatEnumToMasks + + + + Convert one of the enumerated pixel formats to a bpp value and RGBA masks. + + \param format one of the SDL_PixelFormatEnum values + \param bpp a bits per pixel value; usually 15, 16, or 32 + \param Rmask a pointer filled in with the red mask for the format + \param Gmask a pointer filled in with the green mask for the format + \param Bmask a pointer filled in with the blue mask for the format + \param Amask a pointer filled in with the alpha mask for the format + \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't + possible; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_MasksToPixelFormatEnum + + + + Get the human readable name of a pixel format. + + \param format the pixel format to query + \returns the human readable name of the specified pixel format or + `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. + + \since This function is available since SDL 2.0.0. + + + +\note Everything in the pixel format structure is read-only. + + + +The bits of this structure can be directly reinterpreted as an integer-packed +color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 +on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). + + + + If a + b would overflow, return -1. Otherwise store a + b via ret + and return 0. + + \since This function is available since SDL 2.24.0. + + + + If a * b would overflow, return -1. Otherwise store a * b via ret + and return 0. + + \since This function is available since SDL 2.24.0. + + + + This function converts a string between encodings in one pass, returning a + string that must be freed with SDL_free() or NULL on error. + + \since This function is available since SDL 2.0.0. + + + + Get the number of outstanding (unfreed) allocations + + \since This function is available since SDL 2.0.7. + + + + Replace SDL's memory allocation functions with a custom set + + \since This function is available since SDL 2.0.7. + + + + Get the current set of SDL memory functions + + \since This function is available since SDL 2.0.7. + + + + Get the original set of SDL memory functions + + \since This function is available since SDL 2.24.0. + + + +\endcond + \file begin_code.h + + This file sets things up for C dynamic library function definitions, + static inlined functions, and structures aligned at 4-byte alignment. + If you don't like ugly C preprocessor code, don't look at this file. :) + + + +\name Floating-point constants + +\cond + + +\brief An unsigned 64-bit integer type. + + + +\brief A signed 64-bit integer type. + + + +\brief An unsigned 32-bit integer type. + + + +\brief A signed 32-bit integer type. + + + +\brief An unsigned 16-bit integer type. + + + +\brief A signed 16-bit integer type. + + + +\brief An unsigned 8-bit integer type. + + + +\brief A signed 8-bit integer type. + + + + \file close_code.h + + This file reverses the effects of begin_code.h and should be included + after you finish any function and structure declarations in your headers + + + + \file SDL_stdinc.h + + This is a general header that includes C language support. + + \file SDL_platform.h + + Try to get a standard set of platform defines. + + \file begin_code.h + + This file sets things up for C dynamic library function definitions, + static inlined functions, and structures aligned at 4-byte alignment. + If you don't like ugly C preprocessor code, don't look at this file. :) + + Get the name of the platform. + + Here are the names returned for some (but not all) supported platforms: + + - "Windows" + - "Mac OS X" + - "Linux" + - "iOS" + - "Android" + + \returns the name of the platform. If the correct platform name is not + available, returns a string beginning with the text "Unknown". + + \since This function is available since SDL 2.0.0. + + + +*!************************************************************************* + + + +Marks the application to stop at the end of the current frame. + + + + +Whether or not the application is currently in fullscreen mode or not. + + + + +Retrieves the designated height of the current window. + + + + +Retrieves the designated width of the current window. + + + + +Whether or not the engine is in a paused state where script updates and +physics are not in play. + + + + +Whether or not the engine is playing. This will always be true on Publish. +On Debug/Release builds, this is true when the editor is in Play Mode. It +will also be true even if the editor is in Play Mode but is paused. + + + + +Static class that contains useful properties for querying the state of the +engine. + + + + +Sets the parent of this Transform component. + + +Entity that contains the Transform component that this Transform will be +parented to. If null, unparenting will occur. + + +If true, the transform values of this Transform component will retain their +pre-parent-change global transforms. The local transform values will be +modified to ensure that the global transforms do not change. + + + + +Parent Transform that affects this Transform. + + + + +Global scale stored by this Transform. + + + + +Global euler angle rotations stored by this Transform. + + + + +Global rotation quaternion stored by this Transform. + + + + +Global position stored by this Transform. + + + + +Local scale stored by this Transform. + + + + +Local euler angle rotations stored by this Transform. + + + + +Local rotation quaternion stored by this Transform. + + + + +Local position stored by this Transform. + + + + +Constructs a Transform Component that represents a native Transform component +tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the SHADE Engine's TransformComponent. + + + + +Compares if two float values are close enough to be the same with the +specified tolerance value. + + One of the values to compare. + The other value to compare. + Tolerance for floating point comparison. + True if a and b are practically the same. + + + +Compares if two float values are close enough to be the same with a tolerance +of Epsilon. + + One of the values to compare. + The other value to compare. + True if a and b are practically the same. + + + +Calculates the linear parameter t that produces the interpolant value within +the range [a, b]. + + Start value. + End value. + Value between start and end. + Percentage of value between start and end. + + + +Linearly interpolates between a and b by t. +The parameter t is not clamped and a value based on a and b is supported. +If t is less than zero, or greater than one, then LerpUnclamped will result +in a return value outside the range a to b. + + The start value. + The end value. + The interpolation value between the two float. + The interpolated float result between the two float values. + + + +Linearly interpolates between a and b by t. +The parameter t is clamped to the range [0, 1]. + + The start value. + The end value. + The interpolation value between the two float. + The interpolated float result between the two float values. + + + +Converts an angle from radian representation to degree representation. + + Radian-based angle to convert. + The specified angle in degrees. + + + +Converts an angle from degree representation to radian representation. + + Degree-based angle to convert. + The specified angle in radians. + + + +Wraps a value if they get to low or too high. + + Value to wrap. + Minimum value to wrap at. + Maximum value to wrap at. + Wrapped value. + + + +Small value used for single precision floating point comparisons. + + + + +Radians-to-degrees conversion constant + + + + +Degrees-to-radians conversion constant + + + + +Contains utility Math functions. + + + + +Logs a native exception that is formatted nicely to the output. + + Native exception to log. + Name of the one responsible for the exception. + + + +Logs an exception that is formatted nicely to the output. + + Name of the one responsible for the exception. + Exception to log. + + + +Logs a native exception that is formatted nicely to the output. +Equivalent to calling +LogException(exception, Convert::ToNative(thrower->GetType()->Name)); + + Native exception to log. + +Object that threw the exception to label the exception message. +The name of the object will be used. + + + + +Logs an exception that is formatted nicely to the output. + + Exception to log. + +Object that threw the exception to label the exception message. +The name of the object will be used. + + + + +Logs an exception that is formatted nicely to the output. + + Exception to log. + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output. + + The string to output. + + + +Logs a error message to the output. + + The string to output. + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output. + + The string to output. + + + +Logs a warning message to the output. + + The string to output. + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output. + + The string to output. + + + +Logs a message to the output. + + The string to output. + + + +Static class that contains the functions for working with time. + + + + +Material used to render this Renderable. + + + + +Material used to render this Renderable. + + + + +Mesh used to render this Renderable. + + + + +Constructs a Renderable Component that represents a native Renderable +component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the SHADE Engine's SHRenderableComponent. + + + + +Retrieves the value of a specified property on the material. + + Type of property to get. + Name of the property to get. + Value of that property on the material. + +If this Material object is invalid. + + +If the name or type was specified that does not match the material's shader's +defined properties. + + + + +Set the value of a specific property. + + Type of property to set. + Name of the property to set. + Value to set te property to. + +If this Material object is invalid. + + +If the name or type was specified that does not match the material's shader's +defined properties. + + + + +Constructor for the Material + + Handle to the native material object. + + + +Managed counterpart of the native MaterialInstance object containing material +data that can be fed to Renderables for rendering. + + + + +Constructor for the Mesh + + Handle to the mesh object. + + + +Managed counterpart of the native Mesh object containing vertex data that can +be fed to Renderables for rendering. + + + +@brief Decomposes a transformation matrix into translation, orientation and scale. +@param[out] scale The scaling factor of the matrix. +@param[out] orientation The orientation of the matrix. +@param[out] translation The translation of the matrix. +@return True if decomposition was successful. + + + +@brief Decomposes a transformation matrix into translation, euler angles and scale. +@param[out] scale The scaling factor of the matrix. +@param[out] rotation The euler angles of the matrix. +@param[out] translation The translation of the matrix. +@return True if decomposition was successful. + + + +@brief Interface for a Column-Major Row Vector 4x4 Matrix. + + + + +Constructs a RigidBody Component that represents a native +SHRigidBodyComponent component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the the SHADE Engine's SHRigidBodyComponent. + + + + +Creates an instance of the Managed representation of a Component with a +native Entity. + + Type of Component to create. + Native Entity that this Component is tied to. + The created Managed representation of the Component. + + + +Static constructor to initialize static data + + + + +Pointer to a function for Component manipulation operations. + + +Contains a set of Component related data used for resolving operations for +each Component. + + + + +Removes a Component from the specified Entity. + + Type of the Component to remove. + +Entity object that should have the specified Component removed from/ + + + + +Checks if the specified Entity has the specified Component. + + Type of the Component to check for. + Entity object to check for the Component. + +True if the specified Entity has the specified Component. False otherwise. + + + + +Ensures a Component on the specified Entity. + + Type of the Component to ensure. + Entity object to ensure the Component on. + Reference to the Component. + + + +Retrieves the first Component from the specified GameObjectt's children that +matches the specified type. + + Type of the Component to get. + Entity object to get the Component from. + +Reference to the Component or null if the Entity does not have the +specified Component. + + + + +Gets a Component from the specified Entity. + + Type of the Component to get. + Entity object to get the Component from. + +Reference to the Component or null if the Entity does not have the +specified Component. + + + + +Adds a Component to the specified Entity. + + Type of the Component to add. + +Entity object that should have the specified Component added to. + + Reference to the Component that was added. + + + +Static class which contains functions that map Pls::ECS's Component manipulation +functions to managed generic functions. + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Entity that this Component belongs to. + + + + +Constructor for BaseComponent to tie it to a specific Entity. +Constructors of derived Components should call this Constructor. + + Entity that this Component will be tied to. + + + +Implicit conversion operator to enable checking if a component is null. + + Component to check. + + + +Removes all Scripts of the specified type from this GameObject. + + Type of PLushieScripts to remove. + + + +Retrieves a immutable list of Scripts of the specified type from this +GameObject. + + Type of Scripts to Get. + Immutable list of Scripts of the specified type. + + + +Retrieves a Script of the specified type from this GameObject. +If multiple Scripts of the same specified type are added on the same +GameObject, this will retrieve the first one added. + + Type of Script to add. + Reference to the Script to retrieve. + + + +Adds a Script of the specified type to this GameObject. + + Type of Script to add. + Reference to the created Script. + + + +Removes a Component from this GameObject. If no Component exists to begin +with, nothing happens. + + Type of the Component to get. + + + +Gets a Component from this GameObject. + + Type of the Component to get. + +Reference to the Component or null if this GameObject does not have the +specified Component. + + + + +Adds a Component to this GameObject. + + Type of the Component to add. + Reference to the Component that was added. + + + +Retrieves the GameObject that this Component belongs to. + + + + +Class that serves as the base for a wrapper class to Components in native code. + + + + +Called when the attached GameObject has a Collider and leaves a +collision with another GameObject with a Collider2D. + + Information on the collision event. + + + +Called when the attached GameObject has a Collider and collides with +another GameObject with a Collider in subsequent frames of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a Collider and collides with +another GameObject with a Collider in the first frame of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and leaves a +collision with another GameObject with a Collider2D. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and collides with +another GameObject with a Collider in subsequent frames of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and collides with +another GameObject with a Collider in the first frame of collision. + + Information on the collision event. + + + +Called just before the end of the frame where the attached GameObject or +this script is destroyed directly or indirectly due to destruction of the +owner. + + + + +Called every frame after physics and collision resolution but before +rendering. + + + + +Called every frame before physics and collision resolution. + + + + +Called every frame in sync with Physics update steps and thus in most cases +will execute more than update() will. This will be called immediately before +a Physics update step. + + + + +Called on the first frame that the attached GameObject is active but always +after Awake(). + + + + +Called on the first frame that the attached GameObject is active if they are +a part of the scene. + + + + +Called immediately once this script is detached from a GameObject. + + + + +Called immediately once this script is attached to a GameObject. + + + + +Constructor for Script to tie it to a specific GameObject. +Constructors of derived Scripts should call this Constructor. + + +GameObject that this Script will be tied to. + + + + +Used to call onTriggerExit(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onTriggerStay(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onTriggerEnter(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionExit(). This should be called when a collision ends +between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionStay(). This should be called when a collision is +persistent between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionEnter(). This should be called when a collision is +detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onDestroy(). This should be called at the end of the frame +where the attached GameObject or this script is destroyed directly or +indirectly due to destruction of the owner. + + + + +Used to call lateUpdate(). This should be called every frame after physics +and collision resolution but before rendering. + + + + +Used to call update(). This should be called every frame before physics and +collision resolution. + + + + +Used to call fixedUpdate(). This should be called in sync with Physics +update steps and thus in most cases will execute more than Update() will. +This will be called immediately before a Physics update step. + + + + +Used to call start(). This should be called on the first frame that the +attached GameObject is active but always after Awake(). + + + + +Used to call awake(). This should be called on the first frame that the +attached GameObject is active if they are a part of the scene. + + + + +Used to call onDetached(). This is called immediately when this script is +detached from a GameObject. + + + + +Used to call onAttached(). This is called immediately when this script is +attached to a GameObject. + + + + +Implicit conversion operator to enable checking if a component is null. + + Component to check. + + + +Removes all Scripts of the specified type from this GameObject. + + +Type of script to remove. +This needs to be a default constructable Script. + + + + +Retrieves a immutable list of scripts from the specified Entity that +matches the specified type. +
+Note that this function allocates. It should be used sparingly. +
+ +Type of scripts to get. +This needs to be a default constructable Script. + + +Immutable list of references to scripts of the specified type. + +
+ + +Retrieves the first Script from this GameObject's children that matches the +specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + Reference to the script added + + + +Retrieves the first Script from this GameObject that matches the specified +type. + + +Type of script to get. +This needs to be a default constructable Script. + + Reference to the script added + + + +Adds a Script to this GameObject. + + +Type of script to add. +This needs to be a default constructable Script. + + Reference to the script added + + + +Removes a Component from the GameObject that this Script belongs to. + + +Type of the Component to remove. Must be derived from BaseComponent. + + + + +Ensures a Component on the GameObject that this Script belongs to. + + +Type of the Component to ensure. Must be derived from BaseComponent. + + Reference to the Component. + + + +Retrieves the first Component from this GameObject's children that matches +the specified type. + + +Type of the Component to get. Must be derived from BaseComponent. + + Reference to the Component that was retrieved. + + + +Gets a Component from the GameObject that this Script belongs to. + + +Type of the Component to get. Must be derived from BaseComponent. + + Reference to the Component that was retrieved. + + + +Adds a Component to the GameObject that this Script belongs to. + + +Type of the Component to add. Must be derived from BaseComponent. + + Reference to the Component that was added. + + + +GameObject that this Script belongs to. + + + + +Class that forms the basis of all "script"-objects that can be attached to +Entities to update each Entity's Components via C# code. + + + + +The RigidBody that you are colliding with. + + + + +The CollisionShape of the Collider that you are colliding with. + + + + +The Collider that you are colliding with. + + + + +The GameObject whose collider you are colliding with. + + + + +Struct that describes a collision + + + + +Checks if two GameObject references are different. + + GameObject to check. + Another GameObject to check with. + True if both Components are different. + + + +Checks if two GameObject references are the same. + + GameObject to check. + Another GameObject to check with. + True if both Components are the same. + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Retrieves the native Entity object that this GameObject represents. + + Native Entity object that this GameObject represents. + + + +Retrieves the CLR Entity object that this GameObject represents. + + Entity object that this GameObject represents. + + + +Constructor for the GameObject. + + +Managed numerical representation of the ECS Entity that this GameObject +should represent. + + + + +Constructor for the GameObject. + + +The ECS Entity that this GameObject should represent. + + + + +Removes all Scripts of the specified type from this GameObject. + + Type of PLushieScripts to remove. + + + +Retrieves a immutable list of Scripts of the specified type from this +GameObject. + + Type of Scripts to retrieve. + Immutable list of Scripts of the specified type. + + + +Retrieves a Script of the specified type from child GameObjects. +If multiple Scripts of the same specified type are added on the same +child GameObject, this will retrieve the first one added. + + Type of Script to retrieve. + Reference to the Script to retrieve. + + + +Retrieves a Script of the specified type from this GameObject. +If multiple Scripts of the same specified type are added on the same +GameObject, this will retrieve the first one added. + + Type of Script to retrieve. + Reference to the Script to retrieve. + + + +Adds a Script of the specified type to this GameObject. + + Type of Script to add. + Reference to the created Script. + + + +Removes a Component from this GameObject. If no Component exists to begin +with, nothing happens. + + Type of the Component to get. + + + +Ensures a Component on this GameObject. + + Type of the Component to ensure. + +Reference to the Component. + + + + +Retrieves the first Component from this GameObject's children that matches +the specified type. + + Type of the Component to get. + +Reference to the Component or null if neither of this GameObject's children +does not have the specified Component. + + + + +Gets a Component from this GameObject. + + Type of the Component to get. + +Reference to the Component or null if this GameObject does not have the +specified Component. + + + + +Adds a Component to this GameObject. + + Type of the Component to add. + Reference to the Component that was added. + + + +Sets the active state of this GameObject. +
+The actual "activeness" of this GameObject is still dependent on the parents' +active states. +
+ +Whether to activate or deactivate this GameObject. + +
+ + +Sets the name of this GameObject. + + The name to set. + + + +Native Entity ID value for this GameObject. + + + + +Whether or not this Entity is active in the Scene hierarchy. + + + + +Whether or not this Entity alone, is active. This does not mean that this +object is active in the scene. For example, if this Entity's parent is not +active, then this Entity would also be not active. + + + + +Name of the object that this Entity represents. + + + + +Retrieves a GameObject with the specified name. If there are multiple +GameObjects with the same name, the first found GameObject will be retrieved. +There is no guaranteed order of which GameObject is considered "first". + + Name of the GameObject to find. + GameObject that has the specified name. Null if not found. + + + +Destroys the specified GameObject. Note that the specified GameObject will no +longer be a valid GameObject after this function is called. + + The GameObject to be destroyed. + + + +Creates a new GameObject in the current Scene. If multiple Scenes are loaded, +and you would like to create an object in a specific Scene, call the Scene's +CreateGameObject(). + + GameObject that represents the newly created GameObject. + + + +Lightweight object for an PlushieEngine Entity that allows for easy access +to Component and Script operations. + + + + +Constructor for a Tooltip attribute that fills in the description. + + Text to be shown when a field is hovered. + + + +Maximum value for the Ranged field. + + + + +Minimum value for the Ranged field. + + + + +Simple attribute to constrain the range of values for a field on the editor. + + + + +Converts from a native std::Stringto a managed String. + + The native std::string to convert from. + Managed copy of a native std::string. + + + +Converts from a managed String to a native std::string. + + The managed String to convert from. + Native copy of a managed String. + + + +Converts from a native Vector2 to a managed Vector2. + + The native Vector2 to convert from. + Managed copy of a native Vector2. + + + +Converts from a native Quaternion to a managed Quaternion. + + The native Quaternion to convert from. + Managed copy of a native Quaternion. + + + +Converts from a managed Quaternion to a native Quaternion. + + The managed Quaternion to convert from. + Native copy of a managed Quaternion. + + + +Converts from a native Vector2 to a managed Vector2. + + The native Vector2 to convert from. + Managed copy of a native Vector2. + + + +Converts from a managed Vector2 to a native Vector2. + + The managed Vector2 to convert from. + Native copy of a managed Vector2. + + + +Converts from a native Vector3 to a managed Vector3. + + The native Vector3 to convert from. + Managed copy of a native Vector3. + + + +Converts from a managed Vector3 to a native Vector3. + + The managed Vector3 to convert from. + Native copy of a managed Vector3. + + + +Converts from a native Entity to a managed Entity (UInt32). + + Native Entity to convert from. + Managed representation of the specified Entity. + + + +Provides functions easy and consistent syntax for converting between custom +managed and native types that are aligned. + + + + +Converts to true if this is a valid Handle. + + + + +The library that the handle was issued by. + + + + +The internal ID of the handle. + + + + +Creates a ray starting at origin along direction. + + Source of the ray. + Direction the ray travels in. + + + +The direction that a ray travels in. + + + + +The start point of the ray. + + + + +CLR version of the the SHADE Engine's Ray class that represents a ray in +3-Dimensional space. + + + + +Are two quaternions equal to each other? + + Left-hand side quaternion. + Right-hand side quaternion. + + + +Combines rotations lhs and rhs. + + Left-hand side quaternion. + Right-hand side quaternion. + + + +Spherically interpolates between a and b by t. The parameter t is not clamped. + + + + +Spherically interpolates between quaternions a and b by ratio t. The parameter t is clamped to the range [0, 1]. + + Start value, returned when t = 0. + End value, returned when t = 1. + Interpolation ratio. + A quaternion spherically interpolated between quaternions a and b. + + + +Rotates a rotation from towards to.
+The from quaternion is rotated towards to by an angular step of maxDegreesDelta (but note that the rotation will not overshoot). +Negative values of maxDegreesDelta will move away from to until the rotation is exactly the opposite direction. +
+
+ + +Converts this quaternion to one with the same orientation but with a magnitude of 1. + + + + +Creates a rotation with the specified forward and upwards directions.
+Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X. +
+
+ + +Interpolates between a and b by t and normalizes the result afterwards. The parameter t is not clamped. + + + + +Interpolates between a and b by t and normalizes the result afterwards. The parameter t is clamped to the range [0, 1]. + + Start value, returned when t = 0. + End value, returned when t = 1. + Interpolation ratio. + A quaternion interpolated between quaternions a and b. + + + +Returns the Inverse of rotation. + + + + +Creates a rotation which rotates from fromDirection to toDirection. + + + + +Returns a rotation that rotates y degrees around the y axis, x degrees around the x axis, and z degrees around the z axis; applied in that order. + + + + +The dot product between two rotations. + + + + +Creates a rotation which rotates angle degrees around axis. + + + + +Returns the angle in degrees between two rotations a and b.
+ The angle in degrees between the two vectors. +
+ + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Converts a rotation to angle-axis representation (angles in degrees). + + + + +Creates a rotation with the specified forward and upwards directions.
+The result is applied to this quaternion. +If used to orient a Transform, the Z axis will be aligned with forward and the Y axis with upwards, assuming these vectors are orthogonal. +Logs an error if the forward direction is zero. +
+ The direction to look in. + The vector that defines in which direction up is. +
+ + +Creates a rotation which rotates from fromDirection to toDirection.
+Use this to create a rotation which starts at the first Vector (fromDirection) and rotates to the second Vector (toDirection). +These Vectors must be set up in a script. +
+
+ + +Constructor to construct a Quaternion with the specified components. + + X-coordinate to set. + Y-coordinate to set. + Z-coordinate to set. + W-coordinate to set. + + + +W-component of the Quaternion. Do not directly modify quaternions. + + + + +Z-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +Y-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +X-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +Shorthand for writing Quaternion(0, 0, 0, 1). + + + + +CLR version of SHADE's Quaternion class that represents an orientation. +Designed to closely match Unity's Quaternion struct. + + + + +Explicit conversion operator to enable explicit casting from a Vector2 to a +Vector3. + + Vector2 to convert from. + + + +Explicit conversion operator to enable explicit casting from a Vector3 to a +Vector2. + + Vector3 to convert from. + + + +Checks if two Vector3s are not approximately equal. This is equivalent to +calling !Vector3.IsNear() with default tolerance values. + + Vector3 to compare. + Another Vector3 to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Vector3s are approximately equal. This is equivalent to +calling Vector3.IsNear() with default tolerance values. + + Vector3 to compare. + Another Vector3 to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Vector3 with a scalar value and returns +the result. + + Scalar to divide with. + Vector3 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector3 with a scalar value and returns +the result. + + Vector3 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the division of a Vector3 with a scalar value and returns +the result. + + Scalar to divide with. + Vector3 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector3 with a scalar value and returns +the result. + + Vector3 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Vector3s and returns the +result. + + Vector3 to multiply with. + Another Vector3 to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Vector3 from another Vector3 and returns the result. + + Vector3 to subtract from. + Another Vector3 to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Vector3s together and returns the result. + + Vector3 to add. + Another Vector3 to add. + The result of lhs added to rhs + + + +Moves a point current towards target. +Similar to Lerp(), however, the function will ensure that the distance never +exceeds maxDistanceDelta. Negative values of maxDistanceDelta pushes the +vector away from target + + The current position of the point. + The target position to move to. + Maximum distance moved per call. + Vector representing the moved point. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Vector3, returned when t = 0.0f. + The end Vector3, returned when t = 1.0f. + Value used to interpolate between a and b. + The interpolated Vector3. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Vector3, returned when t = 0.0f. + The end Vector3, returned when t = 1.0f. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector3. + + + +Computes and returns a Vector3 that is made from the largest components of +the two specified Vector3s. + + Vector3 to calculate maximum Vector3 with. + Another Vector3 to calculate maximum Vector3 with. + +The Vector3 that contains the largest components of the two specified +Vector3s. + + + + +Computes and returns a Vector3 that is made from the smallest components of +the two specified Vector3s. + + Vector3 to calculate minimum Vector3 with. + Another Vector3 to calculate minimum Vector3 with. + +The Vector3 that contains the smallest components of the two specified +Vector3s. + + + + +Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector3 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in degrees. + + The Vector3 that represents the rotated vector. + + + +Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector3 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in radians. + + The Vector3 that represents the rotated vector. + + + +Reflects a Vector3 across another Vector3. + + A Vector3 to reflect. + A normal to reflect the Vector3 across. + The Vector3 that represents vec reflected across normal. + + + +Computes and returns a Vector3 projection. + + Vector3 to project. + Vector3 to project onto. + The Vector3 that represents the projected vec onto direction. + + + +Computes and returns the cross product of 2 specified Vector3s. + + Vector3 to calculate cross product with. + Another Vector3 to calculate cross product with. + The cross product of the two Vector3s. + + + +Computes and returns the dot product of 2 specified Vector3s. + + Vector3 to calculate dot product with. + Another Vector3 to calculate dot product with. + Scalar value representing the dot product of the two Vector3s. + + + +Checks if two specified Vector3s are near in value. + + Vector3 to check if is near in value. + Another Vector3 to check if is near in value. + Amount of tolerance to do the comparison with. + +True if the two Vector3s are within the tolerance value specified + + + + +Checks if two specified Vector3s are near in value. + + Vector3 to check if is near in value. + Another Vector3 to check if is near in value. + +True if the two Vector3s are within the tolerance value specified + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Checks if a specified point is near this Vector3 that represents a point. + + The other point to check if we are near. + +The amount of tolerance before we consider these points as "near". + + +True if this Vector3 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Checks if a specified point is near this Vector3 that represents a point with +a tolerance value of PLS_EPSILON. + + The other point to check if we are near. + +True if this Vector3 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -180.0f and 180.0f. + + Returns the angle of this vector from the right vector in degrees. + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -Math.PI and Math.PI. + + Returns the angle of this vector from the right vector in radians. + + + +Calculates and returns the squared magnitude of this Vector3. + + Returns the squared length of this Vector3. + + + +Calculates and returns the magnitude of this Vector3. Note that this function +incurs a performance cost from the square root calculation. If you do not +need the precise magnitude, consider using GetSqrMagnitude() instead. + + Returns the length of this Vector3. + + + +Creates a copy of this Vector3 and returns a normalized version. + + +Returns a normalised copy of this Vector3. +If this Vector3 is a zero vector, a zero vector will be returned. + + + + +Normalises this current Vector3. This changes the data of this Vector3. +If you would like to get a copy, use GetNormalised() instead. +This function does nothing to a zero vector. + + + + +Conversion constructor to construct a Vector3 using a Vector2. + + + + + +Constructor to construct a Vector3 with the specified components. + + X-coordinate to set. + Y-coordinate to set. + Z-coordinate to set. + + + +Constructor to construct a Vector3 with the specified components with the +Z-component set to 0.0f. + + X-coordinate to set. + Y-coordinate to set. + + + +Constructor to construct a Vector3 with the specified components with the +Y and Z-component set to 0.0f. + + X-coordinate to set. + + + +Z-component of the Vector3. + + + + +Y-component of the Vector3. + + + + +X-component of the Vector3. + + + + +Shorthand for writing Vector3(0, 0, 0). + + + + +Shorthand for writing Vector3(0, 1, 0). + + + + +Shorthand for writing Vector3(1, 0, 0). + + + + +Shorthand for writing Vector3(float.PositiveInfinity, +float.PositiveInfinity, float.PositiveInfinity). + + + + +Shorthand for writing Vector3(1, 1, 1). + + + + +Shorthand for writing Vector3(float.NegativeInfinity, +float.NegativeInfinity, float.NegativeInfinity). + + + + +Shorthand for writing Vector3(-1, 0, 0). + + + + +Shorthand for writing Vector3(0, 0, 1). + + + + +Shorthand for writing Vector3(0, -1, 0). + + + + +Shorthand for writing Vector3(0, 0, -1). + + + + +CLR version of SHADE Engine's Vector3 class that represents a 3-Dimensional Vector. +Designed to closely match Unity's Vector3 struct. + + + + +Checks if two Vector2s are not approximately equal. This is equivalent to +calling !Vector2.IsNear() with default tolerance values. + + Vector2 to compare. + Another Vector2 to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Vector2s are approximately equal. This is equivalent to +calling Vector2.IsNear() with default tolerance values. + + Vector2 to compare. + Another Vector2 to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Vector2 with a scalar value and returns +the result. + + Scalar to divide with. + Vector2 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector2 with a scalar value and returns +the result. + + Vector2 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the division of a Vector2 with a scalar value and returns +the result. + + Scalar to divide with. + Vector2 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector2 with a scalar value and returns +the result. + + Vector2 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Vector2s and returns the +result. + + Vector2 to multiply with. + Another Vector2 to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Vector2 from another Vector2 and returns the result. + + Vector2 to subtract from. + Another Vector2 to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Vector2s together and returns the result. + + Vector2 to add. + Another Vector2 to add. + The result of lhs added to rhs + + + +Moves a point current towards target. +Similar to Lerp(), however, the function will ensure that the distance never +exceeds maxDistanceDelta. Negative values of maxDistanceDelta pushes the +vector away from target + + The current position of the point. + The target position to move to. + Maximum distance moved per call. + Vector representing the moved point. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Vector2, returned when t = 0.0f. + The end Vector2, returned when t = 1.0f. + Value used to interpolate between a and b. + The interpolated Vector2. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Vector2, returned when t = 0.0f. + The end Vector2, returned when t = 1.0f. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector2. + + + +Computes and returns a Vector2 that is made from the largest components of +the two specified Vector2s. + + Vector2 to calculate maximum Vector2 with. + Another Vector2 to calculate maximum Vector2 with. + +The Vector2 that contains the largest components of the two specified +Vector2s. + + + + +Computes and returns a Vector2 that is made from the smallest components of +the two specified Vector2s. + + Vector2 to calculate minimum Vector2 with. + Another Vector2 to calculate minimum Vector2 with. + +The Vector2 that contains the smallest components of the two specified +Vector2s. + + + + +Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector2 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in degrees. + + The Vector2 that represents the rotated vector. + + + +Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector2 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in radians. + + The Vector2 that represents the rotated vector. + + + +Reflects a Vector2 across another Vector2. + + A Vector2 to reflect. + A normal to reflect the Vector2 across. + The Vector2 that represents vec reflected across normal. + + + +Computes and returns a Vector2 projection. + + Vector2 to project. + Vector2 to project onto. + The Vector2 that represents the projected vec onto direction. + + + +Computes a perpendicular Vector2 to the specified Vector2. + + Vector2 to find a perpendicular of. + +Whether the inward perpendicular Vector is retrieved. If true, the +resultant vector is rotated 90-degrees in a counter-clockwise. + + The perpendicular Vector2 relative to the specified Vector2. + + + + +Computes the inward perpendicular Vector2 to the specified Vector2. +Equivalent to calling Perpendicular(lhs, true). This means, the +resultant Vector2 is rotated 90-degrees in a counter-clockwise. + + Vector2 to find a perpendicular of. + +The perpendicular Vector2 relative to the specified Vector2. + + + + +Computes and returns the dot product of 2 specified Vector2s. + + Vector2 to calculate dot product with. + Another Vector2 to calculate dot product with. + +Scalar value representing the dot product of the two Vector2s. + + + + +Checks if two specified Vector2s are near in value. + + Vector2 to check if is near in value. + Another Vector2 to check if is near in value. + +Amount of tolerance to do the comparison with. + + +True if the two Vector2s are within the tolerance value specified + + + + +Checks if two specified Vector2s are near in value. + + Vector2 to check if is near in value. + Another Vector2 to check if is near in value. + +True if the two Vector2s are within the tolerance value specified + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Checks if a specified point is near this Vector2 that represents a point. + + The other point to check if we are near. + +The amount of tolerance before we consider these points as "near". + + +True if this Vector2 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Checks if a specified point is near this Vector2 that represents a point with +a tolerance value of PLS_EPSILON. + + The other point to check if we are near. + +True if this Vector2 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -180.0f and 180.0f. + + Returns the angle of this vector from the right vector in degrees. + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -Math.PI and Math.PI. + + Returns the angle of this vector from the right vector in radians. + + + +Calculates and returns the squared magnitude of this Vector2. + + Returns the squared length of this Vector2. + + + +Calculates and returns the magnitude of this Vector2. Note that this function +incurs a performance cost from the square root calculation. If you do not +need the precise magnitude, consider using GetSqrMagnitude() instead. + + Returns the length of this Vector2. + + + +Creates a copy of this Vector2 and returns a normalized version. + + +Returns a normalised copy of this Vector2. +If this Vector2 is a zero vector, a zero vector will be returned. + + + + +Normalises this current Vector2. This changes the data of this Vector2. +If you would like to get a copy, use GetNormalised() instead. +This function does nothing to a zero vector. + + + + +Constructor to construct a Vector2 with the specified components.. + + X-coordinate to set. + Y-coordinate to set. + + + +Constructor to construct a Vector2 with the specified components with the +Y-component set to 0.0f. + + X-coordinate to set. + + + +Y-component of the Vector2. + + + + +X-component of the Vector2. + + + + +Shorthand for writing Vector2(0, 0). + + + + +Shorthand for writing Vector2(0, 1). + + + + +Shorthand for writing Vector2(1, 0). + + + + +Shorthand for writing Vector2(float.PositiveInfinity, +float.PositiveInfinity). + + + + +Shorthand for writing Vector2(1, 1). + + + + +Shorthand for writing Vector2(float.NegativeInfinity, +float.NegativeInfinity). + + + + +Shorthand for writing Vector2(-1, 0). + + + + +Shorthand for writing Vector2(0, -1). + + + + +CLR version of SHADE Engine's Vector2 class that represents a 2-Dimensional Vector. +Designed to closely match Unity's Vector2 struct. + + + + +Checks if the specified entity is valid. This is done by checking if it +matches Pls::Entity::INVALID. + + The Entity to check. + True if the specified Entity is valid. + + + +Static class that contains useful utility functions for working with Entity. + + + + +Manages all resources in multiple ResourceLibraries. + + + + +Base class for SHResourceLibrary that holds information about the library type. + + + + +Template Specialization for Handle that represents a type-less Handle. + + + + +Converts to true if this is a valid Handle. + + + + +Native ID type of a handle + + + + +Base implementation of the Handle that is not templated to allow for holding +generic non-type-specific Handles. + + + + +Exception thrown when a generic Handle is being casted to the wrong type. + + + + +Exception thrown when an invalid Handle was dereferenced. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/bin/Release/SHADE_CSharp.xml b/bin/Release/SHADE_CSharp.xml new file mode 100644 index 00000000..daeaa3c5 --- /dev/null +++ b/bin/Release/SHADE_CSharp.xml @@ -0,0 +1,1029 @@ + + + + SHADE_CSharp + + + + + Interface for a CallbackAction that all variants inherit from. + + + + + Whether or not this CallbackAction is runtime assigned. If it is, then the + TargetMethodName and TargetObject properties are invalid. + + + + + Name of the method that this CallbackAction is using. + + + + + Object which the specified target method is called on. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 1 parameter. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 2 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 3 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 4 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 5 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 6 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 7 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 8 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 9 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Represents a function call that can be serialised and put togetheer with scripts. + This variant accepts functions with 10 parameters. + + + + + + + + + + + + + + Constructs an empty Callback action. + + + + + Constructs a CallbackAction that represents a call to the specified static + method. + + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a CallbackAction that represents a call to a specified member + method on the specified target. + + Object to call the method on. + Method to call. + + Thrown if a method that is not compatible with the target is specified. The method's + source type must match the target's type. + + + + + Constructs a Callback action based on an action. + + Action that wraps a function to be called. + + + + Invokes the CallbackAction's stored method/action with the specified parameters. + + + + + Interface for a CallbackEvent that all variants inherit from. + + + + + Registers an empty ICallbackAction. + + + + + Registers an ICallbackAction with the event such that it will be called in + future + + ICallbackAction to register with. + + + + Deregisters an ICallbackAction that was previously added. This should + only emit a warning if an action that was not previous added was + provided. + + ICallbackAction to remove. + + + + Iterable set of ICallbackActions that were registered to this event. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + + A container of CallbackActions that is correlated to a specific scenario as + specified by the user of this class. + This variant accepts CallbackEvents with 1 generic parameter. + + + + + + + + + + + + + + Adds a CallbackAction into the event. + + CallbackAction to add. + + + + Constructs and adds a CallbackACtion into the event. + + System.Action to add as a CallbackAction. + + + + Constructs and adds a CallbackACtion into the event. + + Object to call the method on. + Method to call. + + + + + + + Invokes all stored CallbackActions with the specified parameters. + + + + diff --git a/bin/Release/SHADE_Managed.xml b/bin/Release/SHADE_Managed.xml new file mode 100644 index 00000000..7b653116 --- /dev/null +++ b/bin/Release/SHADE_Managed.xml @@ -0,0 +1,6250 @@ + + + + "SHADE_Managed" + + + + +Retrieves the duration that the specified key has not been held or was last +not been held for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has been held or was last held +for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has not been held or was last +not been held for. + + The key to check. + Time in seconds that the key was held. + + + +Retrieves the duration that the specified key has been held or was last held +for. + + The key to check. + Time in seconds that the key was held. + + + +Sets the position of the mouse cursor relative to the top left corner of the +window. + + +Position of the mouse in window pixel coordinates to set. + + + + +Checks if a specified mouse button is no longer pressed and was pressed +before. + + MouseCode of the mouse button to check. + +True during the frame the user releases the given mouse button. + + + + +Checks if a specified mouse button is pressed and was not pressed before. + + MouseCode of the mouse button to check. + +True during the frame the user pressed the given mouse button. + + + + +Checks if a specified mouse button is being held down. +This will also be true if GetMouseButtonDown() is true. + + MouseCode of the mouse button to check. + True while the user holds down the mouse button specified. + + + +Checks if a specified key is no longer pressed pressed and was pressed +before. + + KeyCode of the key to check. + +True during the frame the user releases the key identified by name. + + + + +Checks if a specified key is pressed and was not pressed before. + + KeyCode of the key to check. + +True during the frame the user starts pressing down the key specified. + + + + +Checks if a specified key is being held down. +This will also be true if GetKeyDown() is true. + + KeyCode of the key to check. + True while the user holds down the key specified. + + + +Amnount of vertical mouse scroll in this frame. + + + + +Mouse position in screen coordinates relative to the top left of the window. +This value is a Vector3 for compatibility with functions that have Vector3 +arguments. The z component of the Vector3 is always 0 + + + + +Represents the available supported mouse keycodes that can be passed into the +mouse-button-based Input functions. + + + + +Represents the available supported keycodes that can be passed into the +key-based Input functions. + +Attempting to follow https://docs.unity3d.com/ScriptReference/KeyCode.html +Win32 keycodes are shift-insensitive, i.e. 'A' and 'a' are the same keycode and '1' and '!' are the same keycode + + + + +Static class responsible for providing access to Input-related functionality. + + + + +Simple attribute to mark that a field in a Script should be serialised. + + + + +Cleans up all required components for managed code. + + + + +Reloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. +Equivalent to calling UnloadScriptAssembly() and then LoadScriptAssembly(). + + + + +Loads the managed script assembly. Ensure this is only called after +UnloadScriptAssembly() has been called. + + + + +Unloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Initialises all required components for managed code. + + + + +Name of the Managed Library that contains the C# scripts written externally. + + + + +Static class that contains the functions for interfacing with the core +PlushieEngine written in C++ for managing the lifecycle of managed code. + + + + +Default Constructor + + + + +Custom AssemblyLoadContext marked as collectible so that it can be unloaded. + + + + +Time taken for Physics simulations. You should use this for operations +within Script.FixedUpdate() + + + + +Time taken to process the previous frame. + + + + +Static class that contains the functions for working with time. + + + + +Static class that wraps up certain functions in the SHPhysicsSystem so that +accessing it from SHADE_Managed would not cause issues due to C++20 features. + + + + +Constructor for a Tooltip attribute that fills in the description. + + Text to be shown when a field is hovered. + + + +Description that is to be shown in the Tooltip. + + + + +Simple attribute to provide a field in a script with a tooltip. + + + + +Checks if a specified file exists. + + File path to the file to check. + True if the file exists + + + +Deletes the folder and all files in it as specified by the file path. + + File path to the file to delete. + + + +Deletes the file as specified by the file path. + + File path to the file to delete. + + + +Reads the file via the specified path that represents a build log of error +and warning messages. + + +File path to the build log of script builds done by BuildScriptAssembly() to +dump and process. + + + + +Registers events for the scripting system + + + + +Loads all the function pointers to CLR code that we need to execute. + + + + +Generates a .csproj file for editing and compiling the C# scripts. + + File path to the generated file. + + + +Utilises execution of a external batch file for invoking the dotnet build +tool to compile C# scripts in the Assets folder into the SHADE_Scripting +C# assembly DLL. + + +Whether or not a debug build will be built. Only debug built C# assemblies +can be debugged. + + +Whether or not we are reloading the assembly, if so, unload and then reload it. + + Whether or not the build succeeded. + + + +Performs a redo for script inspector changes if it exists. + + + + +Performs an undo for script inspector changes if it exists. + + + + +Renders the set of attached Scripts for the specified Entity into the +inspector. +
+This function is meant for consumption from native code in the inspector +rendering code. +
+ The Entity to render the Scripts of. +
+ + +Creates scripts and sets fields for the specified Entity based on the specified +YAML node. + + The Entity to deserialise a Script on to. + +YAML Node that contains the serialised script data. + + True if successfully deserialised. + + + +Performs serialization of all scripts for the specified entity into the +YAML::Node specified. This node will contain all serialised scripts after +calling this function. + + The Entity to Serialise. + +YAML Node that will store the serialised scripts. + + True if successfully serialised. + + + +Removes all Scripts attached to the specified Entity. Unlike +RemoveAllScripts(), this removes all the scripts immediately. +Does not do anything if the specified Entity is invalid or does not have any +Scripts attached. + + The entity to remove the scripts from. + +Whether or not to call OnDestroy on the scripts. This is ignored if not in +play mode. + + + + +Removes all Scripts attached to the specified Entity. Does not do anything +if the specified Entity is invalid or does not have any Scripts +attached. + + The entity to remove the scripts from. + + + +Adds a Script to a specified Entity. Note that while you can call this +multiple times on a specified Entity, it will work for all intents and +purposes but GetScript<T>() (C# only) currently only +gives you the first Script added of the specified type. + + The entity to add a script to. + Type name of the script to add. + +True if successfully added. False otherwise with the error logged to the +console. + + + + +Shuts down the DotNetRuntime. + + + + +Executes the OnCollision*()s and OnTrigger*()s of the Scripts that are attached +to Entities. + + + + +Executes the FixedUpdate()s of the Scripts that are attached to +Entities. + + + + +Reloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Unloads the managed script assembly. +Take note that this will clear all existing scripts, ensure that the scene +is saved before doing so. + + + + +Loads the managed script assembly. Ensure this is only called after +UnloadScriptAssembly() has been called. + + + + +Initialises the DotNetRuntime and retrieves function pointers to all +functions on the CLR used to interface with the engine. + + + + +Manages initialisation of the DotNetRuntime and interfacing with CLR code written +and executed on .NET. + + + + +Deserialises a YAML node that contains a map of Scripts and copies the +deserialised data into the specified object if there are matching fields. + + +The JSON string that contains the data to copy into this Script object. + + The object to copy deserialised data into. + + + +Creates a JSON node that represents the specified object and its associated +serialisable fields. Public fields and fields marked with the SerialiseField +attribute will be serialised. + + The object to serialise. + + + +Checks if a specified field is a candidate for serialisation. This means that +the field is public or private with the [SerialiseField] attribute. + + The field to check. + +True if the specified field is a candidate for serialisation. + + + + +Retrieves a set of all non-static (instance) fields from a specified object. + + The object to get non-static fields from. + Immutable list of non-static fields. + + + +Contains useful static functions for working with Reflection. + + + +Converts the node to a YAML string. + + +Emits the node to the given output stream. + + +Emits the node to the given {@link Emitter}. If there is an error in writing, +{@link Emitter#good} will return false. + + + + Loads the input file as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + @throws {@link BadFile} if the file cannot be loaded. + + + + Loads the input stream as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a list of YAML documents. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input file as a single YAML document. + + @throws {@link ParserException} if it is malformed. + @throws {@link BadFile} if the file cannot be loaded. + + + + Loads the input stream as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + + Loads the input string as a single YAML document. + + @throws {@link ParserException} if it is malformed. + + + +Handles a "TAG" directive, which should be of the form 'handle prefix', +where 'handle' is converted to 'prefix' in the file. + + + +Handles a "YAML" directive, which should be of the form 'major.minor' (like +a version number). + + + +Reads any directives that are next in the queue, setting the internal +{@code m_pDirectives} state. + + + + Handles the next document by calling events on the {@code eventHandler}. + + @throw a ParserException on error. + @return false if there are no more documents + + + +Resets the parser with the given input stream. Any existing state is +erased. + + + +Evaluates to true if the parser has some valid input to be read. + + +Constructs a parser from the given input stream. The input stream must +live as long as the parser. + + + +Constructs an empty parser (with no input. + + +A parser turns a stream of bytes into one stream of "events" per YAML +document in the input stream. + + + + +Renders a context menu when right clicked for the scripts + + The Entity to render the Scripts of. + The Script to render the inspector for. + + + +Renders a field specified into the inspector. + + The field to render. + +The object that contains the data of the field to render. + + + + +Renders a single specified Script's inspector. + + The Entity to render the Scripts of. + The Script to render the inspector for. + +Indices used internally to differentiate each rendered Script +inspector. This is required to open and close each Script's inspector +independently from each other. + + + + +Redoes the last script inspector change if there is any. + + + + +Undoes the last script inspector change if there is any. + + + + +Renders a dropdown button that allows for the addition of PlushieScripts +onto the specified Entity. + + The Entity to add PlushieScripts to. + + + +Renders the set of attached Scripts for the specified Entity into the +inspector. +
+This function is meant for consumption from native code in the inspector +rendering code. +
+ The Entity to render the Scripts of. +
+ + +Static class for Editor-related functions + + + + +Processes a YAML node that contains a list of multiple scripts to be loaded +into the specified Entity. +

+This function should only be called from native unmanaged code. +
+ +The Entity to attach the deserialised Scripts to. + + +Pointer to the YAML::Node that contains serialized script data. + + +
+ + +Populates a YAML node with the scripts for a specified Entity. +

+This function should only be called from native unmanaged code. +
+ The Entity to Serialise. + +Pointer to a YAML::Node that will be populated with all of the serialised +scripts and their associated fields. + + +True if serialisation is successful. False if the buffer is too small for +the serialised output. + +
+ + +Executes OnCollision*() and OnTrigger*() for all scripts. + + + + +Executes LateUpdate() for all scripts. + + + + +Executes Update() for all scripts. + + + + +Executes FixedUpdate() for all scripts. + + + + +Retrieves a immutable list of available scripts that can be added. + + Immutable list of available scripts that can be added. + + + +Cleans up data stored in the ScriptStore to free up memory for garbage +collection. + + + + +Cleans up scripts that were marked for deletion. This calls the OnDestroy() +for these Scripts. + + + + +Sets up scripts that were marked for initialization. This calls the Awake() +and Start() for Scripts that have yet to have done so. + + + + +Initializes the ScriptStore to allocate and pre-populate reflection data. + + + + +Removes all Scripts attached to the specified Entity. Unlike +RemoveAllScripts(), this removes all the scripts immediately. +Does not do anything if the specified Entity is invalid or does not have any +Scripts attached. + + The entity to remove the scripts from. + +Whether or not to call OnDestroy on the scripts.This is ignored if not in +play mode. + + + + +Removes all Scripts attached to the specified Entity. Does not do anything +if the specified Entity is invalid or does not have any Scripts +attached. + + The entity to remove the scripts from. + + + +Removes a specific script from the + + The entity to remove the script from. + The script to remove. + True if successfully removed. False otherwise. + + + +Removes all Scripts of the specified type from the specified Entity. + + +Type of script to remove. +This needs to be a default constructable Script. + + The entity to remove the script from. + +If the specified Entity is invalid. + + + + +Retrieves an immutable list of all scripts attached to a specified Entity. + + +The entity which the scripts to retrieve are attached. + + +Immutable list of references to scripts attached to the specified Entity. +This can also be null if there are no scripts at all or an invalid Entity +was specified. + + + + +Retrieves a immutable list of scripts from the specified Entity that +matches the specified type. +
+Note that this function allocates. It should be used sparingly. +
+ +Type of scripts to get. +This needs to be a default constructable Script. + + +The entity which the scripts to retrieve are attached. + + +Immutable list of references to scripts of the specified type. + +
+ + +Retrieves the first Script from the specified Entity's children that matches +the specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + +The entity which the script to retrieve is attached. + + +Reference to the script. This can be null if no script of the specified +type is attached. + + +If the specified Entity is invalid. + + + + +Retrieves the first Script from the specified Entity that matches the +specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + +The entity which the script to retrieve is attached. + + +Reference to the script. This can be null if no script of the specified +type is attached. + + +If the specified Entity is invalid. + + + + +Adds a Script to a specified Entity. +
+This function is meant for consumption from native code or for serialisation +purposes. If you are writing in C# or C++/CLI and not doing serialisation, +use AddScript<T>() instead as it is faster. +
+ The entity to add a script to. + The entity to add a script to. + +Out parameter handle to the Script that was created. + + +True if successfully added. False otherwise with the error logged to the +console. + +
+ + +Adds a Script to a specified Entity. +
+This function is meant for consumption from native code. If you are writing +in C# or C++/CLI, use AddScript<T>() instead as it is faster. +
+ The entity to add a script to. + The entity to add a script to. + +True if successfully added. False otherwise with the error logged to the +console. + +
+ + +Adds a Script to a specified Entity. + + +Type of script to add. +This needs to be a default constructable PlushieScript. + + The entity to add a script to. + Reference to the script added. + +If the specified Entity is invalid. + + + + +Responsible for managing all scripts attached to Entities as well as executing +all lifecycle functions of scripts. + + + + +Checks if two Colors are not approximately equal. + + Color to compare. + Another Color to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Colors are approximately equal. + + Color to compare. + Another Color to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Color with a scalar value and returns +the result. + + Scalar to divide with. + Color to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Color with a scalar value and returns +the result. + + Color to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Colors and returns the +result. + + Color to multiply with. + Another Color to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Color from another Color and returns the result. + + Color to subtract from. + Another Color to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Colors together and returns the result. + + Color to add. + Another Color to add. + The result of lhs added to rhs + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Color, returned when t = 0.0. + The end Color, returned when t = 1.0. + Value used to interpolate between a and b. + The interpolated Color. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Color, returned when t = 0.0. + The end Color, returned when t = 1.0. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector3. + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Alpha component of the colour. Ranges from 0.0f to 1.0f. + + + + +Blue component of the colour. Ranges from 0.0f to 1.0f. + + + + +Green component of the colour. Ranges from 0.0f to 1.0f. + + + + +Red component of the colour. Ranges from 0.0f to 1.0f. + + + + +Constructor to construct a Color with the specified components. + + Red component to set. + Green component to set. + Blue component to set. + Alpha component to set. + + + +Constructor to construct a Color with the specified components with the +alpha component set to 1.0f. + + Red component to set. + Green component to set. + Blue component to set. + + + +Constructor to construct a Color with the specified components with the +blue and alpha component set to 1.0f. + + Red component to set. + Green component to set. + + + +Constructor to construct a Color with the specified components with the +green, blue and alpha component set to 1.0f. + + Red component to set. + + + +Pure yellow, mix of pure red and green. + + + + +Pure magenta, mix of pure red and blue. + + + + +Pure cyan, mix of pure green and blue. + + + + +Pure blue. + + + + +Pure green. + + + + +Pure red. + + + + +Pure white. + + + + +Dark Gray, darker than gray. + + + + +Gray, halfway between black and white. + + + + +Light Gray, lighter than gray. + + + + +Pure black. + + + + +A static class that contains a set of default Colors. + + + + +CLR version of the the SHADE Engine's Color struct which describes a Color +encoded using floating point numbers that range from 0.0f to 1.0f. + + + + +Creates a inline button widget. +
+Wraps up ImGui::Button(). +
+ Text to display. + True if button was pressed. +
+ + +Creates a small inline button widget. +
+Wraps up ImGui::SmallButton(). +
+ Text to display. + True if button was pressed. +
+ + +Creates a visual text widget. +
+Wraps up ImGui::Text(). +
+ Text to display. +
+ + +Creates a menu item in the list of items for a mini popup. +
+Wraps up ImGui::MenuItem(). +
+ Label used to identify this widget. + Whether or not the menu item was selected. +
+ + +Opens the popup that was defined with the specified label. +
+Wraps up ImGui::OpenPopup(). +
+
+ + +Marks the end of a definition of a mini pop up that can show options. +
+Wraps up ImGui::EndPopup(). +
+
+ + +Marks the start of a definition of a mini pop up that can show options. +
+Wraps up ImGui::BeginPopup(). +
+ Label used to identify this widget. + Whether or not the pop up is open. +
+ + +Creates a collapsing title header. +
+Wraps up ImGui::CollapsingHeader(). +
+ Label for the header. + True if the header is open, false otherwise. +
+ + +Unindents the widgets rendered after this call. +
+Wraps up ImGui::Unindent(). +
+
+ + +Indents the widgets rendered after this call. +
+Wraps up ImGui::Indent(). +
+
+ + +Marks the end of a stack of ImGui widgets from the last PushID() call. +
+Wraps up ImGui::PopID(). +
+
+ + +Marks the start of a stack of ImGui widgets with the specified id. +
+Wraps up ImGui::PushID(). +
+ Integer-based ID. +
+ + +Marks the start of a stack of ImGui widgets with the specified id. +
+Wraps up ImGui::PushID(). +
+ String-based ID. +
+ + +Maximum length of a string supported by InputTextField() + + + + +Static class that contains useful functions for Editor UI using ImGui. + + + + +Redoes the last undo-ed command if it exists. + + + + +Undos the last added command if it exists. + + + + +Adds a command onto the stack. + + + + + +True if there is a redoable action in the stack. + + + + +True if there is an undoable action in the stack. + + + + +Command for the stack that represents a data modification. + + + + +Class that is able to store a stack of actions that can be done and redone. + + + + +To be called from native code when a Collision Shape has been changed. + + +The entity which has it's collision shape changed. + + + + +To be called from native code when a collision shape has been removed. + + The entity which has it's collision shape removed. + + + +Retrieves a ColliderBound at the specified index in the ColliderBound list +and casts it to the appropriate type. + + Type of the ColliderBound to cast to. + Index to retrieve a ColliderBound from. + ColliderBound for the specified index. + + + +Retrieves a ColliderBound at the specified index in the ColliderBound list. + + Index to retrieve a ColliderBound from. + ColliderBound for the specified index. + + + +Total number of ColliderShapes in the Collider component. + + + + +Constructs a Collider Component that represents a native SHColliderComponent +component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the the SHADE Engine's SHColliderComponent. +A single Collider component can contain one or multiple Collider Bounds. + + + + + + + + + + +Radius of the Bounding Sphere formed by this bound. + + + + +Center of the Bounding Sphere formed by this bound. + + + + +Sphere-shaped Collider Bound. + + + + + + + + + + +Position of the top right front corner of the Bounding Box formed by this +bound. + + + + +Position of the bottom left back corner of the Bounding Box formed by this +bound. + + + + +Half of the scale of the Bounding Box formed by this bound. + + + + +Center of the Bounding Box formed by this bound. + + + + +Box-shaped Collider Bound. + + + + +Computes a Raycast and checks if there is a collision with any object. + + The ray to cast. + Maximum distance for the raycast check. + True if the ray intersects with an object in the scene. + + + +Checks if the specified point is within this shape's bounds. + + Point to test with. + True if the point is in the shape's bounds. + + + +Base interface for all Collider Shapes. + + + +@brief The density of the collider that determines the mass of the collision shape + if it is automatically computed. Must be a positive number. + + + +@brief The bounciness factor of the physics object., clamped between [0,1].
+ 0 means the object will never bounce. + 1 means the object never loses energy on a bounce. + +
+ +@brief The friction coefficient of the physics object., clamped between [0,1].
+ 0 means the object will never experience friction. + 1 means the friction force against the object is equal to the applied force. + +
+ +@brief Sets the mass density of the physics material. +@param newDensity The density value to set. Always made positive. + + + +@brief Sets the bounciness factor of the physics material. +@param newBounciness The bounciness value to set. Clamped between [0,1]. + + + +@brief Sets the friction coefficient of the physics material. +@param newFriction The friction value to set. Clamped between [0,1]. + + + +@brief Default constructor for a physics material. +@param friction The friction of the material. Clamped between [0,1]. Defaults to 0.4. +@param bounciness The bounciness of the material. Clamped between [0,1]. +@param density The mass density of the material. Always made positive. + + + + +Closes the current window, and depending on the implementation, should also +close the application. + + + + +Retrieves the current window fullscreen status. + + The current window fullscreen status.. + + + +Retrieves the current window height. + + The current window height. + + + +Retrieves the current window width. + + The current window width. + + + +Static class that wraps up certain functions in the SHGraphicsSystem so that +accessing it from SHADE_Managed would not cause issues due to C++20 features. + + + + @brief Perform ImGui and ImGui Backend Render + + + + + @brief Start new frame for editor + + + + + @brief Initialise Backend for ImGui (SDL and Vulkan backend) + + @param sdlWindow Pointer to SDL_Window + + + + @brief Set the Style for the editor + + @param style Desired style + + + + @brief Safely shutdown the editor + + + + + @brief Update the editor and add to ImGui DrawList + + @param dt Delta-time of the frame + + + + @brief Initialise the editor + + @param sdlWindow pointer to SDL_Window object created in application + + + + @brief Style options + + + + + @brief SHEditor static class contains editor variables and implementation of editor functions. + + + + + Get the YUV conversion mode, returning the correct mode for the resolution + when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + + \since This function is available since SDL 2.0.8. + + + + Get the YUV conversion mode + + \since This function is available since SDL 2.0.8. + + + + Set the YUV conversion mode + + \since This function is available since SDL 2.0.8. + + + + Perform low-level surface scaled blitting only. + + This is a semi-private function and it performs low-level surface blitting, + assuming the input rectangles have already been clipped. + + \param src the SDL_Surface structure to be copied from + \param srcrect the SDL_Rect structure representing the rectangle to be + copied + \param dst the SDL_Surface structure that is the blit target + \param dstrect the SDL_Rect structure representing the rectangle that is + copied into + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitScaled + + + + Perform a scaled surface copy to a destination surface. + + SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is + merely a macro for this function with a less confusing name. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitScaled + + + + Perform bilinear scaling between two surfaces of the same format, 32BPP. + + \since This function is available since SDL 2.0.16. + + + + Perform a fast, low quality, stretch blit between two surfaces of the same + format. + + Please use SDL_BlitScaled() instead. + + \since This function is available since SDL 2.0.0. + + + + Perform low-level surface blitting only. + + This is a semi-private blit function and it performs low-level surface + blitting, assuming the input rectangles have already been clipped. + + Unless you know what you're doing, you should be using SDL_BlitSurface() + instead. + + \param src the SDL_Surface structure to be copied from + \param srcrect the SDL_Rect structure representing the rectangle to be + copied, or NULL to copy the entire surface + \param dst the SDL_Surface structure that is the blit target + \param dstrect the SDL_Rect structure representing the rectangle that is + copied into + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + + + + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \returns 0 if the blit is successful, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + + Perform a fast blit from the source surface to the destination surface. + + SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a + macro for this function with a less confusing name. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + + + + Perform a fast fill of a set of rectangles with a specific color. + + `color` should be a pixel of the format used by the surface, and can be + generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + alpha component then the destination is simply filled with that alpha + information, no blending takes place. + + If there is a clip rectangle set on the destination (set via + SDL_SetClipRect()), then this function will fill based on the intersection + of the clip rectangle and `rect`. + + \param dst the SDL_Surface structure that is the drawing target + \param rects an array of SDL_Rects representing the rectangles to fill. + \param count the number of rectangles in the array + \param color the color to fill with + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FillRect + + + + Perform a fast fill of a rectangle with a specific color. + + `color` should be a pixel of the format used by the surface, and can be + generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + alpha component then the destination is simply filled with that alpha + information, no blending takes place. + + If there is a clip rectangle set on the destination (set via + SDL_SetClipRect()), then this function will fill based on the intersection + of the clip rectangle and `rect`. + + \param dst the SDL_Surface structure that is the drawing target + \param rect the SDL_Rect structure representing the rectangle to fill, or + NULL to fill the entire surface + \param color the color to fill with + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FillRects + + + + Premultiply the alpha on a block of pixels. + + This is safe to use with src == dst, but not for other overlapping areas. + + This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. + + \param width the width of the block to convert, in pixels + \param height the height of the block to convert, in pixels + \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + \param src a pointer to the source pixels + \param src_pitch the pitch of the source pixels, in bytes + \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + \param dst a pointer to be filled in with premultiplied pixel data + \param dst_pitch the pitch of the destination pixels, in bytes + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.18. + + + + Copy a block of pixels of one format to another format. + + \param width the width of the block to copy, in pixels + \param height the height of the block to copy, in pixels + \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + \param src a pointer to the source pixels + \param src_pitch the pitch of the source pixels, in bytes + \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + \param dst a pointer to be filled in with new pixel data + \param dst_pitch the pitch of the destination pixels, in bytes + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + + + Copy an existing surface to a new surface of the specified format enum. + + This function operates just like SDL_ConvertSurface(), but accepts an + SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, + it might be easier to call but it doesn't have access to palette + information for the destination surface, in case that would be important. + + \param src the existing SDL_Surface structure to convert + \param pixel_format the SDL_PixelFormatEnum that the new surface is + optimized for + \param flags the flags are unused and should be set to 0; this is a + leftover from SDL 1.2's API + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + \sa SDL_ConvertSurface + \sa SDL_CreateRGBSurface + + + + Copy an existing surface to a new surface of the specified format. + + This function is used to optimize images for faster *repeat* blitting. This + is accomplished by converting the original and storing the result as a new + surface. The new, optimized surface can then be used as the source for + future blits, making them faster. + + \param src the existing SDL_Surface structure to convert + \param fmt the SDL_PixelFormat structure that the new surface is optimized + for + \param flags the flags are unused and should be set to 0; this is a + leftover from SDL 1.2's API + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + \sa SDL_ConvertSurfaceFormat + \sa SDL_CreateRGBSurface + + + + Get the clipping rectangle for a surface. + + When `surface` is the destination of a blit, only the area within the clip + rectangle is drawn into. + + \param surface the SDL_Surface structure representing the surface to be + clipped + \param rect an SDL_Rect structure filled in with the clipping rectangle for + the surface + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_SetClipRect + + + + Set the clipping rectangle for a surface. + + When `surface` is the destination of a blit, only the area within the clip + rectangle is drawn into. + + Note that blits are automatically clipped to the edges of the source and + destination surfaces. + + \param surface the SDL_Surface structure to be clipped + \param rect the SDL_Rect structure representing the clipping rectangle, or + NULL to disable clipping + \returns SDL_TRUE if the rectangle intersects the surface, otherwise + SDL_FALSE and blits will be completely clipped. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_GetClipRect + + + + Get the blend mode used for blit operations. + + \param surface the SDL_Surface structure to query + \param blendMode a pointer filled in with the current SDL_BlendMode + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_SetSurfaceBlendMode + + + + Set the blend mode used for blit operations. + + To copy a surface to another surface (or texture) without blending with the + existing data, the blendmode of the SOURCE surface should be set to + `SDL_BLENDMODE_NONE`. + + \param surface the SDL_Surface structure to update + \param blendMode the SDL_BlendMode to use for blit blending + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceBlendMode + + + + Get the additional alpha value used in blit operations. + + \param surface the SDL_Surface structure to query + \param alpha a pointer filled in with the current alpha value + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceColorMod + \sa SDL_SetSurfaceAlphaMod + + + + Set an additional alpha value used in blit operations. + + When this surface is blitted, during the blit operation the source alpha + value is modulated by this alpha value according to the following formula: + + `srcA = srcA * (alpha / 255)` + + \param surface the SDL_Surface structure to update + \param alpha the alpha value multiplied into blit operations + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceAlphaMod + \sa SDL_SetSurfaceColorMod + + + + Get the additional color value multiplied into blit operations. + + \param surface the SDL_Surface structure to query + \param r a pointer filled in with the current red color value + \param g a pointer filled in with the current green color value + \param b a pointer filled in with the current blue color value + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceAlphaMod + \sa SDL_SetSurfaceColorMod + + + + Set an additional color value multiplied into blit operations. + + When this surface is blitted, during the blit operation each source color + channel is modulated by the appropriate color value according to the + following formula: + + `srcC = srcC * (color / 255)` + + \param surface the SDL_Surface structure to update + \param r the red color value multiplied into blit operations + \param g the green color value multiplied into blit operations + \param b the blue color value multiplied into blit operations + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetSurfaceColorMod + \sa SDL_SetSurfaceAlphaMod + + + + Get the color key (transparent pixel) for a surface. + + The color key is a pixel of the format used by the surface, as generated by + SDL_MapRGB(). + + If the surface doesn't have color key enabled this function returns -1. + + \param surface the SDL_Surface structure to query + \param key a pointer filled in with the transparent pixel + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_SetColorKey + + + + Returns whether the surface has a color key + + It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + + \param surface the SDL_Surface structure to query + \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.9. + + \sa SDL_SetColorKey + \sa SDL_GetColorKey + + + + Set the color key (transparent pixel) in a surface. + + The color key defines a pixel value that will be treated as transparent in + a blit. For example, one can use this to specify that cyan pixels should be + considered transparent, and therefore not rendered. + + It is a pixel of the format used by the surface, as generated by + SDL_MapRGB(). + + RLE acceleration can substantially speed up blitting of images with large + horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. + + \param surface the SDL_Surface structure to update + \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key + \param key the transparent pixel + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_GetColorKey + + + + Returns whether the surface is RLE enabled + + It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + + \param surface the SDL_Surface structure to query + \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.14. + + \sa SDL_SetSurfaceRLE + + + + Save a surface to a file. + + Convenience macro. + + Set the RLE acceleration hint for a surface. + + If RLE is enabled, color key and alpha blending blits are much faster, but + the surface must be locked before directly accessing the pixels. + + \param surface the SDL_Surface structure to optimize + \param flag 0 to disable, non-zero to enable RLE acceleration + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_BlitSurface + \sa SDL_LockSurface + \sa SDL_UnlockSurface + + + + Load a surface from a file. + + Convenience macro. + + Save a surface to a seekable SDL data stream in BMP format. + + Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + BMP directly. Other RGB formats with 8-bit or higher get converted to a + 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + not supported. + + \param surface the SDL_Surface structure containing the image to be saved + \param dst a data stream to save to + \param freedst non-zero to close the stream after being written + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_LoadBMP_RW + \sa SDL_SaveBMP + + + + Load a BMP image from a seekable SDL data stream. + + The new surface should be freed with SDL_FreeSurface(). Not doing so will + result in a memory leak. + + src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. + Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap + from a file, convert it to an SDL_Surface and then close the file. + + \param src the data stream for the surface + \param freesrc non-zero to close the stream after being read + \returns a pointer to a new SDL_Surface structure or NULL if there was an + error; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeSurface + \sa SDL_RWFromFile + \sa SDL_LoadBMP + \sa SDL_SaveBMP_RW + + + + Release a surface after directly accessing the pixels. + + \param surface the SDL_Surface structure to be unlocked + + \since This function is available since SDL 2.0.0. + + \sa SDL_LockSurface + + + + Set up a surface for directly accessing the pixels. + + Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to + and read from `surface->pixels`, using the pixel format stored in + `surface->format`. Once you are done accessing the surface, you should use + SDL_UnlockSurface() to release it. + + Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to + 0, then you can read and write to the surface at any time, and the pixel + format of the surface will not change. + + \param surface the SDL_Surface structure to be locked + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_MUSTLOCK + \sa SDL_UnlockSurface + + + + Set the palette used by a surface. + + A single palette can be shared with many surfaces. + + \param surface the SDL_Surface structure to update + \param palette the SDL_Palette structure to use + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + + + Free an RGB surface. + + It is safe to pass NULL to this function. + + \param surface the SDL_Surface to free. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_LoadBMP + \sa SDL_LoadBMP_RW + + + + Allocate a new RGB surface with with a specific pixel format and existing + pixel data. + + This function operates mostly like SDL_CreateRGBSurfaceFrom(), except + instead of providing pixel color masks, you provide it with a predefined + format from SDL_PixelFormatEnum. + + No copy is made of the pixel data. Pixel data is not managed automatically; + you must free the surface before you free the pixel data. + + \param pixels a pointer to existing pixel data + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param pitch the pitch of the surface in bytes + \param format the SDL_PixelFormatEnum for the new surface's pixel format. + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.5. + + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + + Allocate a new RGB surface with existing pixel data. + + This function operates mostly like SDL_CreateRGBSurface(), except it does + not allocate memory for the pixel data, instead the caller provides an + existing buffer of data for the surface to use. + + No copy is made of the pixel data. Pixel data is not managed automatically; + you must free the surface before you free the pixel data. + + \param pixels a pointer to existing pixel data + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param pitch the pitch of the surface in bytes + \param Rmask the red mask for the pixels + \param Gmask the green mask for the pixels + \param Bmask the blue mask for the pixels + \param Amask the alpha mask for the pixels + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + + Allocate a new RGB surface with a specific pixel format. + + This function operates mostly like SDL_CreateRGBSurface(), except instead + of providing pixel color masks, you provide it with a predefined format + from SDL_PixelFormatEnum. + + \param flags the flags are unused and should be set to 0 + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param format the SDL_PixelFormatEnum for the new surface's pixel format. + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.5. + + \sa SDL_CreateRGBSurface + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_FreeSurface + + + + Allocate a new RGB surface. + + If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. + If `depth` is greater than 8 bits, the pixel format is set using the + [RGBA]mask parameters. + + The [RGBA]mask parameters are the bitmasks used to extract that color from + a pixel. For instance, `Rmask` being 0xFF000000 means the red data is + stored in the most significant byte. Using zeros for the RGB masks sets a + default value, based on the depth. For example: + + ```c++ + SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); + ``` + + However, using zero for the Amask results in an Amask of 0. + + By default surfaces with an alpha mask are set up for blending as with: + + ```c++ + SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) + ``` + + You can change this by calling SDL_SetSurfaceBlendMode() and selecting a + different `blendMode`. + + \param flags the flags are unused and should be set to 0 + \param width the width of the surface + \param height the height of the surface + \param depth the depth of the surface in bits + \param Rmask the red mask for the pixels + \param Gmask the green mask for the pixels + \param Bmask the blue mask for the pixels + \param Amask the alpha mask for the pixels + \returns the new SDL_Surface structure that is created or NULL if it fails; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_CreateRGBSurfaceFrom + \sa SDL_CreateRGBSurfaceWithFormat + \sa SDL_FreeSurface + + + +Reference count -- used when freeing surface + + +info for fast blit mapping to other surfaces + + +clipping information + + +list of BlitMap that hold a reference to this surface + + +information needed for surfaces requiring locks + + +Application data associated with the surface + + + \brief A collection of pixels used in software blitting. + + \note This structure should be treated as read-only, except for \c pixels, + which, if not NULL, contains the raw pixel data for the surface. + + +\brief The type of function used for surface blitting functions. + + + + Compose a custom blend mode for renderers. + + The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept + the SDL_BlendMode returned by this function if the renderer supports it. + + A blend mode controls how the pixels from a drawing operation (source) get + combined with the pixels from the render target (destination). First, the + components of the source and destination pixels get multiplied with their + blend factors. Then, the blend operation takes the two products and + calculates the result that will get stored in the render target. + + Expressed in pseudocode, it would look like this: + + ```c + dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); + dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); + ``` + + Where the functions `colorOperation(src, dst)` and `alphaOperation(src, + dst)` can return one of the following: + + - `src + dst` + - `src - dst` + - `dst - src` + - `min(src, dst)` + - `max(src, dst)` + + The red, green, and blue components are always multiplied with the first, + second, and third components of the SDL_BlendFactor, respectively. The + fourth component is not used. + + The alpha component is always multiplied with the fourth component of the + SDL_BlendFactor. The other components are not used in the alpha + calculation. + + Support for these blend modes varies for each renderer. To check if a + specific SDL_BlendMode is supported, create a renderer and pass it to + either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will + return with an error if the blend mode is not supported. + + This list describes the support of custom blend modes for each renderer in + SDL 2.0.6. All renderers support the four blend modes listed in the + SDL_BlendMode enumeration. + + - **direct3d**: Supports all operations with all factors. However, some + factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and + `SDL_BLENDOPERATION_MAXIMUM`. + - **direct3d11**: Same as Direct3D 9. + - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL + 2.0.6. + - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + factors. Color and alpha factors need to be the same. OpenGL ES 1 + implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` + and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha + operations being different from each other. May support color and alpha + factors being different from each other. + - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, + `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` + operations with all factors. + - **psp**: No custom blend mode support. + - **software**: No custom blend mode support. + + Some renderers do not provide an alpha component for the default render + target. The `SDL_BLENDFACTOR_DST_ALPHA` and + `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this + case. + + \param srcColorFactor the SDL_BlendFactor applied to the red, green, and + blue components of the source pixels + \param dstColorFactor the SDL_BlendFactor applied to the red, green, and + blue components of the destination pixels + \param colorOperation the SDL_BlendOperation used to combine the red, + green, and blue components of the source and + destination pixels + \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of + the source pixels + \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of + the destination pixels + \param alphaOperation the SDL_BlendOperation used to combine the alpha + component of the source and destination pixels + \returns an SDL_BlendMode that represents the chosen factors and + operations. + + \since This function is available since SDL 2.0.6. + + \sa SDL_SetRenderDrawBlendMode + \sa SDL_GetRenderDrawBlendMode + \sa SDL_SetTextureBlendMode + \sa SDL_GetTextureBlendMode + + + + Calculate the intersection of a rectangle and line segment with float + precision. + + This function is used to clip a line segment to a rectangle. A line segment + contained entirely within the rectangle or that does not intersect will + remain unchanged. A line segment that crosses the rectangle at either or + both ends will be clipped to the boundary of the rectangle and the new + coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + + \param rect an SDL_FRect structure representing the rectangle to intersect + \param X1 a pointer to the starting X-coordinate of the line + \param Y1 a pointer to the starting Y-coordinate of the line + \param X2 a pointer to the ending X-coordinate of the line + \param Y2 a pointer to the ending Y-coordinate of the line + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + + + Calculate a minimal rectangle enclosing a set of points with float + precision. + + If `clip` is not NULL then only points inside of the clipping rectangle are + considered. + + \param points an array of SDL_FPoint structures representing points to be + enclosed + \param count the number of structures in the `points` array + \param clip an SDL_FRect used for clipping or NULL to enclose all points + \param result an SDL_FRect structure filled in with the minimal enclosing + rectangle + \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + points were outside of the clipping rectangle. + + \since This function is available since SDL 2.0.22. + + + + Calculate the union of two rectangles with float precision. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \param result an SDL_FRect structure filled in with the union of rectangles + `A` and `B` + + \since This function is available since SDL 2.0.22. + + + + Calculate the intersection of two rectangles with float precision. + + If `result` is NULL then this function will return SDL_FALSE. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \param result an SDL_FRect structure filled in with the intersection of + rectangles `A` and `B` + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + \sa SDL_HasIntersectionF + + + + Determine whether two rectangles intersect with float precision. + + If either pointer is NULL the function will return SDL_FALSE. + + \param A an SDL_FRect structure representing the first rectangle + \param B an SDL_FRect structure representing the second rectangle + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.22. + + \sa SDL_IntersectRect + + + + Returns true if the two rectangles are equal, using a default epsilon. + + \since This function is available since SDL 2.0.22. + + + + Returns true if the two rectangles are equal, within some given epsilon. + + \since This function is available since SDL 2.0.22. + + + +Returns true if the rectangle has no area. + + + +Returns true if point resides inside a rectangle. + + + + Calculate the intersection of a rectangle and line segment. + + This function is used to clip a line segment to a rectangle. A line segment + contained entirely within the rectangle or that does not intersect will + remain unchanged. A line segment that crosses the rectangle at either or + both ends will be clipped to the boundary of the rectangle and the new + coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + + \param rect an SDL_Rect structure representing the rectangle to intersect + \param X1 a pointer to the starting X-coordinate of the line + \param Y1 a pointer to the starting Y-coordinate of the line + \param X2 a pointer to the ending X-coordinate of the line + \param Y2 a pointer to the ending Y-coordinate of the line + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + + + Calculate a minimal rectangle enclosing a set of points. + + If `clip` is not NULL then only points inside of the clipping rectangle are + considered. + + \param points an array of SDL_Point structures representing points to be + enclosed + \param count the number of structures in the `points` array + \param clip an SDL_Rect used for clipping or NULL to enclose all points + \param result an SDL_Rect structure filled in with the minimal enclosing + rectangle + \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + points were outside of the clipping rectangle. + + \since This function is available since SDL 2.0.0. + + + + Calculate the union of two rectangles. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \param result an SDL_Rect structure filled in with the union of rectangles + `A` and `B` + + \since This function is available since SDL 2.0.0. + + + + Calculate the intersection of two rectangles. + + If `result` is NULL then this function will return SDL_FALSE. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \param result an SDL_Rect structure filled in with the intersection of + rectangles `A` and `B` + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + \sa SDL_HasIntersection + + + + Determine whether two rectangles intersect. + + If either pointer is NULL the function will return SDL_FALSE. + + \param A an SDL_Rect structure representing the first rectangle + \param B an SDL_Rect structure representing the second rectangle + \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + + \since This function is available since SDL 2.0.0. + + \sa SDL_IntersectRect + + + +Returns true if the two rectangles are equal. + + + +Returns true if the rectangle has no area. + + + +Returns true if point resides inside a rectangle. + + + + A rectangle, with the origin at the upper left (floating point). + + \sa SDL_FRectEmpty + \sa SDL_FRectEquals + \sa SDL_FRectEqualsEpsilon + \sa SDL_HasIntersectionF + \sa SDL_IntersectFRect + \sa SDL_IntersectFRectAndLine + \sa SDL_UnionFRect + \sa SDL_EncloseFPoints + \sa SDL_PointInFRect + + + + A rectangle, with the origin at the upper left (integer). + + \sa SDL_RectEmpty + \sa SDL_RectEquals + \sa SDL_HasIntersection + \sa SDL_IntersectRect + \sa SDL_IntersectRectAndLine + \sa SDL_UnionRect + \sa SDL_EnclosePoints + + + + The structure that defines a point (floating point) + + \sa SDL_EncloseFPoints + \sa SDL_PointInFRect + + + + Use this function to write 64 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE64 + + + + Use this function to write 64 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE64 + + + + Use this function to write 32 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE32 + + + + Use this function to write 32 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE32 + + + + Use this function to write 16 bits in native format to a SDL_RWops as + big-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in big-endian format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteLE16 + + + + Use this function to write 16 bits in native format to a SDL_RWops as + little-endian data. + + SDL byteswaps the data only if necessary, so the application always + specifies native format, and the data written will be in little-endian + format. + + \param dst the stream to which data will be written + \param value the data to be written, in native format + \returns 1 on successful write, 0 on error. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteBE16 + + + + \name Write endian functions + + Write an item of native format to the specified endianness. + + Use this function to write a byte to an SDL_RWops. + + \param dst the SDL_RWops to write to + \param value the byte value to write + \returns 1 on success or 0 on failure; call SDL_GetError() for more + information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadU8 + + + + Use this function to read 64 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 64 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE64 + + + + Use this function to read 64 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 64 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE64 + + + + Use this function to read 32 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 32 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE32 + + + + Use this function to read 32 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 32 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE32 + + + + Use this function to read 16 bits of big-endian data from an SDL_RWops and + return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 16 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadLE16 + + + + Use this function to read 16 bits of little-endian data from an SDL_RWops + and return in native format. + + SDL byteswaps the data only if necessary, so the data returned will be in + the native byte order. + + \param src the stream from which to read data + \returns 16 bits of data in the native byte order of the platform. + + \since This function is available since SDL 2.0.0. + + \sa SDL_ReadBE16 + + + + \name Read endian functions + + Read an item of the specified endianness and return in native format. + + Use this function to read a byte from an SDL_RWops. + + \param src the SDL_RWops to read from + \returns the read byte on success or 0 on failure; call SDL_GetError() for + more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_WriteU8 + + + + Load all the data from a file path. + + The data is allocated with a zero byte at the end (null terminated) for + convenience. This extra byte is not included in the value reported via + `datasize`. + + The data should be freed with SDL_free(). + + Prior to SDL 2.0.10, this function was a macro wrapping around + SDL_LoadFile_RW. + + \param file the path to read all available data from + \param datasize if not NULL, will store the number of bytes read + \returns the data, or NULL if there was an error. + + \since This function is available since SDL 2.0.10. + + + + Load all the data from an SDL data stream. + + The data is allocated with a zero byte at the end (null terminated) for + convenience. This extra byte is not included in the value reported via + `datasize`. + + The data should be freed with SDL_free(). + + \param src the SDL_RWops to read all available data from + \param datasize if not NULL, will store the number of bytes read + \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning + \returns the data, or NULL if there was an error. + + \since This function is available since SDL 2.0.6. + + + + Close and free an allocated SDL_RWops structure. + + SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any + resources used by the stream and frees the SDL_RWops itself with + SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to + flush to its output (e.g. to disk). + + Note that if this fails to flush the stream to disk, this function reports + an error, but the SDL_RWops is still invalid once this function returns. + + Prior to SDL 2.0.10, this function was a macro. + + \param context SDL_RWops structure to close + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Write to an SDL_RWops data stream. + + This function writes exactly `num` objects each of size `size` from the + area pointed at by `ptr` to the stream. If this fails for any reason, it'll + return less than `num` to demonstrate how far the write progressed. On + success, it returns `num`. + + SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's + `write` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param ptr a pointer to a buffer containing data to write + \param size the size of an object to write, in bytes + \param num the number of objects to write + \returns the number of objects written, which will be less than **num** on + error; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + + + + Read from a data source. + + This function reads up to `maxnum` objects each of size `size` from the + data source to the area pointed at by `ptr`. This function may read less + objects than requested. It will return zero when there has been an error or + the data stream is completely read. + + SDL_RWread() is actually a function wrapper that calls the SDL_RWops's + `read` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param ptr a pointer to a buffer to read data into + \param size the size of each object to read, in bytes + \param maxnum the maximum number of objects to be read + \returns the number of objects read, or 0 at error or end of file; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Determine the current read/write offset in an SDL_RWops data stream. + + SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` + method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify + application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a SDL_RWops data stream object from which to get the current + offset + \returns the current offset in the stream, or -1 if the information can not + be determined. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWwrite + + + + Seek within an SDL_RWops data stream. + + This function seeks to byte `offset`, relative to `whence`. + + `whence` may be any of the following values: + + - `RW_SEEK_SET`: seek from the beginning of data + - `RW_SEEK_CUR`: seek relative to current read point + - `RW_SEEK_END`: seek relative to the end of data + + If this stream can not seek, it will return -1. + + SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's + `seek` method appropriately, to simplify application development. + + Prior to SDL 2.0.10, this function was a macro. + + \param context a pointer to an SDL_RWops structure + \param offset an offset in bytes, relative to **whence** location; can be + negative + \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` + \returns the final offset in the data stream after the seek or -1 on error. + + \since This function is available since SDL 2.0.10. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWtell + \sa SDL_RWwrite + + + + Use this function to get the size of the data stream in an SDL_RWops. + + Prior to SDL 2.0.10, this function was a macro. + + \param context the SDL_RWops to get the size of the data stream from + \returns the size of the data stream in the SDL_RWops on success, -1 if + unknown or a negative error code on failure; call SDL_GetError() + for more information. + + \since This function is available since SDL 2.0.10. + + + + Use this function to free an SDL_RWops structure allocated by + SDL_AllocRW(). + + Applications do not need to use this function unless they are providing + their own SDL_RWops implementation. If you just need a SDL_RWops to + read/write a common data source, you should use the built-in + implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and + call the **close** method on those SDL_RWops pointers when you are done + with them. + + Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is + invalid as soon as this function returns. Any extra memory allocated during + creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must + be responsible for managing that memory in their **close** method. + + \param area the SDL_RWops structure to be freed + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocRW + + + + Use this function to allocate an empty, unpopulated SDL_RWops structure. + + Applications do not need to use this function unless they are providing + their own SDL_RWops implementation. If you just need a SDL_RWops to + read/write a common data source, you should use the built-in + implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. + + You must free the returned pointer with SDL_FreeRW(). Depending on your + operating system and compiler, there may be a difference between the + malloc() and free() your program uses and the versions SDL calls + internally. Trying to mix the two can cause crashing such as segmentation + faults. Since all SDL_RWops must free themselves when their **close** + method is called, all SDL_RWops must be allocated through this function, so + they can all be freed correctly with SDL_FreeRW(). + + \returns a pointer to the allocated memory on success, or NULL on failure; + call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeRW + + + + Use this function to prepare a read-only memory buffer for use with RWops. + + This function sets up an SDL_RWops struct based on a memory area of a + certain size. It assumes the memory area is not writable. + + Attempting to write to this RWops stream will report an error without + writing to the memory buffer. + + This memory buffer is not copied by the RWops; the pointer you provide must + remain valid until you close the stream. Closing the stream will not free + the original buffer. + + If you need to write to a memory buffer, you should use SDL_RWFromMem() + with a writable buffer of memory instead. + + \param mem a pointer to a read-only buffer to feed an SDL_RWops stream + \param size the buffer size, in bytes + \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + + + + Use this function to prepare a read-write memory buffer for use with + SDL_RWops. + + This function sets up an SDL_RWops struct based on a memory area of a + certain size, for both read and write access. + + This memory buffer is not copied by the RWops; the pointer you provide must + remain valid until you close the stream. Closing the stream will not free + the original buffer. + + If you need to make sure the RWops never writes to the memory buffer, you + should use SDL_RWFromConstMem() with a read-only buffer of memory instead. + + \param mem a pointer to a buffer to feed an SDL_RWops stream + \param size the buffer size, in bytes + \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + + Use this function to create an SDL_RWops structure from a standard I/O file + pointer (stdio.h's `FILE*`). + + This function is not available on Windows, since files opened in an + application on that platform cannot be used by a dynamically linked + library. + + On some platforms, the first parameter is a `void*`, on others, it's a + `FILE*`, depending on what system headers are available to SDL. It is + always intended to be the `FILE*` type from the C runtime's stdio.h. + + \param fp the `FILE*` that feeds the SDL_RWops stream + \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, + SDL_FALSE to leave the `FILE*` open when the RWops is + closed + \returns a pointer to the SDL_RWops structure that is created, or NULL on + failure; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFile + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + + \name RWFrom functions + + Functions to create SDL_RWops structures from various data streams. + + Use this function to create a new SDL_RWops structure for reading from + and/or writing to a named file. + + The `mode` string is treated roughly the same as in a call to the C + library's fopen(), even if SDL doesn't happen to use fopen() behind the + scenes. + + Available `mode` strings: + + - "r": Open a file for reading. The file must exist. + - "w": Create an empty file for writing. If a file with the same name + already exists its content is erased and the file is treated as a new + empty file. + - "a": Append to a file. Writing operations append data at the end of the + file. The file is created if it does not exist. + - "r+": Open a file for update both reading and writing. The file must + exist. + - "w+": Create an empty file for both reading and writing. If a file with + the same name already exists its content is erased and the file is + treated as a new empty file. + - "a+": Open a file for reading and appending. All writing operations are + performed at the end of the file, protecting the previous content to be + overwritten. You can reposition (fseek, rewind) the internal pointer to + anywhere in the file for reading, but writing operations will move it + back to the end of file. The file is created if it does not exist. + + **NOTE**: In order to open a file as a binary file, a "b" character has to + be included in the `mode` string. This additional "b" character can either + be appended at the end of the string (thus making the following compound + modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the + letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). + Additional characters may follow the sequence, although they should have no + effect. For example, "t" is sometimes appended to make explicit the file is + a text file. + + This function supports Unicode filenames, but they must be encoded in UTF-8 + format, regardless of the underlying operating system. + + As a fallback, SDL_RWFromFile() will transparently open a matching filename + in an Android app's `assets`. + + Closing the SDL_RWops will close the file handle SDL is holding internally. + + \param file a UTF-8 string representing the filename to open + \param mode an ASCII string representing the mode to be used for opening + the file. + \returns a pointer to the SDL_RWops structure that is created, or NULL on + failure; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_RWclose + \sa SDL_RWFromConstMem + \sa SDL_RWFromFP + \sa SDL_RWFromMem + \sa SDL_RWread + \sa SDL_RWseek + \sa SDL_RWtell + \sa SDL_RWwrite + + + +Return the size of the file in this rwops, or -1 if unknown + + + Seek to \c offset relative to \c whence, one of stdio's whence values: + RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + + \return the final offset in the data stream, or -1 on error. + + + Read up to \c maxnum objects each of size \c size from the data + stream to the area pointed at by \c ptr. + + \return the number of objects read, or 0 at error or end of file. + + + Write exactly \c num objects each of size \c size from the area + pointed at by \c ptr to data stream. + + \return the number of objects written, or 0 at error or end of file. + + + Close and free an allocated SDL_RWops structure. + + \return 0 if successful or -1 on write error when flushing data. + + + + Clear any previous error message for this thread. + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetError + \sa SDL_SetError + + + + Get the last error message that was set for the current thread. + + This allows the caller to copy the error string into a provided buffer, but + otherwise operates exactly the same as SDL_GetError(). + + \param errstr A buffer to fill with the last error message that was set for + the current thread + \param maxlen The size of the buffer pointed to by the errstr parameter + \returns the pointer passed in as the `errstr` parameter. + + \since This function is available since SDL 2.0.14. + + \sa SDL_GetError + + + + Retrieve a message about the last error that occurred on the current + thread. + + It is possible for multiple errors to occur before calling SDL_GetError(). + Only the last error is returned. + + The message is only applicable when an SDL function has signaled an error. + You must check the return values of SDL function calls to determine when to + appropriately call SDL_GetError(). You should *not* use the results of + SDL_GetError() to decide if an error has occurred! Sometimes SDL will set + an error string even when reporting success. + + SDL will *not* clear the error string for successful API calls. You *must* + check return values for failure cases before you can assume the error + string applies. + + Error strings are set per-thread, so an error set in a different thread + will not interfere with the current thread's operation. + + The returned string is internally allocated and must not be freed by the + application. + + \returns a message with information about the specific error that occurred, + or an empty string if there hasn't been an error message set since + the last call to SDL_ClearError(). The message is only applicable + when an SDL function has signaled an error. You must check the + return values of SDL function calls to determine when to + appropriately call SDL_GetError(). + + \since This function is available since SDL 2.0.0. + + \sa SDL_ClearError + \sa SDL_SetError + + + + Calculate a 256 entry gamma ramp for a gamma value. + + \param gamma a gamma value where 0.0 is black and 1.0 is identity + \param ramp an array of 256 values filled in with the gamma ramp + + \since This function is available since SDL 2.0.0. + + \sa SDL_SetWindowGammaRamp + + + + Get RGBA values from a pixel in the specified format. + + This function uses the entire 8-bit [0..255] range when converting color + components from pixel formats with less than 8-bits per RGB component + (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + + If the surface has no alpha component, the alpha will be returned as 0xff + (100% opaque). + + \param pixel a pixel value + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r a pointer filled in with the red component + \param g a pointer filled in with the green component + \param b a pointer filled in with the blue component + \param a a pointer filled in with the alpha component + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_MapRGB + \sa SDL_MapRGBA + + + + Get RGB values from a pixel in the specified format. + + This function uses the entire 8-bit [0..255] range when converting color + components from pixel formats with less than 8-bits per RGB component + (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + + \param pixel a pixel value + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r a pointer filled in with the red component + \param g a pointer filled in with the green component + \param b a pointer filled in with the blue component + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGBA + \sa SDL_MapRGB + \sa SDL_MapRGBA + + + + Map an RGBA quadruple to a pixel value for a given pixel format. + + This function maps the RGBA color value to the specified pixel format and + returns the pixel value best approximating the given RGBA color value for + the given pixel format. + + If the specified pixel format has no alpha component the alpha value will + be ignored (as it will be in formats with a palette). + + If the format has a palette (8-bit) the index of the closest matching color + in the palette will be returned. + + If the pixel format bpp (color depth) is less than 32-bpp then the unused + upper bits of the return value can safely be ignored (e.g., with a 16-bpp + format the return value can be assigned to a Uint16, and similarly a Uint8 + for an 8-bpp format). + + \param format an SDL_PixelFormat structure describing the format of the + pixel + \param r the red component of the pixel in the range 0-255 + \param g the green component of the pixel in the range 0-255 + \param b the blue component of the pixel in the range 0-255 + \param a the alpha component of the pixel in the range 0-255 + \returns a pixel value + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_GetRGBA + \sa SDL_MapRGB + + + + Map an RGB triple to an opaque pixel value for a given pixel format. + + This function maps the RGB color value to the specified pixel format and + returns the pixel value best approximating the given RGB color value for + the given pixel format. + + If the format has a palette (8-bit) the index of the closest matching color + in the palette will be returned. + + If the specified pixel format has an alpha component it will be returned as + all 1 bits (fully opaque). + + If the pixel format bpp (color depth) is less than 32-bpp then the unused + upper bits of the return value can safely be ignored (e.g., with a 16-bpp + format the return value can be assigned to a Uint16, and similarly a Uint8 + for an 8-bpp format). + + \param format an SDL_PixelFormat structure describing the pixel format + \param r the red component of the pixel in the range 0-255 + \param g the green component of the pixel in the range 0-255 + \param b the blue component of the pixel in the range 0-255 + \returns a pixel value + + \since This function is available since SDL 2.0.0. + + \sa SDL_GetRGB + \sa SDL_GetRGBA + \sa SDL_MapRGBA + + + + Free a palette created with SDL_AllocPalette(). + + \param palette the SDL_Palette structure to be freed + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + + + + Set a range of colors in a palette. + + \param palette the SDL_Palette structure to modify + \param colors an array of SDL_Color structures to copy into the palette + \param firstcolor the index of the first palette entry to modify + \param ncolors the number of entries to modify + \returns 0 on success or a negative error code if not all of the colors + could be set; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + \sa SDL_CreateRGBSurface + + + + Set the palette for a pixel format structure. + + \param format the SDL_PixelFormat structure that will use the palette + \param palette the SDL_Palette structure that will be used + \returns 0 on success or a negative error code on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocPalette + \sa SDL_FreePalette + + + + Create a palette structure with the specified number of color entries. + + The palette entries are initialized to white. + + \param ncolors represents the number of color entries in the color palette + \returns a new SDL_Palette structure on success or NULL on failure (e.g. if + there wasn't enough memory); call SDL_GetError() for more + information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreePalette + + + + Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). + + \param format the SDL_PixelFormat structure to free + + \since This function is available since SDL 2.0.0. + + \sa SDL_AllocFormat + + + + Create an SDL_PixelFormat structure corresponding to a pixel format. + + Returned structure may come from a shared global cache (i.e. not newly + allocated), and hence should not be modified, especially the palette. Weird + errors such as `Blit combination not supported` may occur. + + \param pixel_format one of the SDL_PixelFormatEnum values + \returns the new SDL_PixelFormat structure or NULL on failure; call + SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_FreeFormat + + + + Convert a bpp value and RGBA masks to an enumerated pixel format. + + This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't + possible. + + \param bpp a bits per pixel value; usually 15, 16, or 32 + \param Rmask the red mask for the format + \param Gmask the green mask for the format + \param Bmask the blue mask for the format + \param Amask the alpha mask for the format + \returns one of the SDL_PixelFormatEnum values + + \since This function is available since SDL 2.0.0. + + \sa SDL_PixelFormatEnumToMasks + + + + Convert one of the enumerated pixel formats to a bpp value and RGBA masks. + + \param format one of the SDL_PixelFormatEnum values + \param bpp a bits per pixel value; usually 15, 16, or 32 + \param Rmask a pointer filled in with the red mask for the format + \param Gmask a pointer filled in with the green mask for the format + \param Bmask a pointer filled in with the blue mask for the format + \param Amask a pointer filled in with the alpha mask for the format + \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't + possible; call SDL_GetError() for more information. + + \since This function is available since SDL 2.0.0. + + \sa SDL_MasksToPixelFormatEnum + + + + Get the human readable name of a pixel format. + + \param format the pixel format to query + \returns the human readable name of the specified pixel format or + `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. + + \since This function is available since SDL 2.0.0. + + + +\note Everything in the pixel format structure is read-only. + + + +The bits of this structure can be directly reinterpreted as an integer-packed +color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 +on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). + + + + If a + b would overflow, return -1. Otherwise store a + b via ret + and return 0. + + \since This function is available since SDL 2.24.0. + + + + If a * b would overflow, return -1. Otherwise store a * b via ret + and return 0. + + \since This function is available since SDL 2.24.0. + + + + This function converts a string between encodings in one pass, returning a + string that must be freed with SDL_free() or NULL on error. + + \since This function is available since SDL 2.0.0. + + + + Get the number of outstanding (unfreed) allocations + + \since This function is available since SDL 2.0.7. + + + + Replace SDL's memory allocation functions with a custom set + + \since This function is available since SDL 2.0.7. + + + + Get the current set of SDL memory functions + + \since This function is available since SDL 2.0.7. + + + + Get the original set of SDL memory functions + + \since This function is available since SDL 2.24.0. + + + +\endcond + \file begin_code.h + + This file sets things up for C dynamic library function definitions, + static inlined functions, and structures aligned at 4-byte alignment. + If you don't like ugly C preprocessor code, don't look at this file. :) + + + +\name Floating-point constants + +\cond + + +\brief An unsigned 64-bit integer type. + + + +\brief A signed 64-bit integer type. + + + +\brief An unsigned 32-bit integer type. + + + +\brief A signed 32-bit integer type. + + + +\brief An unsigned 16-bit integer type. + + + +\brief A signed 16-bit integer type. + + + +\brief An unsigned 8-bit integer type. + + + +\brief A signed 8-bit integer type. + + + + \file close_code.h + + This file reverses the effects of begin_code.h and should be included + after you finish any function and structure declarations in your headers + + + + \file SDL_stdinc.h + + This is a general header that includes C language support. + + \file SDL_platform.h + + Try to get a standard set of platform defines. + + \file begin_code.h + + This file sets things up for C dynamic library function definitions, + static inlined functions, and structures aligned at 4-byte alignment. + If you don't like ugly C preprocessor code, don't look at this file. :) + + Get the name of the platform. + + Here are the names returned for some (but not all) supported platforms: + + - "Windows" + - "Mac OS X" + - "Linux" + - "iOS" + - "Android" + + \returns the name of the platform. If the correct platform name is not + available, returns a string beginning with the text "Unknown". + + \since This function is available since SDL 2.0.0. + + + +*!************************************************************************* + + + +Marks the application to stop at the end of the current frame. + + + + +Whether or not the application is currently in fullscreen mode or not. + + + + +Retrieves the designated height of the current window. + + + + +Retrieves the designated width of the current window. + + + + +Whether or not the engine is in a paused state where script updates and +physics are not in play. + + + + +Whether or not the engine is playing. This will always be true on Publish. +On Debug/Release builds, this is true when the editor is in Play Mode. It +will also be true even if the editor is in Play Mode but is paused. + + + + +Static class that contains useful properties for querying the state of the +engine. + + + + +Sets the parent of this Transform component. + + +Entity that contains the Transform component that this Transform will be +parented to. If null, unparenting will occur. + + +If true, the transform values of this Transform component will retain their +pre-parent-change global transforms. The local transform values will be +modified to ensure that the global transforms do not change. + + + + +Parent Transform that affects this Transform. + + + + +Global scale stored by this Transform. + + + + +Global euler angle rotations stored by this Transform. + + + + +Global rotation quaternion stored by this Transform. + + + + +Global position stored by this Transform. + + + + +Local scale stored by this Transform. + + + + +Local euler angle rotations stored by this Transform. + + + + +Local rotation quaternion stored by this Transform. + + + + +Local position stored by this Transform. + + + + +Constructs a Transform Component that represents a native Transform component +tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the SHADE Engine's TransformComponent. + + + + +Compares if two float values are close enough to be the same with the +specified tolerance value. + + One of the values to compare. + The other value to compare. + Tolerance for floating point comparison. + True if a and b are practically the same. + + + +Compares if two float values are close enough to be the same with a tolerance +of Epsilon. + + One of the values to compare. + The other value to compare. + True if a and b are practically the same. + + + +Calculates the linear parameter t that produces the interpolant value within +the range [a, b]. + + Start value. + End value. + Value between start and end. + Percentage of value between start and end. + + + +Linearly interpolates between a and b by t. +The parameter t is not clamped and a value based on a and b is supported. +If t is less than zero, or greater than one, then LerpUnclamped will result +in a return value outside the range a to b. + + The start value. + The end value. + The interpolation value between the two float. + The interpolated float result between the two float values. + + + +Linearly interpolates between a and b by t. +The parameter t is clamped to the range [0, 1]. + + The start value. + The end value. + The interpolation value between the two float. + The interpolated float result between the two float values. + + + +Converts an angle from radian representation to degree representation. + + Radian-based angle to convert. + The specified angle in degrees. + + + +Converts an angle from degree representation to radian representation. + + Degree-based angle to convert. + The specified angle in radians. + + + +Wraps a value if they get to low or too high. + + Value to wrap. + Minimum value to wrap at. + Maximum value to wrap at. + Wrapped value. + + + +Small value used for single precision floating point comparisons. + + + + +Radians-to-degrees conversion constant + + + + +Degrees-to-radians conversion constant + + + + +Contains utility Math functions. + + + + +Logs a native exception that is formatted nicely to the output. + + Native exception to log. + Name of the one responsible for the exception. + + + +Logs an exception that is formatted nicely to the output. + + Name of the one responsible for the exception. + Exception to log. + + + +Logs a native exception that is formatted nicely to the output. +Equivalent to calling +LogException(exception, Convert::ToNative(thrower->GetType()->Name)); + + Native exception to log. + +Object that threw the exception to label the exception message. +The name of the object will be used. + + + + +Logs an exception that is formatted nicely to the output. + + Exception to log. + +Object that threw the exception to label the exception message. +The name of the object will be used. + + + + +Logs an exception that is formatted nicely to the output. + + Exception to log. + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that threw the error to label the error message. +The name of the object will be used. + + + + +Logs a error message to the output. + + The string to output. + + + +Logs a error message to the output. + + The string to output. + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that threw the warning to label the warning message. +The name of the object will be used. + + + + +Logs a warning message to the output. + + The string to output. + + + +Logs a warning message to the output. + + The string to output. + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Name of the object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output with a label such that it looks like this: +"[Label] Message" + + The string to output. + +Object that sent the message to label the message. +The name of the object will be used. + + + + +Logs a message to the output. + + The string to output. + + + +Logs a message to the output. + + The string to output. + + + +Static class that contains the functions for working with time. + + + + +Material used to render this Renderable. + + + + +Material used to render this Renderable. + + + + +Mesh used to render this Renderable. + + + + +Constructs a Renderable Component that represents a native Renderable +component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the SHADE Engine's SHRenderableComponent. + + + + +Retrieves the value of a specified property on the material. + + Type of property to get. + Name of the property to get. + Value of that property on the material. + +If this Material object is invalid. + + +If the name or type was specified that does not match the material's shader's +defined properties. + + + + +Set the value of a specific property. + + Type of property to set. + Name of the property to set. + Value to set te property to. + +If this Material object is invalid. + + +If the name or type was specified that does not match the material's shader's +defined properties. + + + + +Constructor for the Material + + Handle to the native material object. + + + +Managed counterpart of the native MaterialInstance object containing material +data that can be fed to Renderables for rendering. + + + + +Constructor for the Mesh + + Handle to the mesh object. + + + +Managed counterpart of the native Mesh object containing vertex data that can +be fed to Renderables for rendering. + + + +@brief Decomposes a transformation matrix into translation, orientation and scale. +@param[out] scale The scaling factor of the matrix. +@param[out] orientation The orientation of the matrix. +@param[out] translation The translation of the matrix. +@return True if decomposition was successful. + + + +@brief Decomposes a transformation matrix into translation, euler angles and scale. +@param[out] scale The scaling factor of the matrix. +@param[out] rotation The euler angles of the matrix. +@param[out] translation The translation of the matrix. +@return True if decomposition was successful. + + + +@brief Interface for a Column-Major Row Vector 4x4 Matrix. + + + + +Constructs a RigidBody Component that represents a native +SHRigidBodyComponent component tied to the specified Entity. + + Entity that this Component will be tied to. + + + +CLR version of the the SHADE Engine's SHRigidBodyComponent. + + + + +Creates an instance of the Managed representation of a Component with a +native Entity. + + Type of Component to create. + Native Entity that this Component is tied to. + The created Managed representation of the Component. + + + +Static constructor to initialize static data + + + + +Pointer to a function for Component manipulation operations. + + +Contains a set of Component related data used for resolving operations for +each Component. + + + + +Removes a Component from the specified Entity. + + Type of the Component to remove. + +Entity object that should have the specified Component removed from/ + + + + +Checks if the specified Entity has the specified Component. + + Type of the Component to check for. + Entity object to check for the Component. + +True if the specified Entity has the specified Component. False otherwise. + + + + +Ensures a Component on the specified Entity. + + Type of the Component to ensure. + Entity object to ensure the Component on. + Reference to the Component. + + + +Retrieves the first Component from the specified GameObjectt's children that +matches the specified type. + + Type of the Component to get. + Entity object to get the Component from. + +Reference to the Component or null if the Entity does not have the +specified Component. + + + + +Gets a Component from the specified Entity. + + Type of the Component to get. + Entity object to get the Component from. + +Reference to the Component or null if the Entity does not have the +specified Component. + + + + +Adds a Component to the specified Entity. + + Type of the Component to add. + +Entity object that should have the specified Component added to. + + Reference to the Component that was added. + + + +Static class which contains functions that map Pls::ECS's Component manipulation +functions to managed generic functions. + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Entity that this Component belongs to. + + + + +Constructor for BaseComponent to tie it to a specific Entity. +Constructors of derived Components should call this Constructor. + + Entity that this Component will be tied to. + + + +Implicit conversion operator to enable checking if a component is null. + + Component to check. + + + +Removes all Scripts of the specified type from this GameObject. + + Type of PLushieScripts to remove. + + + +Retrieves a immutable list of Scripts of the specified type from this +GameObject. + + Type of Scripts to Get. + Immutable list of Scripts of the specified type. + + + +Retrieves a Script of the specified type from this GameObject. +If multiple Scripts of the same specified type are added on the same +GameObject, this will retrieve the first one added. + + Type of Script to add. + Reference to the Script to retrieve. + + + +Adds a Script of the specified type to this GameObject. + + Type of Script to add. + Reference to the created Script. + + + +Removes a Component from this GameObject. If no Component exists to begin +with, nothing happens. + + Type of the Component to get. + + + +Gets a Component from this GameObject. + + Type of the Component to get. + +Reference to the Component or null if this GameObject does not have the +specified Component. + + + + +Adds a Component to this GameObject. + + Type of the Component to add. + Reference to the Component that was added. + + + +Retrieves the GameObject that this Component belongs to. + + + + +Class that serves as the base for a wrapper class to Components in native code. + + + + +Called when the attached GameObject has a Collider and leaves a +collision with another GameObject with a Collider2D. + + Information on the collision event. + + + +Called when the attached GameObject has a Collider and collides with +another GameObject with a Collider in subsequent frames of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a Collider and collides with +another GameObject with a Collider in the first frame of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and leaves a +collision with another GameObject with a Collider2D. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and collides with +another GameObject with a Collider in subsequent frames of collision. + + Information on the collision event. + + + +Called when the attached GameObject has a trigger Collider and collides with +another GameObject with a Collider in the first frame of collision. + + Information on the collision event. + + + +Called just before the end of the frame where the attached GameObject or +this script is destroyed directly or indirectly due to destruction of the +owner. + + + + +Called every frame after physics and collision resolution but before +rendering. + + + + +Called every frame before physics and collision resolution. + + + + +Called every frame in sync with Physics update steps and thus in most cases +will execute more than update() will. This will be called immediately before +a Physics update step. + + + + +Called on the first frame that the attached GameObject is active but always +after Awake(). + + + + +Called on the first frame that the attached GameObject is active if they are +a part of the scene. + + + + +Called immediately once this script is detached from a GameObject. + + + + +Called immediately once this script is attached to a GameObject. + + + + +Constructor for Script to tie it to a specific GameObject. +Constructors of derived Scripts should call this Constructor. + + +GameObject that this Script will be tied to. + + + + +Used to call onTriggerExit(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onTriggerStay(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onTriggerEnter(). This should be called when a trigger-type +collision is detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionExit(). This should be called when a collision ends +between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionStay(). This should be called when a collision is +persistent between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onCollisionEnter(). This should be called when a collision is +detected between the attached GameObject and another GameObject. + + Information on the collision event. + + + +Used to call onDestroy(). This should be called at the end of the frame +where the attached GameObject or this script is destroyed directly or +indirectly due to destruction of the owner. + + + + +Used to call lateUpdate(). This should be called every frame after physics +and collision resolution but before rendering. + + + + +Used to call update(). This should be called every frame before physics and +collision resolution. + + + + +Used to call fixedUpdate(). This should be called in sync with Physics +update steps and thus in most cases will execute more than Update() will. +This will be called immediately before a Physics update step. + + + + +Used to call start(). This should be called on the first frame that the +attached GameObject is active but always after Awake(). + + + + +Used to call awake(). This should be called on the first frame that the +attached GameObject is active if they are a part of the scene. + + + + +Used to call onDetached(). This is called immediately when this script is +detached from a GameObject. + + + + +Used to call onAttached(). This is called immediately when this script is +attached to a GameObject. + + + + +Implicit conversion operator to enable checking if a component is null. + + Component to check. + + + +Removes all Scripts of the specified type from this GameObject. + + +Type of script to remove. +This needs to be a default constructable Script. + + + + +Retrieves a immutable list of scripts from the specified Entity that +matches the specified type. +
+Note that this function allocates. It should be used sparingly. +
+ +Type of scripts to get. +This needs to be a default constructable Script. + + +Immutable list of references to scripts of the specified type. + +
+ + +Retrieves the first Script from this GameObject's children that matches the +specified type. + + +Type of script to get. +This needs to be a default constructable Script. + + Reference to the script added + + + +Retrieves the first Script from this GameObject that matches the specified +type. + + +Type of script to get. +This needs to be a default constructable Script. + + Reference to the script added + + + +Adds a Script to this GameObject. + + +Type of script to add. +This needs to be a default constructable Script. + + Reference to the script added + + + +Removes a Component from the GameObject that this Script belongs to. + + +Type of the Component to remove. Must be derived from BaseComponent. + + + + +Ensures a Component on the GameObject that this Script belongs to. + + +Type of the Component to ensure. Must be derived from BaseComponent. + + Reference to the Component. + + + +Retrieves the first Component from this GameObject's children that matches +the specified type. + + +Type of the Component to get. Must be derived from BaseComponent. + + Reference to the Component that was retrieved. + + + +Gets a Component from the GameObject that this Script belongs to. + + +Type of the Component to get. Must be derived from BaseComponent. + + Reference to the Component that was retrieved. + + + +Adds a Component to the GameObject that this Script belongs to. + + +Type of the Component to add. Must be derived from BaseComponent. + + Reference to the Component that was added. + + + +GameObject that this Script belongs to. + + + + +Class that forms the basis of all "script"-objects that can be attached to +Entities to update each Entity's Components via C# code. + + + + +The RigidBody that you are colliding with. + + + + +The CollisionShape of the Collider that you are colliding with. + + + + +The Collider that you are colliding with. + + + + +The GameObject whose collider you are colliding with. + + + + +Struct that describes a collision + + + + +Checks if two GameObject references are different. + + GameObject to check. + Another GameObject to check with. + True if both Components are different. + + + +Checks if two GameObject references are the same. + + GameObject to check. + Another GameObject to check with. + True if both Components are the same. + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Retrieves the native Entity object that this GameObject represents. + + Native Entity object that this GameObject represents. + + + +Retrieves the CLR Entity object that this GameObject represents. + + Entity object that this GameObject represents. + + + +Constructor for the GameObject. + + +Managed numerical representation of the ECS Entity that this GameObject +should represent. + + + + +Constructor for the GameObject. + + +The ECS Entity that this GameObject should represent. + + + + +Removes all Scripts of the specified type from this GameObject. + + Type of PLushieScripts to remove. + + + +Retrieves a immutable list of Scripts of the specified type from this +GameObject. + + Type of Scripts to retrieve. + Immutable list of Scripts of the specified type. + + + +Retrieves a Script of the specified type from child GameObjects. +If multiple Scripts of the same specified type are added on the same +child GameObject, this will retrieve the first one added. + + Type of Script to retrieve. + Reference to the Script to retrieve. + + + +Retrieves a Script of the specified type from this GameObject. +If multiple Scripts of the same specified type are added on the same +GameObject, this will retrieve the first one added. + + Type of Script to retrieve. + Reference to the Script to retrieve. + + + +Adds a Script of the specified type to this GameObject. + + Type of Script to add. + Reference to the created Script. + + + +Removes a Component from this GameObject. If no Component exists to begin +with, nothing happens. + + Type of the Component to get. + + + +Ensures a Component on this GameObject. + + Type of the Component to ensure. + +Reference to the Component. + + + + +Retrieves the first Component from this GameObject's children that matches +the specified type. + + Type of the Component to get. + +Reference to the Component or null if neither of this GameObject's children +does not have the specified Component. + + + + +Gets a Component from this GameObject. + + Type of the Component to get. + +Reference to the Component or null if this GameObject does not have the +specified Component. + + + + +Adds a Component to this GameObject. + + Type of the Component to add. + Reference to the Component that was added. + + + +Sets the active state of this GameObject. +
+The actual "activeness" of this GameObject is still dependent on the parents' +active states. +
+ +Whether to activate or deactivate this GameObject. + +
+ + +Sets the name of this GameObject. + + The name to set. + + + +Native Entity ID value for this GameObject. + + + + +Whether or not this Entity is active in the Scene hierarchy. + + + + +Whether or not this Entity alone, is active. This does not mean that this +object is active in the scene. For example, if this Entity's parent is not +active, then this Entity would also be not active. + + + + +Name of the object that this Entity represents. + + + + +Retrieves a GameObject with the specified name. If there are multiple +GameObjects with the same name, the first found GameObject will be retrieved. +There is no guaranteed order of which GameObject is considered "first". + + Name of the GameObject to find. + GameObject that has the specified name. Null if not found. + + + +Destroys the specified GameObject. Note that the specified GameObject will no +longer be a valid GameObject after this function is called. + + The GameObject to be destroyed. + + + +Creates a new GameObject in the current Scene. If multiple Scenes are loaded, +and you would like to create an object in a specific Scene, call the Scene's +CreateGameObject(). + + GameObject that represents the newly created GameObject. + + + +Lightweight object for an PlushieEngine Entity that allows for easy access +to Component and Script operations. + + + + +Constructor for a Tooltip attribute that fills in the description. + + Text to be shown when a field is hovered. + + + +Maximum value for the Ranged field. + + + + +Minimum value for the Ranged field. + + + + +Simple attribute to constrain the range of values for a field on the editor. + + + + +Converts from a native std::Stringto a managed String. + + The native std::string to convert from. + Managed copy of a native std::string. + + + +Converts from a managed String to a native std::string. + + The managed String to convert from. + Native copy of a managed String. + + + +Converts from a native Vector2 to a managed Vector2. + + The native Vector2 to convert from. + Managed copy of a native Vector2. + + + +Converts from a native Quaternion to a managed Quaternion. + + The native Quaternion to convert from. + Managed copy of a native Quaternion. + + + +Converts from a managed Quaternion to a native Quaternion. + + The managed Quaternion to convert from. + Native copy of a managed Quaternion. + + + +Converts from a native Vector2 to a managed Vector2. + + The native Vector2 to convert from. + Managed copy of a native Vector2. + + + +Converts from a managed Vector2 to a native Vector2. + + The managed Vector2 to convert from. + Native copy of a managed Vector2. + + + +Converts from a native Vector3 to a managed Vector3. + + The native Vector3 to convert from. + Managed copy of a native Vector3. + + + +Converts from a managed Vector3 to a native Vector3. + + The managed Vector3 to convert from. + Native copy of a managed Vector3. + + + +Converts from a native Entity to a managed Entity (UInt32). + + Native Entity to convert from. + Managed representation of the specified Entity. + + + +Provides functions easy and consistent syntax for converting between custom +managed and native types that are aligned. + + + + +Converts to true if this is a valid Handle. + + + + +The library that the handle was issued by. + + + + +The internal ID of the handle. + + + + +Creates a ray starting at origin along direction. + + Source of the ray. + Direction the ray travels in. + + + +The direction that a ray travels in. + + + + +The start point of the ray. + + + + +CLR version of the the SHADE Engine's Ray class that represents a ray in +3-Dimensional space. + + + + +Are two quaternions equal to each other? + + Left-hand side quaternion. + Right-hand side quaternion. + + + +Combines rotations lhs and rhs. + + Left-hand side quaternion. + Right-hand side quaternion. + + + +Spherically interpolates between a and b by t. The parameter t is not clamped. + + + + +Spherically interpolates between quaternions a and b by ratio t. The parameter t is clamped to the range [0, 1]. + + Start value, returned when t = 0. + End value, returned when t = 1. + Interpolation ratio. + A quaternion spherically interpolated between quaternions a and b. + + + +Rotates a rotation from towards to.
+The from quaternion is rotated towards to by an angular step of maxDegreesDelta (but note that the rotation will not overshoot). +Negative values of maxDegreesDelta will move away from to until the rotation is exactly the opposite direction. +
+
+ + +Converts this quaternion to one with the same orientation but with a magnitude of 1. + + + + +Creates a rotation with the specified forward and upwards directions.
+Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X. +
+
+ + +Interpolates between a and b by t and normalizes the result afterwards. The parameter t is not clamped. + + + + +Interpolates between a and b by t and normalizes the result afterwards. The parameter t is clamped to the range [0, 1]. + + Start value, returned when t = 0. + End value, returned when t = 1. + Interpolation ratio. + A quaternion interpolated between quaternions a and b. + + + +Returns the Inverse of rotation. + + + + +Creates a rotation which rotates from fromDirection to toDirection. + + + + +Returns a rotation that rotates y degrees around the y axis, x degrees around the x axis, and z degrees around the z axis; applied in that order. + + + + +The dot product between two rotations. + + + + +Creates a rotation which rotates angle degrees around axis. + + + + +Returns the angle in degrees between two rotations a and b.
+ The angle in degrees between the two vectors. +
+ + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Converts a rotation to angle-axis representation (angles in degrees). + + + + +Creates a rotation with the specified forward and upwards directions.
+The result is applied to this quaternion. +If used to orient a Transform, the Z axis will be aligned with forward and the Y axis with upwards, assuming these vectors are orthogonal. +Logs an error if the forward direction is zero. +
+ The direction to look in. + The vector that defines in which direction up is. +
+ + +Creates a rotation which rotates from fromDirection to toDirection.
+Use this to create a rotation which starts at the first Vector (fromDirection) and rotates to the second Vector (toDirection). +These Vectors must be set up in a script. +
+
+ + +Constructor to construct a Quaternion with the specified components. + + X-coordinate to set. + Y-coordinate to set. + Z-coordinate to set. + W-coordinate to set. + + + +W-component of the Quaternion. Do not directly modify quaternions. + + + + +Z-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +Y-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +X-component of the Quaternion. +Don't modify this directly unless you know quaternions inside out. + + + + +Shorthand for writing Quaternion(0, 0, 0, 1). + + + + +CLR version of SHADE's Quaternion class that represents an orientation. +Designed to closely match Unity's Quaternion struct. + + + + +Explicit conversion operator to enable explicit casting from a Vector2 to a +Vector3. + + Vector2 to convert from. + + + +Explicit conversion operator to enable explicit casting from a Vector3 to a +Vector2. + + Vector3 to convert from. + + + +Checks if two Vector3s are not approximately equal. This is equivalent to +calling !Vector3.IsNear() with default tolerance values. + + Vector3 to compare. + Another Vector3 to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Vector3s are approximately equal. This is equivalent to +calling Vector3.IsNear() with default tolerance values. + + Vector3 to compare. + Another Vector3 to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Vector3 with a scalar value and returns +the result. + + Scalar to divide with. + Vector3 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector3 with a scalar value and returns +the result. + + Vector3 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the division of a Vector3 with a scalar value and returns +the result. + + Scalar to divide with. + Vector3 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector3 with a scalar value and returns +the result. + + Vector3 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Vector3s and returns the +result. + + Vector3 to multiply with. + Another Vector3 to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Vector3 from another Vector3 and returns the result. + + Vector3 to subtract from. + Another Vector3 to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Vector3s together and returns the result. + + Vector3 to add. + Another Vector3 to add. + The result of lhs added to rhs + + + +Moves a point current towards target. +Similar to Lerp(), however, the function will ensure that the distance never +exceeds maxDistanceDelta. Negative values of maxDistanceDelta pushes the +vector away from target + + The current position of the point. + The target position to move to. + Maximum distance moved per call. + Vector representing the moved point. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Vector3, returned when t = 0.0f. + The end Vector3, returned when t = 1.0f. + Value used to interpolate between a and b. + The interpolated Vector3. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Vector3, returned when t = 0.0f. + The end Vector3, returned when t = 1.0f. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector3. + + + +Computes and returns a Vector3 that is made from the largest components of +the two specified Vector3s. + + Vector3 to calculate maximum Vector3 with. + Another Vector3 to calculate maximum Vector3 with. + +The Vector3 that contains the largest components of the two specified +Vector3s. + + + + +Computes and returns a Vector3 that is made from the smallest components of +the two specified Vector3s. + + Vector3 to calculate minimum Vector3 with. + Another Vector3 to calculate minimum Vector3 with. + +The Vector3 that contains the smallest components of the two specified +Vector3s. + + + + +Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector3 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in degrees. + + The Vector3 that represents the rotated vector. + + + +Rotates a Vector3 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector3 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in radians. + + The Vector3 that represents the rotated vector. + + + +Reflects a Vector3 across another Vector3. + + A Vector3 to reflect. + A normal to reflect the Vector3 across. + The Vector3 that represents vec reflected across normal. + + + +Computes and returns a Vector3 projection. + + Vector3 to project. + Vector3 to project onto. + The Vector3 that represents the projected vec onto direction. + + + +Computes and returns the cross product of 2 specified Vector3s. + + Vector3 to calculate cross product with. + Another Vector3 to calculate cross product with. + The cross product of the two Vector3s. + + + +Computes and returns the dot product of 2 specified Vector3s. + + Vector3 to calculate dot product with. + Another Vector3 to calculate dot product with. + Scalar value representing the dot product of the two Vector3s. + + + +Checks if two specified Vector3s are near in value. + + Vector3 to check if is near in value. + Another Vector3 to check if is near in value. + Amount of tolerance to do the comparison with. + +True if the two Vector3s are within the tolerance value specified + + + + +Checks if two specified Vector3s are near in value. + + Vector3 to check if is near in value. + Another Vector3 to check if is near in value. + +True if the two Vector3s are within the tolerance value specified + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Checks if a specified point is near this Vector3 that represents a point. + + The other point to check if we are near. + +The amount of tolerance before we consider these points as "near". + + +True if this Vector3 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Checks if a specified point is near this Vector3 that represents a point with +a tolerance value of PLS_EPSILON. + + The other point to check if we are near. + +True if this Vector3 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -180.0f and 180.0f. + + Returns the angle of this vector from the right vector in degrees. + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -Math.PI and Math.PI. + + Returns the angle of this vector from the right vector in radians. + + + +Calculates and returns the squared magnitude of this Vector3. + + Returns the squared length of this Vector3. + + + +Calculates and returns the magnitude of this Vector3. Note that this function +incurs a performance cost from the square root calculation. If you do not +need the precise magnitude, consider using GetSqrMagnitude() instead. + + Returns the length of this Vector3. + + + +Creates a copy of this Vector3 and returns a normalized version. + + +Returns a normalised copy of this Vector3. +If this Vector3 is a zero vector, a zero vector will be returned. + + + + +Normalises this current Vector3. This changes the data of this Vector3. +If you would like to get a copy, use GetNormalised() instead. +This function does nothing to a zero vector. + + + + +Conversion constructor to construct a Vector3 using a Vector2. + + + + + +Constructor to construct a Vector3 with the specified components. + + X-coordinate to set. + Y-coordinate to set. + Z-coordinate to set. + + + +Constructor to construct a Vector3 with the specified components with the +Z-component set to 0.0f. + + X-coordinate to set. + Y-coordinate to set. + + + +Constructor to construct a Vector3 with the specified components with the +Y and Z-component set to 0.0f. + + X-coordinate to set. + + + +Z-component of the Vector3. + + + + +Y-component of the Vector3. + + + + +X-component of the Vector3. + + + + +Shorthand for writing Vector3(0, 0, 0). + + + + +Shorthand for writing Vector3(0, 1, 0). + + + + +Shorthand for writing Vector3(1, 0, 0). + + + + +Shorthand for writing Vector3(float.PositiveInfinity, +float.PositiveInfinity, float.PositiveInfinity). + + + + +Shorthand for writing Vector3(1, 1, 1). + + + + +Shorthand for writing Vector3(float.NegativeInfinity, +float.NegativeInfinity, float.NegativeInfinity). + + + + +Shorthand for writing Vector3(-1, 0, 0). + + + + +Shorthand for writing Vector3(0, 0, 1). + + + + +Shorthand for writing Vector3(0, -1, 0). + + + + +Shorthand for writing Vector3(0, 0, -1). + + + + +CLR version of SHADE Engine's Vector3 class that represents a 3-Dimensional Vector. +Designed to closely match Unity's Vector3 struct. + + + + +Checks if two Vector2s are not approximately equal. This is equivalent to +calling !Vector2.IsNear() with default tolerance values. + + Vector2 to compare. + Another Vector2 to compare. + +True if all components are not approximately equal within the default +tolerance value. + + + + +Checks if two Vector2s are approximately equal. This is equivalent to +calling Vector2.IsNear() with default tolerance values. + + Vector2 to compare. + Another Vector2 to compare. + +True if all components are approximately equal within the default +tolerance value. + + + + +Calculates the division of a Vector2 with a scalar value and returns +the result. + + Scalar to divide with. + Vector2 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector2 with a scalar value and returns +the result. + + Vector2 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the division of a Vector2 with a scalar value and returns +the result. + + Scalar to divide with. + Vector2 to divide with. + The result of the scalar division. + + + +Calculates the multiplication of a Vector2 with a scalar value and returns +the result. + + Vector2 to multiply with. + Scalar to multiply with. + The result of the scalar multiplication. + + + +Calculates the component-wise multiplication of two Vector2s and returns the +result. + + Vector2 to multiply with. + Another Vector2 to multiply with. + The result of rhs subtracted from lhs. + + + +Subtracts a Vector2 from another Vector2 and returns the result. + + Vector2 to subtract from. + Another Vector2 to subtract. + The result of rhs subtracted from lhs. + + + +Adds two Vector2s together and returns the result. + + Vector2 to add. + Another Vector2 to add. + The result of lhs added to rhs + + + +Moves a point current towards target. +Similar to Lerp(), however, the function will ensure that the distance never +exceeds maxDistanceDelta. Negative values of maxDistanceDelta pushes the +vector away from target + + The current position of the point. + The target position to move to. + Maximum distance moved per call. + Vector representing the moved point. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. +Unlike Lerp(), t is not clamped to a range at all. + + The start Vector2, returned when t = 0.0f. + The end Vector2, returned when t = 1.0f. + Value used to interpolate between a and b. + The interpolated Vector2. + + + +Linearly interpolates between two specified points. +This is most commonly used to find a point some fraction of the way along a +line between two endpoints. + + The start Vector2, returned when t = 0.0f. + The end Vector2, returned when t = 1.0f. + +Value used to interpolate between a and b which is clamped to +the range[0, 1]. + + The interpolated Vector2. + + + +Computes and returns a Vector2 that is made from the largest components of +the two specified Vector2s. + + Vector2 to calculate maximum Vector2 with. + Another Vector2 to calculate maximum Vector2 with. + +The Vector2 that contains the largest components of the two specified +Vector2s. + + + + +Computes and returns a Vector2 that is made from the smallest components of +the two specified Vector2s. + + Vector2 to calculate minimum Vector2 with. + Another Vector2 to calculate minimum Vector2 with. + +The Vector2 that contains the smallest components of the two specified +Vector2s. + + + + +Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector2 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in degrees. + + The Vector2 that represents the rotated vector. + + + +Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise +direction. + + A Vector2 to rotate. + +Angle to rotate the vector by in an anti-clockwise direction in radians. + + The Vector2 that represents the rotated vector. + + + +Reflects a Vector2 across another Vector2. + + A Vector2 to reflect. + A normal to reflect the Vector2 across. + The Vector2 that represents vec reflected across normal. + + + +Computes and returns a Vector2 projection. + + Vector2 to project. + Vector2 to project onto. + The Vector2 that represents the projected vec onto direction. + + + +Computes a perpendicular Vector2 to the specified Vector2. + + Vector2 to find a perpendicular of. + +Whether the inward perpendicular Vector is retrieved. If true, the +resultant vector is rotated 90-degrees in a counter-clockwise. + + The perpendicular Vector2 relative to the specified Vector2. + + + + +Computes the inward perpendicular Vector2 to the specified Vector2. +Equivalent to calling Perpendicular(lhs, true). This means, the +resultant Vector2 is rotated 90-degrees in a counter-clockwise. + + Vector2 to find a perpendicular of. + +The perpendicular Vector2 relative to the specified Vector2. + + + + +Computes and returns the dot product of 2 specified Vector2s. + + Vector2 to calculate dot product with. + Another Vector2 to calculate dot product with. + +Scalar value representing the dot product of the two Vector2s. + + + + +Checks if two specified Vector2s are near in value. + + Vector2 to check if is near in value. + Another Vector2 to check if is near in value. + +Amount of tolerance to do the comparison with. + + +True if the two Vector2s are within the tolerance value specified + + + + +Checks if two specified Vector2s are near in value. + + Vector2 to check if is near in value. + Another Vector2 to check if is near in value. + +True if the two Vector2s are within the tolerance value specified + + + + +Gets a unique hash for this object. + + Unique hash for this object. + + + +Compares equality with another unboxed object. + + The unboxed object to compare with. + True if both objects are the same. + + + +Compares equality with an object of the same type. + + The object to compare with. + True if both objects are the same. + + + +Checks if a specified point is near this Vector2 that represents a point. + + The other point to check if we are near. + +The amount of tolerance before we consider these points as "near". + + +True if this Vector2 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Checks if a specified point is near this Vector2 that represents a point with +a tolerance value of PLS_EPSILON. + + The other point to check if we are near. + +True if this Vector2 representing a point and the specified point are within +the range of the specified tolerance. False otherwise. + + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -180.0f and 180.0f. + + Returns the angle of this vector from the right vector in degrees. + + + +Calculates and returns the angle of this vector from the right vector. This +function returns values between -Math.PI and Math.PI. + + Returns the angle of this vector from the right vector in radians. + + + +Calculates and returns the squared magnitude of this Vector2. + + Returns the squared length of this Vector2. + + + +Calculates and returns the magnitude of this Vector2. Note that this function +incurs a performance cost from the square root calculation. If you do not +need the precise magnitude, consider using GetSqrMagnitude() instead. + + Returns the length of this Vector2. + + + +Creates a copy of this Vector2 and returns a normalized version. + + +Returns a normalised copy of this Vector2. +If this Vector2 is a zero vector, a zero vector will be returned. + + + + +Normalises this current Vector2. This changes the data of this Vector2. +If you would like to get a copy, use GetNormalised() instead. +This function does nothing to a zero vector. + + + + +Constructor to construct a Vector2 with the specified components.. + + X-coordinate to set. + Y-coordinate to set. + + + +Constructor to construct a Vector2 with the specified components with the +Y-component set to 0.0f. + + X-coordinate to set. + + + +Y-component of the Vector2. + + + + +X-component of the Vector2. + + + + +Shorthand for writing Vector2(0, 0). + + + + +Shorthand for writing Vector2(0, 1). + + + + +Shorthand for writing Vector2(1, 0). + + + + +Shorthand for writing Vector2(float.PositiveInfinity, +float.PositiveInfinity). + + + + +Shorthand for writing Vector2(1, 1). + + + + +Shorthand for writing Vector2(float.NegativeInfinity, +float.NegativeInfinity). + + + + +Shorthand for writing Vector2(-1, 0). + + + + +Shorthand for writing Vector2(0, -1). + + + + +CLR version of SHADE Engine's Vector2 class that represents a 2-Dimensional Vector. +Designed to closely match Unity's Vector2 struct. + + + + +Checks if the specified entity is valid. This is done by checking if it +matches Pls::Entity::INVALID. + + The Entity to check. + True if the specified Entity is valid. + + + +Static class that contains useful utility functions for working with Entity. + + + + +Manages all resources in multiple ResourceLibraries. + + + + +Base class for SHResourceLibrary that holds information about the library type. + + + + +Template Specialization for Handle that represents a type-less Handle. + + + + +Converts to true if this is a valid Handle. + + + + +Native ID type of a handle + + + + +Base implementation of the Handle that is not templated to allow for holding +generic non-type-specific Handles. + + + + +Exception thrown when a generic Handle is being casted to the wrong type. + + + + +Exception thrown when an invalid Handle was dereferenced. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file From f919d95c0b99b3a8e7e9ae39db3eae66c1f2dc42 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Tue, 1 Nov 2022 15:30:13 +0800 Subject: [PATCH 53/57] Added C# interface for Camera and Camera Arm. Added some test scripts --- SHADE_Managed/{ => src/Components}/Camera.cxx | 0 SHADE_Managed/{ => src/Components}/Camera.hxx | 0 SHADE_Managed/src/Components/CameraArm.cxx | 51 +++++++++++++++++ SHADE_Managed/src/Components/CameraArm.hxx | 40 ++++++++++++++ SHADE_Managed/src/Engine/ECS.cxx | 4 ++ SHADE_Managed/src/Engine/Time.cxx | 6 ++ SHADE_Managed/src/Engine/Time.hxx | 5 ++ SHADE_Managed/src/Input/Input.cxx | 7 +++ SHADE_Managed/src/Input/Input.hxx | 2 + TempScriptsFolder/CameraControl.cs | 22 ++++++++ TempScriptsFolder/CameraTest.cs | 9 --- TempScriptsFolder/ThirdPersonCamera.cs | 55 +++++++++++++++++++ 12 files changed, 192 insertions(+), 9 deletions(-) rename SHADE_Managed/{ => src/Components}/Camera.cxx (100%) rename SHADE_Managed/{ => src/Components}/Camera.hxx (100%) create mode 100644 SHADE_Managed/src/Components/CameraArm.cxx create mode 100644 SHADE_Managed/src/Components/CameraArm.hxx create mode 100644 TempScriptsFolder/CameraControl.cs delete mode 100644 TempScriptsFolder/CameraTest.cs create mode 100644 TempScriptsFolder/ThirdPersonCamera.cs diff --git a/SHADE_Managed/Camera.cxx b/SHADE_Managed/src/Components/Camera.cxx similarity index 100% rename from SHADE_Managed/Camera.cxx rename to SHADE_Managed/src/Components/Camera.cxx diff --git a/SHADE_Managed/Camera.hxx b/SHADE_Managed/src/Components/Camera.hxx similarity index 100% rename from SHADE_Managed/Camera.hxx rename to SHADE_Managed/src/Components/Camera.hxx diff --git a/SHADE_Managed/src/Components/CameraArm.cxx b/SHADE_Managed/src/Components/CameraArm.cxx new file mode 100644 index 00000000..67fcf6cf --- /dev/null +++ b/SHADE_Managed/src/Components/CameraArm.cxx @@ -0,0 +1,51 @@ +#include "SHpch.h" +#include "CameraArm.hxx" + + +namespace SHADE +{ + CameraArm::CameraArm(Entity entity) + :Component(entity) + { + + } + + float CameraArm::Pitch::get() + { + return (GetNativeComponent()->GetPitch()); + } + + void CameraArm::Pitch::set(float val) + { + GetNativeComponent()->SetPitch(val); + } + float CameraArm::Yaw::get() + { + return (GetNativeComponent()->GetYaw()); + } + + void CameraArm::Yaw::set(float val) + { + GetNativeComponent()->SetYaw(val); + } + + float CameraArm::ArmLength::get() + { + return (GetNativeComponent()->GetArmLength()); + } + + void CameraArm::ArmLength::set(float val) + { + GetNativeComponent()->SetArmLength(val); + } + + bool CameraArm::LookAtCameraOrigin::get() + { + return GetNativeComponent()->lookAtCameraOrigin; + } + + void CameraArm::LookAtCameraOrigin::set(bool val) + { + GetNativeComponent()->lookAtCameraOrigin = val; + } +} \ No newline at end of file diff --git a/SHADE_Managed/src/Components/CameraArm.hxx b/SHADE_Managed/src/Components/CameraArm.hxx new file mode 100644 index 00000000..771771cf --- /dev/null +++ b/SHADE_Managed/src/Components/CameraArm.hxx @@ -0,0 +1,40 @@ +#pragma once + +// Project Includes +#include "Components/Component.hxx" +#include "Math/Vector3.hxx" + +// External Dependencies +#include "Camera/SHCameraArmComponent.h" + + +namespace SHADE +{ + public ref class CameraArm : public Component + { + internal: + CameraArm(Entity entity); + public: + property float Pitch + { + float get(); + void set(float val); + } + property float Yaw + { + float get(); + void set(float val); + } + property float ArmLength + { + float get(); + void set(float val); + } + property bool LookAtCameraOrigin + { + bool get(); + void set(bool val); + } + + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index df67c788..3da39394 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -33,6 +33,8 @@ of DigiPen Institute of Technology is prohibited. #include "Components/Transform.hxx" #include "Components\RigidBody.hxx" #include "Components\Collider.hxx" +#include "Components/Camera.hxx" +#include "Components/CameraArm.hxx" namespace SHADE { @@ -248,6 +250,8 @@ namespace SHADE componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); + componentMap.Add(createComponentSet()); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/Time.cxx b/SHADE_Managed/src/Engine/Time.cxx index ff0628e7..31773ce9 100644 --- a/SHADE_Managed/src/Engine/Time.cxx +++ b/SHADE_Managed/src/Engine/Time.cxx @@ -26,4 +26,10 @@ namespace SHADE { return SHFrameRateController::GetRawDeltaTime(); } + + + float Time::DeltaTimeF::get() + { + return static_cast(SHFrameRateController::GetRawDeltaTime()); + } } \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/Time.hxx b/SHADE_Managed/src/Engine/Time.hxx index 969eea03..3a487ee9 100644 --- a/SHADE_Managed/src/Engine/Time.hxx +++ b/SHADE_Managed/src/Engine/Time.hxx @@ -37,5 +37,10 @@ namespace SHADE { double get(); } + + static property float DeltaTimeF + { + float get(); + } }; } \ No newline at end of file diff --git a/SHADE_Managed/src/Input/Input.cxx b/SHADE_Managed/src/Input/Input.cxx index 0a386f3a..f0ea0edc 100644 --- a/SHADE_Managed/src/Input/Input.cxx +++ b/SHADE_Managed/src/Input/Input.cxx @@ -99,4 +99,11 @@ namespace SHADE return SHInputManager::GetKeyReleasedTime(static_cast(key)); } + Vector2 Input::GetMouseVelocity() + { + double velX, velY; + SHInputManager::GetMouseVelocity(&velX, &velY); + + return Convert::ToCLI(SHVec2{ (float)velX,(float)velY }); + } } \ No newline at end of file diff --git a/SHADE_Managed/src/Input/Input.hxx b/SHADE_Managed/src/Input/Input.hxx index f281e4c8..e1426654 100644 --- a/SHADE_Managed/src/Input/Input.hxx +++ b/SHADE_Managed/src/Input/Input.hxx @@ -321,5 +321,7 @@ namespace SHADE /// The key to check. /// Time in seconds that the key was held. static double GetMouseReleasedTime(MouseCode mouseButton); + + static Vector2 GetMouseVelocity(); }; } \ No newline at end of file diff --git a/TempScriptsFolder/CameraControl.cs b/TempScriptsFolder/CameraControl.cs new file mode 100644 index 00000000..fc900f46 --- /dev/null +++ b/TempScriptsFolder/CameraControl.cs @@ -0,0 +1,22 @@ +using System; +using SHADE; + +namespace SHADE_Scripting +{ + public class CameraControl :Script + { + public float turnSpeed = 0.5f; + + public CameraControl(GameObject go) : base(go) { } + protected override void update() + { + //Camera + Camera cam = GetComponent(); + Vector2 mouseVel = Input.GetMouseVelocity(); + + cam.Pitch -= mouseVel.y * turnSpeed * (float)Time.DeltaTime; + cam.Yaw += mouseVel.x * turnSpeed * (float)Time.DeltaTime; + + } + } +} diff --git a/TempScriptsFolder/CameraTest.cs b/TempScriptsFolder/CameraTest.cs deleted file mode 100644 index 867f3dcc..00000000 --- a/TempScriptsFolder/CameraTest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using SHADE; - -namespace SHADE_Scripting -{ - class CameraTest :Script - { - } -} diff --git a/TempScriptsFolder/ThirdPersonCamera.cs b/TempScriptsFolder/ThirdPersonCamera.cs new file mode 100644 index 00000000..e3b043bd --- /dev/null +++ b/TempScriptsFolder/ThirdPersonCamera.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SHADE; + + +namespace SHADE_Scripting +{ + public class ThirdPersonCamera: Script + { + + public float armLength = 4.0f; + public float turnSpeedPitch = 0.3f; + public float turnSpeedYaw = 0.5f; + public float pitchClamp = 45.0f; + public ThirdPersonCamera(GameObject go) : base(go) { } + + protected override void awake() + { + if(!GetComponent()) + { + AddComponent(); + } + if (!GetComponent()) + { + AddComponent(); + } + GetComponent().ArmLength = armLength; + } + + protected override void update() + { + CameraArm arm = GetComponent(); + if(arm) + { + Vector2 vel = Input.GetMouseVelocity(); + arm.Pitch -= vel.y * turnSpeedPitch * Time.DeltaTimeF; + arm.Yaw += vel.x * turnSpeedYaw * Time.DeltaTimeF; + + if(arm.Pitch > pitchClamp) + { + arm.Pitch = pitchClamp; + } + else if(arm.Pitch < -pitchClamp) + { + arm.Pitch = -pitchClamp; + } + + } + } + + } +} From e0dcf9e13e5eaff23b372138414a2246301dfe9b Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 1 Nov 2022 15:32:01 +0800 Subject: [PATCH 54/57] Added Editor State Change events --- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 18 +++++ .../EditorWindow/MenuBar/SHEditorMenuBar.h | 6 ++ SHADE_Engine/src/Events/SHEventDefines.h | 3 + SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 67 +++++++++++-------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 1 + 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index 50b878a8..06c0c2ae 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -175,19 +175,37 @@ namespace SHADE ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY); if(ImGui::SmallButton(ICON_MD_PLAY_ARROW)) { + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editor->editorState + }; editor->editorState = SHEditor::State::PLAY; + + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT); } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); if(ImGui::SmallButton(ICON_MD_PAUSE)) { + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editor->editorState + }; editor->editorState = SHEditor::State::PAUSE; + + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT); } ImGui::EndDisabled(); ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); if(ImGui::SmallButton(ICON_MD_STOP)) { + const SHEditorStateChangeEvent STATE_CHANGE_EVENT + { + .previousState = editor->editorState + }; editor->editorState = SHEditor::State::STOP; + + SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); } ImGui::EndDisabled(); ImGui::EndMenuBar(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h index 7cbcd696..e4f1d20b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h @@ -20,4 +20,10 @@ namespace SHADE float menuBarHeight = 20.0f; std::vector layoutPaths; };//class SHEditorMenuBar + + struct SHEditorStateChangeEvent + { + SHEditor::State previousState; + }; + }//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index 804fbfec..d649fabf 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -13,4 +13,7 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index b1248509..e1acccd9 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -17,7 +17,6 @@ #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" -#include "Editor/SHEditor.h" #include "Math/SHMathHelpers.h" #include "Math/Transform/SHTransformComponent.h" #include "Scene/SHSceneManager.h" @@ -212,6 +211,12 @@ namespace SHADE const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::RemovePhysicsComponent) }; const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast(REMOVE_COMPONENT_RECEIVER); SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR); + + #ifdef SHEDITOR + const std::shared_ptr EDITOR_STOP_RECEIVER { std::make_shared>(this, &SHPhysicsSystem::ResetWorld) }; + const ReceiverPtr EDITOR_STOP_RECEIVER_PTR = std::dynamic_pointer_cast(EDITOR_STOP_RECEIVER); + SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, EDITOR_STOP_RECEIVER_PTR); + #endif } void SHPhysicsSystem::Exit() @@ -289,16 +294,6 @@ namespace SHADE if (rigidBodyComponent) { - // Clear all forces and velocities if editor is stopped - if (SHSystemManager::GetSystem()->editorState == SHEditor::State::STOP) - { - auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); - rp3dRigidBody->resetForce(); - rp3dRigidBody->resetTorque(); - rp3dRigidBody->setLinearVelocity(SHVec3::Zero); - rp3dRigidBody->setAngularVelocity(SHVec3::Zero); - } - // Sync active states const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive; SyncActiveStates(physicsObject, COMPONENT_ACTIVE); @@ -324,11 +319,11 @@ namespace SHADE void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept { - auto* physicsSystem = reinterpret_cast(GetSystem()); - auto scriptSys = SHSystemManager::GetSystem(); - if (!scriptSys) + auto* physicsSystem = reinterpret_cast(GetSystem()); + auto* scriptingSystem = SHSystemManager::GetSystem(); + if (scriptingSystem == nullptr) { - SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!"); + SHLOGV_WARNING("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!"); } fixedTimeStep = 1.0 / physicsSystem->fixedDT; @@ -337,10 +332,9 @@ namespace SHADE int count = 0; while (accumulatedTime > fixedTimeStep) { - if (scriptSys) - { - scriptSys->ExecuteFixedUpdates(); - } + if (scriptingSystem != nullptr) + scriptingSystem->ExecuteFixedUpdates(); + physicsSystem->world->update(static_cast(fixedTimeStep)); accumulatedTime -= fixedTimeStep; @@ -356,6 +350,11 @@ namespace SHADE void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept { auto* physicsSystem = reinterpret_cast(GetSystem()); + auto* scriptingSystem = SHSystemManager::GetSystem(); + if (scriptingSystem == nullptr) + { + SHLOGV_WARNING("Unable to invoke collision and trigger script events due to missing SHScriptEngine!"); + } // Interpolate transforms for rendering if (physicsSystem->worldUpdated) @@ -363,15 +362,8 @@ namespace SHADE physicsSystem->SyncTransforms(); // Collision & Trigger messages - auto scriptSys = SHSystemManager::GetSystem(); - if (scriptSys) - { - scriptSys->ExecuteCollisionFunctions(); - } - else - { - SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!"); - } + if (scriptingSystem != nullptr) + scriptingSystem->ExecuteCollisionFunctions(); physicsSystem->ClearInvalidCollisions(); } @@ -678,4 +670,23 @@ namespace SHADE return EVENT_DATA->handle; } + SHEventHandle SHPhysicsSystem::ResetWorld(SHEventPtr editorStopEvent) + { + // TODO(Diren): Rebuild world based on how scene reloading is done + + for (auto& [entityID, physicsObject] : map) + { + if (SHComponentManager::HasComponent(entityID)) + { + auto* rp3dRigidBody = reinterpret_cast(physicsObject.rp3dBody); + rp3dRigidBody->resetForce(); + rp3dRigidBody->resetTorque(); + rp3dRigidBody->setLinearVelocity(SHVec3::Zero); + rp3dRigidBody->setAngularVelocity(SHVec3::Zero); + } + } + + return editorStopEvent->handle; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index dd399f96..1d773618 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -189,6 +189,7 @@ namespace SHADE SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent); SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent); + SHEventHandle ResetWorld (SHEventPtr editorStopEvent); template From a45432ef665bbe645ad8673c18c334be45a6f86f Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Tue, 1 Nov 2022 15:35:50 +0800 Subject: [PATCH 55/57] Merge conflict --- SHADE_Managed/src/Engine/Time.cxx | 1 + SHADE_Managed/src/Engine/Time.hxx | 1 + 2 files changed, 2 insertions(+) diff --git a/SHADE_Managed/src/Engine/Time.cxx b/SHADE_Managed/src/Engine/Time.cxx index e244f3c5..36032e00 100644 --- a/SHADE_Managed/src/Engine/Time.cxx +++ b/SHADE_Managed/src/Engine/Time.cxx @@ -34,6 +34,7 @@ namespace SHADE float Time::DeltaTimeF::get() { return static_cast(SHFrameRateController::GetRawDeltaTime()); + } double Time::FixedDeltaTime::get() { return SHPhysicsSystemInterface::GetFixedDT(); diff --git a/SHADE_Managed/src/Engine/Time.hxx b/SHADE_Managed/src/Engine/Time.hxx index d97b74df..c0f0ed62 100644 --- a/SHADE_Managed/src/Engine/Time.hxx +++ b/SHADE_Managed/src/Engine/Time.hxx @@ -41,6 +41,7 @@ namespace SHADE static property float DeltaTimeF { float get(); + } /// /// Time taken for Physics simulations. You should use this for operations /// within Script.FixedUpdate() From 39910afa5439d3ed782f41622960b338c0c1e0c8 Mon Sep 17 00:00:00 2001 From: maverickdgg Date: Tue, 1 Nov 2022 15:49:15 +0800 Subject: [PATCH 56/57] Added GetForward to Camera C# interface. GetForward gets the forward according to Camera's last calculated view matrix --- SHADE_Managed/src/Components/Camera.cxx | 9 ++++++++- SHADE_Managed/src/Components/Camera.hxx | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SHADE_Managed/src/Components/Camera.cxx b/SHADE_Managed/src/Components/Camera.cxx index f90e2bfe..5e570cc1 100644 --- a/SHADE_Managed/src/Components/Camera.cxx +++ b/SHADE_Managed/src/Components/Camera.cxx @@ -114,7 +114,14 @@ namespace SHADE system->CameraLookAt(*GetNativeComponent(), Convert::ToNative(targetPosition)); } - + Vector3 Camera::GetForward() + { + auto system = SHSystemManager::GetSystem(); + SHVec3 forward, up, right; + system->GetCameraAxis(*GetNativeComponent(), forward, right, up); + return Convert::ToCLI(forward); + + } } \ No newline at end of file diff --git a/SHADE_Managed/src/Components/Camera.hxx b/SHADE_Managed/src/Components/Camera.hxx index e5a017b3..257bff11 100644 --- a/SHADE_Managed/src/Components/Camera.hxx +++ b/SHADE_Managed/src/Components/Camera.hxx @@ -65,5 +65,6 @@ namespace SHADE void SetMainCamera(size_t directorIndex); void SetMainCamera(); void LookAt(Vector3 targetPosition); + Vector3 GetForward(); }; } \ No newline at end of file From 8afe8c1a79a71e255ba1e88bafe9eea8efcc4f3e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 1 Nov 2022 17:24:20 +0800 Subject: [PATCH 57/57] GameObjects on scripts can now be edited in the inspector and are serialized --- .../HierarchyPanel/SHHierarchyPanel.cpp | 14 +++++---- SHADE_Engine/src/Editor/SHEditorUI.cpp | 30 +++++++++++++++++++ SHADE_Engine/src/Editor/SHEditorUI.h | 8 +++++ SHADE_Managed/src/Editor/Editor.cxx | 15 ++++++++-- .../src/Serialisation/ReflectionUtilities.cxx | 10 +++++++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 55d78421..1b289a90 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -195,18 +195,22 @@ namespace SHADE if (SHDragDrop::BeginSource()) { std::string moveLabel = "Moving EID: "; + static std::vector draggingEntities = editor->selectedEntities; if (!isSelected) - editor->selectedEntities.push_back(eid); - for (int i = 0; i < static_cast(editor->selectedEntities.size()); ++i) { - moveLabel.append(std::to_string(editor->selectedEntities[i])); - if (i + 1 < static_cast(editor->selectedEntities.size())) + draggingEntities.clear(); + draggingEntities.push_back(eid); + } + for (int i = 0; i < static_cast(draggingEntities.size()); ++i) + { + moveLabel.append(std::to_string(draggingEntities[i])); + if (i + 1 < static_cast(draggingEntities.size())) { moveLabel.append(", "); } } ImGui::Text(moveLabel.c_str()); - SHDragDrop::SetPayload>(SHDragDrop::DRAG_EID, &editor->selectedEntities); + SHDragDrop::SetPayload>(SHDragDrop::DRAG_EID, &draggingEntities); SHDragDrop::EndSource(); } else if (SHDragDrop::BeginTarget()) //If Received DragDrop diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index 0137b951..f3760b4d 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include #include "SHEditorWidgets.hpp" +#include "ECS_Base/Managers/SHEntityManager.h" namespace SHADE { @@ -287,6 +288,35 @@ namespace SHADE return CHANGED; } + bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered) + { + ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); + ImGui::SameLine(); + SHEntity* entity = SHEntityManager::GetEntityByID(value); + std::ostringstream oss; + if (entity) + { + oss << value << ": " << entity->name; + } + std::string entityName = oss.str(); + bool changed = ImGui::InputText("##", &entityName, ImGuiInputTextFlags_ReadOnly); + if (SHDragDrop::BeginTarget()) + { + if (const std::vector* payload = SHDragDrop::AcceptPayload>(SHDragDrop::DRAG_EID)) + { + if (!payload->empty()) + { + value = payload->at(0); + changed = true; + } + SHDragDrop::EndTarget(); + } + } + return changed; + } + bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector& enumNames, bool* isHovered) { // Clamp input value diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index f3051aa1..d4104639 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -308,6 +308,14 @@ namespace SHADE /// True if the value was changed. static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr); /// + /// Creates a drag field widget for int input. + /// + /// Label used to identify this widget. + /// Reference to the variable to store the result. + /// The type of enum to input. diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 1097e203..55fe91da 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -260,7 +260,7 @@ namespace SHADE int val = safe_cast(field->GetValue(object)); int oldVal = val; - if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames)) + if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames, &isHovered)) { field->SetValue(object, val); registerUndoAction(object, field, val, oldVal); @@ -280,12 +280,23 @@ namespace SHADE // Actual Field std::string val = Convert::ToNative(stringVal); std::string oldVal = val; - if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val)) + if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val, &isHovered)) { field->SetValue(object, Convert::ToCLI(val)); registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); } } + else if (field->FieldType == GameObject::typeid) + { + GameObject gameObj = safe_cast(field->GetValue(object)); + uint32_t entityId = gameObj.GetEntity(); + if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered)) + { + GameObject newVal = GameObject(entityId); + field->SetValue(object, newVal); + registerUndoAction(object, field, newVal, gameObj); + } + } else { array^ interfaces = field->FieldType->GetInterfaces(); diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index f114d01b..4b4e44fc 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Vector2.hxx" #include "Math/Vector3.hxx" #include "Utility/Debug.hxx" +#include "Engine/GameObject.hxx" /*-------------------------------------------------------------------------------------*/ /* Macro Functions */ @@ -167,6 +168,11 @@ namespace SHADE fieldNode.push_back(vec.y); fieldNode.push_back(vec.z); } + else if (fieldInfo->FieldType == GameObject::typeid) + { + GameObject gameObj = safe_cast(fieldInfo->GetValue(object)); + fieldNode = gameObj.GetEntity(); + } else // Not any of the supported types { Debug::LogWarning(Convert::ToNative(System::String::Format @@ -242,6 +248,10 @@ namespace SHADE ); } } + else if (fieldInfo->FieldType == GameObject::typeid) + { + fieldInfo->SetValue(object, GameObject(node.as())); + } else // Not any of the supported types { Debug::LogWarning(Convert::ToNative(System::String::Format