diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index 889de5fb..4326daf1 100644 Binary files a/Assets/Shaders/DeferredComposite_CS.shshaderb and b/Assets/Shaders/DeferredComposite_CS.shshaderb differ 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/Kirsch_CS.shshaderb b/Assets/Shaders/Kirsch_CS.shshaderb index 6219d9a9..4c54946c 100644 Binary files a/Assets/Shaders/Kirsch_CS.shshaderb and b/Assets/Shaders/Kirsch_CS.shshaderb differ diff --git a/Assets/Shaders/PureCopy_CS.shshaderb b/Assets/Shaders/PureCopy_CS.shshaderb index 9f1b0534..30a629f5 100644 Binary files a/Assets/Shaders/PureCopy_CS.shshaderb and b/Assets/Shaders/PureCopy_CS.shshaderb differ diff --git a/Assets/Shaders/TestCube_FS.shshaderb b/Assets/Shaders/TestCube_FS.shshaderb index b0113dc7..95b4f62a 100644 Binary files a/Assets/Shaders/TestCube_FS.shshaderb and b/Assets/Shaders/TestCube_FS.shshaderb differ 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 03e23af3..7a7b047a 100644 Binary files a/Assets/Shaders/TestCube_VS.shshaderb and b/Assets/Shaders/TestCube_VS.shshaderb differ diff --git a/Assets/Shaders/TestCube_VS.shshaderb.shmeta b/Assets/Shaders/TestCube_VS.shshaderb.shmeta index b133437b..5c9f895f 100644 --- a/Assets/Shaders/TestCube_VS.shshaderb.shmeta +++ b/Assets/Shaders/TestCube_VS.shshaderb.shmeta @@ -1,3 +1,3 @@ Name: TestCube_VS -ID: 41688429 +ID: 39210065 Type: 2 diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 24f0a214..a4fef1fa 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -108,13 +108,10 @@ namespace Sandbox SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); SHComponentManager::CreateComponentSparseSet(); - SHComponentManager::CreateComponentSparseSet(); + //SHComponentManager::CreateComponentSparseSet(); SHAssetManager::Load(); - auto id = SHFamilyID::GetID(); - auto id2 = SHFamilyID::GetID(); - auto id3 = SHFamilyID::GetID(); SHSystemManager::RegisterRoutine(); 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/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/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/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index a21a9840..3376a2d5 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 @@ -113,10 +114,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/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 682eb9ec..4897fc42 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -151,19 +151,23 @@ 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; + data = new SHPrefabAsset(); break; case AssetType::SCENE: newPath += SCENE_FOLDER; + data = new SHSceneAsset(); break; case AssetType::MATERIAL: newPath += MATERIAL_FOLDER; + data = new SHMaterialAsset(); break; default: @@ -189,6 +193,8 @@ namespace SHADE ) }); + assetData.emplace(id, data); + return id; } diff --git a/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp new file mode 100644 index 00000000..9cb221ff --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.cpp @@ -0,0 +1,68 @@ +#include "SHpch.h" +#include "SHCameraArmComponent.h" + + + +namespace SHADE +{ + + SHCameraArmComponent::SHCameraArmComponent() + :pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true) + { + + } + + + SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept + { + return offset; + } + + 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) + .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 new file mode 100644 index 00000000..2b81a808 --- /dev/null +++ b/SHADE_Engine/src/Camera/SHCameraArmComponent.h @@ -0,0 +1,44 @@ +#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; + SHVec3 offset; + + public: + friend class SHCameraSystem; + SHCameraArmComponent(); + virtual ~SHCameraArmComponent() = default; + + bool lookAtCameraOrigin; + //Getters + //SHMatrix const& GetMatrix() const noexcept; + SHVec3 const& GetOffset() 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.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 f5e08af4..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; @@ -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..98341098 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,7 @@ namespace SHADE viewMatrix = camComponent->GetViewMatrix(); projMatrix = camComponent->GetProjMatrix(); } + } void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) 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 609805f8..d5bd414d 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -1,10 +1,12 @@ #include "SHpch.h" #include "SHCameraSystem.h" +#include "SHCameraArmComponent.h" #include "Math/SHMathHelpers.h" #include "Input/SHInputManager.h" #include "Math/Vector/SHVec2.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" +#include namespace SHADE @@ -59,6 +61,7 @@ namespace SHADE } UpdateCameraComponent(editorCamera); + } void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept { @@ -112,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) @@ -121,6 +126,9 @@ namespace SHADE editorCamera.SetYaw(0.0f); editorCamera.SetRoll(0.0f); editorCamera.movementSpeed = 2.0f; + + SHComponentManager::CreateComponentSparseSet(); + SHComponentManager::CreateComponentSparseSet(); } @@ -134,6 +142,26 @@ namespace SHADE return &editorCamera; } + void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept + { + if (pivot.dirty) + { + + SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() }; + offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch()))); + offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(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); + } + } + + void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept { if (SHComponentManager::HasComponent(camera.GetEID()) == true && &camera != &editorCamera) @@ -151,6 +179,15 @@ namespace SHADE if (camera.dirtyView) { + camera.offset = SHVec3{ 0.0f }; + if (SHComponentManager::HasComponent(camera.GetEID())) + { + auto arm = SHComponentManager::GetComponent(camera.GetEID()); + camera.offset = arm->GetOffset(); + if(arm->lookAtCameraOrigin) + CameraLookAt(camera, camera.position); + } + SHVec3 view, right, UP; @@ -171,9 +208,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; } @@ -221,6 +261,8 @@ namespace SHADE SHVec3 up = { 0.0f,1.0f,0.0f }; + + target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); target += camera.position; @@ -241,6 +283,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,18 +323,115 @@ namespace SHADE } void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept { + constexpr float clampVal = 85.0f; + 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); - 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); + 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 const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept + { + + float initPitch = pitch; + SHVec3 initPos = pos; + SHVec3 translate3, scale; + SHQuaternion quat; + + //SHMatrix viewInverse = viewMatrix; + + viewMatrix.Decompose(translate3, quat, scale); + yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y); + pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x); + + SHVec4 dotPos{ -viewMatrix(0,3),-viewMatrix(1,3), -viewMatrix(2,3), 1.0f }; + SHMatrix mtx = viewMatrix; + mtx(0, 3) = 0.0f; + mtx(1, 3) = 0.0f; + mtx(2, 3) = 0.0f; + mtx.Transpose(); + mtx = SHMatrix::Inverse(mtx); + SHVec4 translate = mtx* dotPos; + + pos.x = translate.x; + pos.y = translate.y; + pos.z = translate.z; + + } + void SHCameraSystem::SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept + { + 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 68071160..98fd442f 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: @@ -19,6 +22,11 @@ namespace SHADE SHResourceLibrary directorLibrary; std::vector directorHandleList; + + void UpdateCameraComponent(SHCameraComponent& camera) noexcept; + void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept; + + public: SHCameraSystem(void) = default; virtual ~SHCameraSystem(void) = default; @@ -39,7 +47,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,12 +59,10 @@ 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 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; }; 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/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index c4a86785..2fecae25 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -17,6 +17,7 @@ #include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHColliderComponent.h" #include "Camera/SHCameraComponent.h" +#include "Camera/SHCameraArmComponent.h" #include "SHEditorComponentView.h" namespace SHADE @@ -126,6 +127,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 @@ -136,6 +140,7 @@ namespace SHADE { DrawAddComponentButton(eid); DrawAddComponentButton(eid); + DrawAddComponentButton(eid); DrawAddComponentButton(eid); // Components that require Transforms diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 7391da2c..97380fa3 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 { @@ -109,9 +111,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 = 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 @@ -180,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" }); @@ -207,10 +201,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 c5908db4..3f899446 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" @@ -329,6 +328,7 @@ namespace SHADE SHTextureLibrary texLibrary; SHSamplerCache samplerCache; SHMaterialInstanceCache materialInstanceCache; + // Viewports #ifdef SHEDITOR Handle editorViewport; @@ -349,10 +349,13 @@ namespace SHADE // Temp Cameras Handle worldCamera; Handle screenCamera; - - SHShaderModuleLibrary shaderModuleLibrary; - // Temp Materials + // Built-In Shaders + Handle defaultVertShader; + Handle defaultFragShader; + Handle deferredCompositeShader; + + // Built-In Materials Handle defaultMaterial; Handle worldRenderGraph; 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/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/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 36836404..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); - - // 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) - { - // 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; - } - 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 454759e4..e7eed326 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 { @@ -257,7 +258,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,82 +270,110 @@ 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; + } + + // Sync colliders + + if (colliderComponent) + { + const bool COMPONENT_ACTIVE = colliderComponent->isActive; + SyncActiveStates(physicsObject, colliderComponent->isActive); + + if (!COMPONENT_ACTIVE) + continue; + + physicsObject.SyncColliders(colliderComponent); + } } } void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept { - auto* system = reinterpret_cast(GetSystem()); - fixedTimeStep = 1.0 / system->fixedDT; + 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; int count = 0; while (accumulatedTime > fixedTimeStep) { - system->world->update(static_cast(fixedTimeStep)); + if (scriptSys) + { + scriptSys->ExecuteFixedUpdates(); + } + 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) + if (physicsSystem->worldUpdated) { - system->SyncTransforms(); + physicsSystem->SyncTransforms(); - // TODO(Kah Wei): Take Collision & Trigger messages here + // 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!"); + } - system->ClearInvalidCollisions(); + physicsSystem->ClearInvalidCollisions(); } } @@ -349,26 +381,10 @@ namespace SHADE { for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i) { - auto contactPair = callbackData.getContactPair(i); - SHCollisionEvent newCollisionEvent = 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] == 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; - } + UpdateEventContainers(NEW_EVENT, collisionInfo); } } @@ -376,26 +392,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 == collisionInfo.end()) - { - // Add new event - triggerInfo.emplace_back(newTriggerEvent); - } - else - { - existingEvent->collisionState = newTriggerEvent.collisionState; - } + UpdateEventContainers(NEW_EVENT, triggerInfo); } } @@ -432,11 +432,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 @@ -491,155 +491,54 @@ 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; - } - } - } - - 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; + CLEAR(collisionInfo); + CLEAR(triggerInfo); } - 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()); @@ -728,14 +627,23 @@ namespace SHADE const EntityID ENTITY_ID = EVENT_DATA->data->eid; auto* physicsObject = GetPhysicsObject(ENTITY_ID); - SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") + 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) + { + if (SHComponentManager::HasComponent(entityID)) + reinterpret_cast(object.rp3dBody)->setIsSleeping(false); + } + 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 @@ -747,13 +655,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) @@ -766,6 +667,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 744615d1..dd399f96 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -28,6 +28,7 @@ namespace SHADE { + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -176,22 +177,24 @@ 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; + static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept; + void ClearInvalidCollisions () 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..957fb3aa --- /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; + + // 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; + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp new file mode 100644 index 00000000..4b292340 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.cpp @@ -0,0 +1,65 @@ +/************************************************************************************//*! +\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" +#include "Physics/SHPhysicsUtils.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; + } + + 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 new file mode 100644 index 00000000..da6a0433 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystemInterface.h @@ -0,0 +1,46 @@ +/************************************************************************************//*! +\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 + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHCollisionEvent; + + /*-----------------------------------------------------------------------------------*/ + /* 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; + [[nodiscard]] static double GetFixedDT() noexcept; + }; +} diff --git a/SHADE_Engine/src/Resource/SHResourceManager.h b/SHADE_Engine/src/Resource/SHResourceManager.h index 84f93b10..61689420 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.h +++ b/SHADE_Engine/src/Resource/SHResourceManager.h @@ -17,9 +17,45 @@ 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" +#include "Graphics/MiddleEnd/Interface/SHMaterial.h" +#include "Assets/Asset Types/SHMaterialAsset.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; + }; + template<> + struct SHResourceLoader + { + using AssetType = SHMaterialAsset; + }; + + /// /// Static class responsible for loading and caching runtime resources from their /// serialised Asset IDs. @@ -124,6 +160,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..15834cdf 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. @@ -13,12 +13,17 @@ 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" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Tools/SHLog.h" +#include "Graphics/Shaders/SHVkShaderModule.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" namespace SHADE { @@ -40,67 +45,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 +109,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 +117,7 @@ namespace SHADE assetIdMap.emplace(TYPE, HandleAssetMap{}); typedFreeFuncMap.emplace ( - TYPE, + TYPE, [TYPE](AssetID assetId) { static_cast>(SHResourceManager::handlesMap[TYPE][assetId]).Free(); @@ -169,4 +126,129 @@ 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) + { + auto shader = gfxSystem->GetDevice()->CreateShaderModule + ( + assetData.spirvBinary, + "main", + static_cast(assetData.shaderType), + assetData.name + ); + shader->Reflect(); + return shader; + } + // Materials + else if constexpr (std::is_same_v) + { + // Get the data we need to construct + SHMaterialSpec matSpec = YAML::Node(assetData.data).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/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_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index a6f02249..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 { @@ -303,104 +306,45 @@ 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; - 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 - )); - } - */ - - // 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()].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<> @@ -413,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) @@ -424,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; } 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/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 }; /// 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 diff --git a/SHADE_Managed/src/Physics/CollisionInfo.cxx b/SHADE_Managed/src/Physics/CollisionInfo.cxx new file mode 100644 index 00000000..135760db --- /dev/null +++ b/SHADE_Managed/src/Physics/CollisionInfo.cxx @@ -0,0 +1,36 @@ +/************************************************************************************//*! +\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" +#include "Components/RigidBody.hxx" +#include "Components/Collider.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(); + } +} diff --git a/SHADE_Managed/src/Physics/CollisionInfo.hxx b/SHADE_Managed/src/Physics/CollisionInfo.hxx new file mode 100644 index 00000000..40cb9ccc --- /dev/null +++ b/SHADE_Managed/src/Physics/CollisionInfo.hxx @@ -0,0 +1,66 @@ +/************************************************************************************//*! +\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" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + ref class RigidBody; + ref class Collider; + ref class CollisionShape; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /// + /// 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(); + } + }; +} 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 +} diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index d7492fdc..407d0fa8 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,95 @@ 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) + { + auto entities = + { + std::make_pair(collisionInfo.GetEntityA(), collisionInfo.GetEntityB()), + std::make_pair(collisionInfo.GetEntityB(), collisionInfo.GetEntityA()) + }; + for (auto entity : entities) + { + // 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) + { + 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) + { + auto entities = + { + std::make_pair(triggerInfo.GetEntityA(), triggerInfo.GetEntityB()), + std::make_pair(triggerInfo.GetEntityB(), triggerInfo.GetEntityA()) + }; + for (auto entity : entities) + { + // 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) + { + 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 +599,7 @@ namespace SHADE } return true; - SAFE_NATIVE_CALL_END_N("SHADE.ScriptStore") + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") return false; } @@ -559,7 +649,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 */ diff --git a/TempScriptsFolder/PhysicsTest.cs b/TempScriptsFolder/PhysicsTest.cs index add5971d..c2f707cf 100644 --- a/TempScriptsFolder/PhysicsTest.cs +++ b/TempScriptsFolder/PhysicsTest.cs @@ -40,4 +40,34 @@ 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}"); + } + 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