From 97013ba73ca16501a7bd13c5f12fe35e519800f6 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 9 Mar 2023 21:18:05 +0800 Subject: [PATCH 01/12] Added override for simulating gravity in SimulateBody method --- SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp | 6 ++---- SHADE_Engine/src/Physics/System/SHPhysicsSystem.h | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 2e5f5c2c..f19002e6 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -275,8 +275,6 @@ namespace SHADE for (size_t i = 0; i < SHVec3::SIZE; ++i) localInvInertia[i] = 1.0f / localInvInertia[i]; - - // Build raycast layer from colliders. If none exist....then this never stops simulating technically. // I'm too lazy to handle that case, so I'll just throw an error. uint16_t raycastLayers = 0; @@ -302,7 +300,7 @@ namespace SHADE int iterationCounter = simInfo.maxSteps; do { - raycastInfo.distance = linearVelocity.Length(); + raycastInfo.distance = linearVelocity.Length() * simInfo.timeStep; // Do not take the entire velocity's length as that is for an entire second. raycastInfo.ray.position = bodyPosition; raycastInfo.ray.direction = SHVec3::Normalise(linearVelocity); @@ -337,7 +335,7 @@ namespace SHADE // Integrate Velocities // Integrate forces and gravity into linear velocity const SHVec3 LINEAR_ACCELERATION = accumulatedForce * invMass; - const SHVec3 GRAVITATIONAL_ACCELERATION = rigidBody->IsGravityEnabled() ? worldState.settings.gravity * rigidBody->GetGravityScale() : SHVec3::Zero; + const SHVec3 GRAVITATIONAL_ACCELERATION = simInfo.simulateGravity ? worldState.settings.gravity * rigidBody->GetGravityScale() : SHVec3::Zero; linearVelocity += (LINEAR_ACCELERATION + GRAVITATIONAL_ACCELERATION) * simInfo.timeStep * LINEAR_LOCK; angularVelocity += worldInvInertia * (accumulatedTorque * simInfo.timeStep); diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index f466481d..0a1e2057 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -81,6 +81,7 @@ namespace SHADE // Whether or not to clear the force after the first iteration bool continuousForce = false; + bool simulateGravity = true; float timeStep = static_cast(SHPhysicsConstants::DEFAULT_FIXED_DT); int maxSteps = -1; }; From 6dcee04077c3a1341f7dc90b64b9eb566da27cdf Mon Sep 17 00:00:00 2001 From: Glence Date: Sat, 11 Mar 2023 02:19:42 +0800 Subject: [PATCH 02/12] remove unnecessary script --- Assets/Scenes/Level2.shade | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Assets/Scenes/Level2.shade b/Assets/Scenes/Level2.shade index 4c2918a4..f6955c77 100644 --- a/Assets/Scenes/Level2.shade +++ b/Assets/Scenes/Level2.shade @@ -5535,13 +5535,7 @@ Canvas Height: 1080 Scale by canvas width: false IsActive: false - Scripts: - - Type: PauseMenu - Enabled: true - resumeBtn: 8 - retryBtn: 458 - quitBtn: 0 - canvas: 10 + Scripts: ~ - EID: 8 Name: ResumeButton IsActive: true From 6bfa0d0eca15c1675e2ea7b248eb0fd9497ae1ed Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 11 Mar 2023 02:31:48 +0800 Subject: [PATCH 03/12] Fixed post build command for SHADE_CSharp --- SHADE_CSharp/premake5.lua | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/SHADE_CSharp/premake5.lua b/SHADE_CSharp/premake5.lua index c94bb438..4d5f798c 100644 --- a/SHADE_CSharp/premake5.lua +++ b/SHADE_CSharp/premake5.lua @@ -25,34 +25,25 @@ project "SHADE_CSharp" "SHADE_Engine" } + postbuildcommands + { + "xcopy /r /y /q \"$(OutputPath)net5.0\\SHADE_CSharp.xml\" \"%{outputdir}\"", + "xcopy /r /y /q \"$(OutputPath)net5.0\\SHADE_CSharp.pdb\" \"%{outputdir}\"" + } + warnings 'Extra' filter "configurations:Debug" symbols "On" defines {"_DEBUG"} - postbuildcommands - { - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Debug\\net5.0\\SHADE_CSharp.xml\" \"%{outputdir}\"", - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Debug\\net5.0\\SHADE_CSharp.pdb\" \"%{outputdir}\"" - } filter "configurations:Release" optimize "On" defines{"_RELEASE"} - postbuildcommands - { - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Release\\net5.0\\SHADE_CSharp.xml\" \"%{outputdir}\"", - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Release\\net5.0\\SHADE_CSharp.pdb\" \"%{outputdir}\"" - } filter "configurations:Publish" optimize "On" defines{"_RELEASE"} - postbuildcommands - { - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Release\\net5.0\\SHADE_CSharp.xml\" \"%{outputdir}\"", - "xcopy /r /y /q \"$(SolutionDir)\\bin\\Release\\net5.0\\SHADE_CSharp.pdb\" \"%{outputdir}\"" - } require "vstudio" From b7520b683629cfcd53ba26a0f7b50ac502f197f0 Mon Sep 17 00:00:00 2001 From: Glence Date: Sat, 11 Mar 2023 11:07:21 +0800 Subject: [PATCH 04/12] added animation for the other scenes --- Assets/Scenes/Level2.shade | 34 +++++++++++++++++-- Assets/Scenes/Level3.shade | 34 +++++++++++++++++-- .../Player/PlayerStates/UT_PlayerJumpState.cs | 2 +- .../Gameplay/Player/SC_PlayerController.cs | 12 ++++++- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/Assets/Scenes/Level2.shade b/Assets/Scenes/Level2.shade index f6955c77..c3c40c44 100644 --- a/Assets/Scenes/Level2.shade +++ b/Assets/Scenes/Level2.shade @@ -3059,7 +3059,7 @@ IsActive: true Renderable Component: Mesh: 149697411 - Material: 126974645 + Material: 128805346 IsActive: true RigidBody Component: Type: Dynamic @@ -3089,6 +3089,10 @@ Position Offset: {x: 0, y: 0.300000012, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: - Type: PlayerController Enabled: true @@ -3116,6 +3120,20 @@ throwItem: false rayDistance: 0.75 rayHeight: 0.100000001 + - Type: PlayerAnimations + Enabled: true + playerIdleClip: 227450439 + playerWalkClip: 229125027 + playerRunClip: 228149757 + playerPickUpClip: 219605278 + playerCarryIdleClip: 231128260 + playerCarryWalkClip: 227671720 + playerThrowClip: 223399345 + playerJumpStartClip: 223009573 + playerJumpLoopClip: 230974023 + playerJumpEndClip: 228134756 + silhouettePlayer: 462 + silhouetteBag: 465 - EID: 3 Name: HoldingPoint IsActive: true @@ -3178,7 +3196,11 @@ IsActive: true Renderable Component: Mesh: 144838771 - Material: 123745521 + Material: 117923942 + IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 462 @@ -3195,6 +3217,10 @@ Mesh: 149697411 Material: 126391182 IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: ~ - EID: 465 Name: SilouetteBag @@ -3210,6 +3236,10 @@ Mesh: 144838771 Material: 126391182 IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: ~ - EID: 239 Name: RespawnPoint diff --git a/Assets/Scenes/Level3.shade b/Assets/Scenes/Level3.shade index 5753c783..b116d292 100644 --- a/Assets/Scenes/Level3.shade +++ b/Assets/Scenes/Level3.shade @@ -11620,7 +11620,7 @@ IsActive: true Renderable Component: Mesh: 149697411 - Material: 126974645 + Material: 128805346 IsActive: true RigidBody Component: Type: Dynamic @@ -11650,6 +11650,10 @@ Position Offset: {x: 0, y: 0.300000012, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: - Type: PlayerController Enabled: true @@ -11677,6 +11681,20 @@ throwItem: false rayDistance: 0.75 rayHeight: 0.100000001 + - Type: PlayerAnimations + Enabled: true + playerIdleClip: 227450439 + playerWalkClip: 229125027 + playerRunClip: 228149757 + playerPickUpClip: 219605278 + playerCarryIdleClip: 231128260 + playerCarryWalkClip: 227671720 + playerThrowClip: 223399345 + playerJumpStartClip: 223009573 + playerJumpLoopClip: 230974023 + playerJumpEndClip: 228134756 + silhouettePlayer: 462 + silhouetteBag: 465 - EID: 66068 Name: HoldingPoint IsActive: true @@ -11739,7 +11757,11 @@ IsActive: true Renderable Component: Mesh: 144838771 - Material: 123745521 + Material: 117923942 + IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 IsActive: true Scripts: ~ - EID: 462 @@ -11756,6 +11778,10 @@ Mesh: 149697411 Material: 126391182 IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: ~ - EID: 465 Name: SilouetteBag @@ -11771,6 +11797,10 @@ Mesh: 144838771 Material: 126391182 IsActive: true + Animator Component: + Rig: 77816045 + AnimationController: 0 + IsActive: true Scripts: ~ - EID: 66065 Name: RespawnPoint diff --git a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerJumpState.cs b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerJumpState.cs index 1adfdf67..8d5350d7 100644 --- a/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerJumpState.cs +++ b/Assets/Scripts/Gameplay/Player/PlayerStates/UT_PlayerJumpState.cs @@ -9,7 +9,7 @@ public class PlayerJumpState : BaseState } public override void OnEnter() { - //Debug.Log("WALK ENTER"); + //Debug.Log("jump"); } public override void update() { diff --git a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs index 78b92b84..9bac991b 100644 --- a/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs +++ b/Assets/Scripts/Gameplay/Player/SC_PlayerController.cs @@ -324,6 +324,8 @@ public class PlayerController : Script if ( (Input.GetKeyDown(Input.KeyCode.Space) || landedOnJumpPad ) && isGrounded && rb != null) { currentState = RaccoonStates.JUMP; + if (stateMachine && !stateMachine.IsState(typeof(PlayerJumpState))) + stateMachine.SetState(typeof(PlayerJumpState)); Vector3 v = rb.LinearVelocity; v.y = initialJumpVel * 0.5f; if (holdItem && pat != null && pat.item.GetScript() != null) @@ -346,8 +348,12 @@ public class PlayerController : Script } } - if(!isGrounded && rb != null && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space))) + if (!isGrounded && rb != null && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space))) + { currentState = RaccoonStates.FALLING; + if (stateMachine && !stateMachine.IsState(typeof(PlayerFallState))) + stateMachine.SetState(typeof(PlayerFallState)); + } } @@ -378,7 +384,11 @@ public class PlayerController : Script { isGrounded = true; if (currentState == RaccoonStates.FALLING) + { currentState = RaccoonStates.LANDED; + if (stateMachine && !stateMachine.IsState(typeof(PlayerLandState))) + stateMachine.SetState(typeof(PlayerLandState)); + } } else isGrounded = false; From b81cff4638c5000bc1e3af461686bffdfeb01200 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 11 Mar 2023 13:07:25 +0800 Subject: [PATCH 05/12] Fixed creation of audio handler with invalid path in endscene and main menu. remove set volume for homeowner detect sound. audio system now stops all instances before they are release when scene changes --- .../Gameplay/AIBehaviour/Implemented/Homeowner1.cs | 2 +- Assets/Scripts/UI/SC_EndScene.cs | 12 ++++++------ Assets/Scripts/UI/SC_MainMenu.cs | 4 ++-- SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Assets/Scripts/Gameplay/AIBehaviour/Implemented/Homeowner1.cs b/Assets/Scripts/Gameplay/AIBehaviour/Implemented/Homeowner1.cs index 552a6aad..1a7d4a81 100644 --- a/Assets/Scripts/Gameplay/AIBehaviour/Implemented/Homeowner1.cs +++ b/Assets/Scripts/Gameplay/AIBehaviour/Implemented/Homeowner1.cs @@ -121,7 +121,7 @@ public partial class Homeowner1 : BehaviourTree AudioHandler.audioClipHandlers["SFXDetectSting"] = Audio.CreateAudioClip("event:/Music/stingers/player_detected"); AudioHandler.audioClipHandlers["SFXHumming"] = Audio.CreateAudioClip("event:/Homeowner/homeowner_humming"); Audio.AttachAudioClipToObject(AudioHandler.audioClipHandlers["SFXHumming"], GameObject.EntityId); - AudioHandler.audioClipHandlers["SFXHumming"].SetVolume(0.15f); + //AudioHandler.audioClipHandlers["SFXHumming"].SetVolume(0.15f); AudioHandler.audioClipHandlers["SFXHumming"].Play(); if (aiInstance != null && aiInstance != this) diff --git a/Assets/Scripts/UI/SC_EndScene.cs b/Assets/Scripts/UI/SC_EndScene.cs index 3812db2a..5fbca3b6 100644 --- a/Assets/Scripts/UI/SC_EndScene.cs +++ b/Assets/Scripts/UI/SC_EndScene.cs @@ -10,8 +10,8 @@ public class EndScene : Script protected override void awake() { - AudioHandler.audioClipHandlers["SFXMouseDownElement"] = Audio.CreateAudioClip("event:/UI/mouse_down_element"); - AudioHandler.audioClipHandlers["SFXUISuccess"] = Audio.CreateAudioClip("event:/UI/success"); + //AudioHandler.audioClipHandlers["SFXMouseDownElement"] = Audio.CreateAudioClip("event:/UI/mouse_down_element"); + //AudioHandler.audioClipHandlers["SFXUISuccess"] = Audio.CreateAudioClip("event:/UI/success"); } protected override void start() @@ -27,28 +27,28 @@ public class EndScene : Script if (Input.GetKeyDown(Input.KeyCode.R)) { //Audio.PlaySFXOnce2D("event:/UI/mouse_down_element"); - AudioHandler.audioClipHandlers["SFXMouseDownElement"].Play(); + //AudioHandler.audioClipHandlers["SFXMouseDownElement"].Play(); } if (Input.GetKeyUp(Input.KeyCode.R)) { //Audio.PlaySFXOnce2D("event:/UI/success"); //Audio.StopAllSounds(); AudioHandler.StopAllSounds(false); - AudioHandler.audioClipHandlers["SFXUISuccess"].Play(); + //AudioHandler.audioClipHandlers["SFXUISuccess"].Play(); SceneManager.ChangeScene(mainGameScene); } if (Input.GetKeyDown(Input.KeyCode.M)) { //Audio.PlaySFXOnce2D("event:/UI/mouse_down_element"); - AudioHandler.audioClipHandlers["SFXMouseDownElement"].Play(); + //AudioHandler.audioClipHandlers["SFXMouseDownElement"].Play(); } if (Input.GetKeyUp(Input.KeyCode.M)) { //Audio.PlaySFXOnce2D("event:/UI/success"); //Audio.StopAllSounds(); AudioHandler.StopAllSounds(false); - AudioHandler.audioClipHandlers["SFXUISuccess"].Play(); + //AudioHandler.audioClipHandlers["SFXUISuccess"].Play(); SceneManager.ChangeScene(mainMainScene); } diff --git a/Assets/Scripts/UI/SC_MainMenu.cs b/Assets/Scripts/UI/SC_MainMenu.cs index 8252344d..33958118 100644 --- a/Assets/Scripts/UI/SC_MainMenu.cs +++ b/Assets/Scripts/UI/SC_MainMenu.cs @@ -13,8 +13,8 @@ public class MainMenu : Script protected override void awake() { AudioHandler.audioClipHandlers["BGMMainMenu"] = Audio.CreateAudioClip("event:/Music/main_menu"); - AudioHandler.audioClipHandlers["SFXMouseDownElement"] = Audio.CreateAudioClip("event:/UI/mouse_down_element"); - AudioHandler.audioClipHandlers["SFXUISuccess"] = Audio.CreateAudioClip("event:/UI/success"); + //AudioHandler.audioClipHandlers["SFXMouseDownElement"] = Audio.CreateAudioClip("event:/UI/mouse_down_element"); + //AudioHandler.audioClipHandlers["SFXUISuccess"] = Audio.CreateAudioClip("event:/UI/success"); //Audio.PlayBGMOnce2D("event:/Music/main_menu"); AudioHandler.audioClipHandlers["BGMMainMenu"].Play(); diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index 1bfa97ce..591b3e8c 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -840,6 +840,7 @@ namespace SHADE auto [begin, end] = audioClipLibrary.GetDenseAccess(); for (auto& it = begin; it != end; ++it) { + it->instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); it->instance->release(); } From e82dcdee20253953065b09a3566622f6d54d33d2 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 11 Mar 2023 18:39:06 +0800 Subject: [PATCH 06/12] fix audio not stopping between scene for non editor builds --- Assets/Application.SHConfig | 2 +- SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Assets/Application.SHConfig b/Assets/Application.SHConfig index 97477f5a..5673556d 100644 --- a/Assets/Application.SHConfig +++ b/Assets/Application.SHConfig @@ -1,4 +1,4 @@ Start in Fullscreen: false -Starting Scene ID: 91478134 +Starting Scene ID: 97158628 Window Size: {x: 1920, y: 1080} Window Title: SHADE Engine \ No newline at end of file diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index 591b3e8c..724c31a0 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -134,11 +134,12 @@ namespace SHADE const ReceiverPtr ON_PAUSE_RECEIVER_PTR = std::dynamic_pointer_cast(ON_PAUSE_RECEIVER); SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, ON_PAUSE_RECEIVER_PTR); + #endif + const std::shared_ptr ON_SCENE_EXIT_RECEIVER{ std::make_shared>(this, &SHAudioSystem::onSceneExit) }; const ReceiverPtr ON_SCENE_EXIT_RECEIVER_PTR = std::dynamic_pointer_cast(ON_SCENE_EXIT_RECEIVER); SHEventManager::SubscribeTo(SH_SCENE_EXIT_POST, ON_SCENE_EXIT_RECEIVER_PTR); - #endif } void SHADE::SHAudioSystem::Run(double dt) From 0be385c6bd4a6e29dab4c72cbbd7e1516826e866 Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sat, 11 Mar 2023 21:17:28 +0800 Subject: [PATCH 07/12] Fixed xcopy command for csharp project --- SHADE_CSharp/premake5.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SHADE_CSharp/premake5.lua b/SHADE_CSharp/premake5.lua index 4d5f798c..0bb5f448 100644 --- a/SHADE_CSharp/premake5.lua +++ b/SHADE_CSharp/premake5.lua @@ -24,11 +24,9 @@ project "SHADE_CSharp" { "SHADE_Engine" } - postbuildcommands { - "xcopy /r /y /q \"$(OutputPath)net5.0\\SHADE_CSharp.xml\" \"%{outputdir}\"", - "xcopy /r /y /q \"$(OutputPath)net5.0\\SHADE_CSharp.pdb\" \"%{outputdir}\"" + "xcopy /r /y /q \"%{wks.location}/bin/$(Configuration)\\net5.0\\SHADE_CSharp.pdb\" \"%{wks.location}/bin/$(Configuration)\"" } warnings 'Extra' From d0067b09c959e14fa82e7383eef1788b1562540d Mon Sep 17 00:00:00 2001 From: Glence Date: Sat, 11 Mar 2023 21:25:56 +0800 Subject: [PATCH 08/12] Minor bug fix set animation dt back to default when retry or quit --- Assets/Scripts/UI/SC_PauseMenu.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Assets/Scripts/UI/SC_PauseMenu.cs b/Assets/Scripts/UI/SC_PauseMenu.cs index 7dd528b0..a5d14a87 100644 --- a/Assets/Scripts/UI/SC_PauseMenu.cs +++ b/Assets/Scripts/UI/SC_PauseMenu.cs @@ -70,6 +70,8 @@ public class PauseMenu : Script GameManager.Instance.GamePause = false; GameManager.Instance.stealFoodPopUpDone = false; GameManager.Instance.PreviewLevelDone = false; + Application.FixDeltaTime = Time.DefaultFixDeltaTime; + AnimationSystem.TimeScale = AnimationSystem.DefaultTimeScale; }); } else @@ -83,6 +85,8 @@ public class PauseMenu : Script quit.OnRelease.RegisterAction(() => { Audio.StopAllSounds(); + Application.FixDeltaTime = Time.DefaultFixDeltaTime; + AnimationSystem.TimeScale = AnimationSystem.DefaultTimeScale; //go to main menu SceneManager.ChangeScene(97158628); }); From f844079eea4ca611e19793bdd6c214a749daa77f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 14 Mar 2023 14:07:46 +0800 Subject: [PATCH 09/12] Added support for changing playback speed of an animation clip --- .../src/Animation/SHAnimationClip.cpp | 13 +++++---- SHADE_Engine/src/Animation/SHAnimationClip.h | 28 ++++++++++++++----- .../src/Animation/SHAnimationController.cpp | 13 +++++---- .../src/Animation/SHAnimatorComponent.cpp | 2 +- .../Asset Types/SHAnimClipContainerAsset.h | 1 + .../SHRawAnimInspector.cpp | 15 +++++++++- .../SHRawAnimInspector.h | 1 + .../src/Resource/SHResourceManager.hpp | 3 +- 8 files changed, 55 insertions(+), 21 deletions(-) diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.cpp b/SHADE_Engine/src/Animation/SHAnimationClip.cpp index 2066506f..b45701d8 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationClip.cpp @@ -20,12 +20,13 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Constructors */ /*-----------------------------------------------------------------------------------*/ - SHAnimationClip::SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame) - : rawAnim { rawAnimHandle } - , startFrameIndex { firstFrame } - , endFrameIndex { lastFrame } - , duration { 0.0f } - , startTimeStamp { 0.0f } + SHAnimationClip::SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame, float playbackMultiplier) + : rawAnim { rawAnimHandle } + , startFrameIndex { firstFrame } + , endFrameIndex { lastFrame } + , duration { 0.0f } + , startTimeStamp { 0.0f } + , playbackSpeedMultiplier { playbackMultiplier } { if (!rawAnim) return; diff --git a/SHADE_Engine/src/Animation/SHAnimationClip.h b/SHADE_Engine/src/Animation/SHAnimationClip.h index 6b97c955..2c6b6561 100644 --- a/SHADE_Engine/src/Animation/SHAnimationClip.h +++ b/SHADE_Engine/src/Animation/SHAnimationClip.h @@ -41,25 +41,39 @@ namespace SHADE /// Handle to the raw animation data. /// First frame to be played. /// Last frame to be played. - SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame); + /// Multiplier for the playback speed. + SHAnimationClip(Handle rawAnimHandle, int firstFrame, int lastFrame, float playbackMultiplier = 1.0f); /*---------------------------------------------------------------------------------*/ /* Getter Functions */ /*---------------------------------------------------------------------------------*/ inline Handle GetRawAnimation() const noexcept { return rawAnim; } inline int GetStartFrameIndex() const noexcept { return startFrameIndex; } - inline int GetEndFrameIndex() const noexcept { return endFrameIndex; } - inline float GetTotalDuration() const noexcept { return duration; } + inline int GetEndFrameIndex() const noexcept { return endFrameIndex; }\ inline float GetStartTimeStamp() const noexcept { return startTimeStamp; } + inline float GetPlaybackSpeedMultiplier() const noexcept { return playbackSpeedMultiplier; } + /// + /// Retrieves the duration of the animation as if the playback speed multiplier is + /// in it's default value of 1.0f. + /// + /// Duration of the animation in seconds. + inline float GetTotalDuration() const noexcept { return duration; } + /// + /// Retrieves the duration of the animation with the playback speed multiplier + /// taken into account. + /// + /// True duration of the animation in seconds. + inline float GetTrueDuration() const noexcept { return duration / playbackSpeedMultiplier; } private: /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ Handle rawAnim; - int startFrameIndex; // First Frame - int endFrameIndex; // Last Frame (inclusive) - float duration; // Total playback time - float startTimeStamp; // Starting time stamp of the raw anim + int startFrameIndex; // First Frame + int endFrameIndex; // Last Frame (inclusive) + float duration; // Total playback time + float startTimeStamp; // Starting time stamp of the raw anim + float playbackSpeedMultiplier; // Multiplier applied to the playback of an animation clip }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Animation/SHAnimationController.cpp b/SHADE_Engine/src/Animation/SHAnimationController.cpp index 3c04614a..e105c0da 100644 --- a/SHADE_Engine/src/Animation/SHAnimationController.cpp +++ b/SHADE_Engine/src/Animation/SHAnimationController.cpp @@ -62,18 +62,21 @@ namespace SHADE if (!instData.CurrentNode) return; + // Get the clip + Handle clip = instData.CurrentNode->Clip; + // Update the current playback - instData.ClipPlaybackTime += dt; + instData.ClipPlaybackTime += dt * clip->GetPlaybackSpeedMultiplier(); // Check if we finished playing - const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - instData.CurrentNode->Clip->GetStartTimeStamp(); - if (CLIP_CURR_PLAYED_TIME > instData.CurrentNode->Clip->GetTotalDuration()) + const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - clip->GetStartTimeStamp(); + if (CLIP_CURR_PLAYED_TIME > clip->GetTotalDuration()) { // Clamp - instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp() + instData.CurrentNode->Clip->GetTotalDuration(); + instData.ClipPlaybackTime = clip->GetStartTimeStamp() + clip->GetTotalDuration(); // Go to next state - Handle originalClip = instData.CurrentNode->Clip; + Handle originalClip = clip; bool stateChanged = false; for (const auto& transition : instData.CurrentNode->Transitions) { diff --git a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp index 294d8098..923fb876 100644 --- a/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp +++ b/SHADE_Engine/src/Animation/SHAnimatorComponent.cpp @@ -254,7 +254,7 @@ namespace SHADE } void SHAnimatorComponent::updateManualClipState(float dt) { - currPlaybackTime += dt; + currPlaybackTime += dt * currClip->GetPlaybackSpeedMultiplier(); const float CLIP_CURR_PLAYED_TIME = currPlaybackTime - currClip->GetStartTimeStamp(); if (CLIP_CURR_PLAYED_TIME > currClip->GetTotalDuration()) { diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index 28d3b697..15fc449d 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -26,6 +26,7 @@ namespace SHADE uint32_t firstIndex; uint32_t lastIndex; AssetID animRawDataAssetId; // Not serialised, only populated during runtime from parent asset + float playbackMultiplier = 1.0f; }; struct SH_API SHAnimClipContainerAsset final : SHAssetData diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp index 332bf6e9..e85efaf4 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.cpp @@ -54,6 +54,7 @@ namespace SHADE newAssetName.clear(); firstIndex = 0; lastIndex = rawAnimation->GetTotalFrames(); + playbackMultiplier = 1.0f; } // Assign callback @@ -72,6 +73,9 @@ namespace SHADE SHEditorUI::PushID(1); SHEditorUI::InputUnsignedInt("Last Frame Index", lastIndex); SHEditorUI::PopID(); + SHEditorUI::PushID(2); + SHEditorUI::InputFloat("Playback Multiplier", playbackMultiplier); + SHEditorUI::PopID(); // Invalid values const bool INVALID_CONFIG = newAssetName.empty() || firstIndex > lastIndex; @@ -88,6 +92,7 @@ namespace SHADE animClip->firstIndex = firstIndex; animClip->lastIndex = lastIndex; animClip->animRawDataAssetId = SHResourceManager::GetAssetID(rawAnimation).value_or(0); + animClip->playbackMultiplier = playbackMultiplier; SHAssetManager::SaveAsset(containerAsset->id); // Close @@ -168,6 +173,7 @@ namespace SHADE int firstIndex = animClip->GetStartFrameIndex(); int endIndex = animClip->GetEndFrameIndex(); + float playbackMp = animClip->GetPlaybackSpeedMultiplier(); ImGui::Separator(); ImGui::Text(animClipName.has_value() ? animClipName.value().c_str() : ""); @@ -183,12 +189,18 @@ namespace SHADE [&]() { return endIndex; }, [&](int i) { endIndex = i; } ); + changed |= SHEditorWidgets::DragFloat + ( + "Playback Multiplier", + [&]() { return playbackMp; }, + [&](float f) { playbackMp = f; } + ); // If there's a change we need to commit changes if (changed && firstIndex < endIndex) { // Update runtime asset - *animClip = SHAnimationClip(currRawAnim, firstIndex, endIndex); + *animClip = SHAnimationClip(currRawAnim, firstIndex, endIndex, playbackMp); // Update serialized asset auto assetId = SHResourceManager::GetAssetID(animClip); @@ -197,6 +209,7 @@ namespace SHADE auto const animAsset = SHAssetManager::GetData(assetId.value()); animAsset->firstIndex = firstIndex; animAsset->lastIndex = endIndex; + animAsset->playbackMultiplier = playbackMp; SHAssetManager::SaveAsset(containerAsset->id); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h index 6790cded..550bd158 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h +++ b/SHADE_Engine/src/Editor/EditorWindow/RawAnimationInspector/SHRawAnimInspector.h @@ -62,6 +62,7 @@ namespace SHADE std::string newAssetName; uint32_t firstIndex = 0; uint32_t lastIndex = 0; + float playbackMultiplier = 1.0f; Handle rawAnimation; SHAsset* containerAsset{nullptr}; SHAnimClipContainerAsset* container{nullptr}; diff --git a/SHADE_Engine/src/Resource/SHResourceManager.hpp b/SHADE_Engine/src/Resource/SHResourceManager.hpp index 6474b478..d2bc9241 100644 --- a/SHADE_Engine/src/Resource/SHResourceManager.hpp +++ b/SHADE_Engine/src/Resource/SHResourceManager.hpp @@ -372,7 +372,8 @@ namespace SHADE ( LoadOrGet(assetData.animRawDataAssetId), assetData.firstIndex, - assetData.lastIndex + assetData.lastIndex, + assetData.playbackMultiplier ); } else if constexpr (std::is_same_v) From 3ca463aa2196eda31fc8f4c05f26fcc979aacbf6 Mon Sep 17 00:00:00 2001 From: XiaoQiDigipen <72735604+XiaoQiDigipen@users.noreply.github.com> Date: Tue, 14 Mar 2023 16:47:08 +0800 Subject: [PATCH 10/12] Added serialisation of extra time multiplier field in animation clip asset Fixed bug when creating animation clip --- ..._RigTest01_SkinningTestAnims.shanimcontainer | Bin 24 -> 28 bytes .../Animation Clips/racoonAnims.shanimcontainer | Bin 231 -> 279 bytes .../src/Application/SBApplication.cpp | 4 ++-- .../Asset Types/SHAnimClipContainerAsset.h | 2 +- .../Assets/Libraries/Loaders/SHBinaryLoader.cpp | 4 ++-- SHADE_Engine/src/Assets/SHAssetManager.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer b/Assets/Animation Clips/MD_RigTest01_SkinningTestAnims.shanimcontainer index 5d6924e2be094865660e35de817f0e71ebd1574b..c14d75f4a06f920f82b7f6a5928a0208999b2462 100644 GIT binary patch delta 9 Qcmb1;nIOT!z|de100)!-pa1{> delta 4 Lcmb1>ZF0rUXf diff --git a/Assets/Animation Clips/racoonAnims.shanimcontainer b/Assets/Animation Clips/racoonAnims.shanimcontainer index c0b335cf09d328278c77c7263f3e4d57d283dea9..2cd476937aba0f8b186c0e97c724b43c46a946c5 100644 GIT binary patch literal 279 zcmaExu$YC1fq{V)h(iMMi&KF#11E@JXs~AilAb9!sa!x>2_ys*V+N8zrFj}a$^nQ$ zLTo@XATv3;w7?C>3IhoOMM0XJ6N`!}<3UD50eM9r37`zfc!&(ppb8*o0!SPv0d_=2 zQGWR}Aa@y55M+9AK~ZL2$toag7gQ8vx>sp#L40sYVo}LHAnzzt24p%|#wS0&;24l| e4l2O`lW@&TIS*uCgNlQE=~kMP1LEF=iU9y*Lp9z2 literal 231 zcmaExu$YC1fq{V)h(iMMi&KF#11Au(0I_FEPAV6WRsv#XAPy?c(*RNqK+Fcj0h!6! zr3G$4Ru~Y26gnps6;;NAv_%1VML-NP3L*;BTmj@v0AjFZ8AbW!(}0|1KnyZ1xS%LA zuVfXFwF`(rrg@d-7Q_daBo>wI1M-dnF~~Hqs84==!7(7`91wHB1YPq|&I8%kfEeU@ Nx6+&(AjNPOhykn?Eb0IN diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 3943b34d..42e112b8 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -180,8 +180,8 @@ namespace Sandbox // Link up SHDebugDraw SHDebugDraw::Init(SHSystemManager::GetSystem()); - auto clip = SHResourceManager::LoadOrGet(77816045); - auto rig = SHResourceManager::LoadOrGet(77816045); + //auto clip = SHResourceManager::LoadOrGet(77816045); + //auto rig = SHResourceManager::LoadOrGet(77816045); } void SBApplication::Update(void) diff --git a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h index 15fc449d..7a719685 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHAnimClipContainerAsset.h @@ -25,8 +25,8 @@ namespace SHADE std::string name; uint32_t firstIndex; uint32_t lastIndex; - AssetID animRawDataAssetId; // Not serialised, only populated during runtime from parent asset float playbackMultiplier = 1.0f; + AssetID animRawDataAssetId; // Not serialised, only populated during runtime from parent asset }; struct SH_API SHAnimClipContainerAsset final : SHAssetData diff --git a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp index 119bd9aa..a8663dde 100644 --- a/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/Loaders/SHBinaryLoader.cpp @@ -79,7 +79,7 @@ namespace SHADE file.write( reinterpret_cast(&clip->firstIndex), - sizeof(uint32_t) * 2 + sizeof(uint32_t) * 3 ); } } @@ -118,7 +118,7 @@ namespace SHADE file.read( reinterpret_cast(&clip->firstIndex), - sizeof(uint32_t) * 2 + sizeof(uint32_t) * 3 ); clip->animRawDataAssetId = data->animRawDataAssetId; diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 8cddaf2c..dc9d9587 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -313,7 +313,7 @@ namespace SHADE .isSubAsset = true, .parent = parent }; - auto& newClip {animContainer->clips.emplace_back()}; + auto& newClip {animContainer->clips.emplace_back(new SHAnimClipAsset())}; newClip->name = name; assetCollection.emplace(id, asset); assetCollection[parent].subAssets.push_back(&assetCollection[id]); From c9b284fe93107307d3ef7f1f0e1618c79858dc9b Mon Sep 17 00:00:00 2001 From: SHAM-DP Date: Mon, 20 Mar 2023 12:23:00 +0800 Subject: [PATCH 11/12] Destroy on scene exit property of AudioClipHandles --- SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp | 17 +++++++++++++++-- SHADE_Engine/src/AudioSystem/SHAudioSystem.h | 3 +++ SHADE_Managed/src/Audio/AudioClip.cxx | 10 ++++++++++ SHADE_Managed/src/Audio/AudioClip.hxx | 6 ++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index 724c31a0..749f6180 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -822,6 +822,16 @@ namespace SHADE instance->setVolume(volume); } + bool AudioClip::GetDestroyOnSceneExit() + { + return destroyOnSceneExit; + } + + void AudioClip::SetDestroyOnSceneExit(bool value) + { + destroyOnSceneExit = value; + } + SHEventHandle SHAudioSystem::onStop(SHEventPtr onStopEvent) { StopAllSounds(); @@ -841,8 +851,11 @@ namespace SHADE auto [begin, end] = audioClipLibrary.GetDenseAccess(); for (auto& it = begin; it != end; ++it) { - it->instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); - it->instance->release(); + if(it->destroyOnSceneExit) + { + it->instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT); + it->instance->release(); + } } return onSceneExitEvent->handle; diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index 7e2fac11..1c285b62 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -37,10 +37,13 @@ namespace SHADE float GetParameterValue(const char* paramName); float GetVolume(); void SetVolume(float volume); + bool GetDestroyOnSceneExit(); + void SetDestroyOnSceneExit(bool value); friend class SHAudioSystem; private: FMOD::Studio::EventInstance* instance = nullptr; EntityID transformRef = MAX_EID; + bool destroyOnSceneExit = true; }; class SH_API SHAudioSystem : public SHSystem diff --git a/SHADE_Managed/src/Audio/AudioClip.cxx b/SHADE_Managed/src/Audio/AudioClip.cxx index 062b543e..c4cad5cf 100644 --- a/SHADE_Managed/src/Audio/AudioClip.cxx +++ b/SHADE_Managed/src/Audio/AudioClip.cxx @@ -44,6 +44,16 @@ namespace SHADE return SHResourceManagerInterface::GetAssetID(Convert::ToNative(audioClipInstHandle)).value_or(INVALID_ASSET_ID); } + bool AudioClipHandler::DestroyOnSceneExit::get() + { + return NativeObject->GetDestroyOnSceneExit(); + } + + void AudioClipHandler::DestroyOnSceneExit::set(bool value) + { + NativeObject->SetDestroyOnSceneExit(value); + } + /*---------------------------------------------------------------------------------*/ /* Constructors/Destructor */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Audio/AudioClip.hxx b/SHADE_Managed/src/Audio/AudioClip.hxx index 317c5bad..a6c969db 100644 --- a/SHADE_Managed/src/Audio/AudioClip.hxx +++ b/SHADE_Managed/src/Audio/AudioClip.hxx @@ -54,6 +54,12 @@ namespace SHADE AssetID get(); } + property bool DestroyOnSceneExit + { + bool get(); + void set(bool value); + } + /*-----------------------------------------------------------------------------*/ /* Constructors/Destructor */ /*-----------------------------------------------------------------------------*/ From 11878d4cc2ba764ff0cf65e40cb7eb8b6024d1d9 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 20 Mar 2023 14:53:36 +0800 Subject: [PATCH 12/12] reworked simulate body --- SHADE_Engine/SHGhostBody.cpp | 51 ++++++++++ SHADE_Engine/SHGhostBody.h | 64 +++++++++++++ .../SHTrajectoryRenderingSubSystem.cpp | 28 ++++-- .../Interface/SHRigidBodyComponent.cpp | 10 ++ .../Physics/Interface/SHRigidBodyComponent.h | 3 + .../src/Physics/System/SHPhysicsSystem.cpp | 96 ++++++++----------- .../src/Physics/System/SHPhysicsSystem.h | 71 ++++++++------ 7 files changed, 230 insertions(+), 93 deletions(-) create mode 100644 SHADE_Engine/SHGhostBody.cpp create mode 100644 SHADE_Engine/SHGhostBody.h diff --git a/SHADE_Engine/SHGhostBody.cpp b/SHADE_Engine/SHGhostBody.cpp new file mode 100644 index 00000000..ef260521 --- /dev/null +++ b/SHADE_Engine/SHGhostBody.cpp @@ -0,0 +1,51 @@ +/**************************************************************************************** + * \file SHGhostBody.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Ghost Body meant for Simulation. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHGhostBody.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHGhostBody::SHGhostBody(const SHRigidBodyComponent& rigidBody) noexcept + : linearVelocity { rigidBody.GetLinearVelocity() } + , angularVelocity { rigidBody.GetAngularVelocity() } + , localCentroid { rigidBody.GetLocalCentroid() } + , accumulatedForce { rigidBody.GetForce() } + , accumulatedTorque{ rigidBody.GetTorque() } + , gravityScale { rigidBody.GetGravityScale() } + , mass { rigidBody.GetMass() } + , drag { rigidBody.GetDrag() } + , angularDrag { rigidBody.GetAngularDrag() } + , position { rigidBody.GetPosition() } + , orientation { SHQuaternion::FromEuler(rigidBody.GetRotation()) } + , useGravity { rigidBody.IsGravityEnabled() } + { + const SHVec3 LOCAL_INERTIA = rigidBody.GetLocalInertia(); + localInvInertia.x = 1.0f / LOCAL_INERTIA.x; + localInvInertia.y = 1.0f / LOCAL_INERTIA.y; + localInvInertia.z = 1.0f / LOCAL_INERTIA.z; + + linearLock.x = rigidBody.GetFreezePositionX() ? 1.0f : 0.0f; + linearLock.y = rigidBody.GetFreezePositionY() ? 1.0f : 0.0f; + linearLock.z = rigidBody.GetFreezePositionZ() ? 1.0f : 0.0f; + + angularLock.x = rigidBody.GetFreezeRotationX() ? 1.0f : 0.0f; + angularLock.y = rigidBody.GetFreezeRotationY() ? 1.0f : 0.0f; + angularLock.z = rigidBody.GetFreezeRotationZ() ? 1.0f : 0.0f; + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/SHGhostBody.h b/SHADE_Engine/SHGhostBody.h new file mode 100644 index 00000000..ebc2b0db --- /dev/null +++ b/SHADE_Engine/SHGhostBody.h @@ -0,0 +1,64 @@ +/**************************************************************************************** + * \file SHGhostBody.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the Ghost Body meant for Simulation. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Headers +#include "Physics/Interface/SHRigidBodyComponent.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + /** + * @brief + * Encapsulates a rigid body that will be simulated in the world, but doesn't actually + * exist in the world. + */ + struct SHGhostBody + { + public: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + SHVec3 linearVelocity = SHVec3::Zero; + SHVec3 angularVelocity = SHVec3::Zero; + + SHVec3 localInvInertia = SHVec3::One; + SHVec3 localCentroid = SHVec3::Zero; + SHVec3 accumulatedForce = SHVec3::Zero; + SHVec3 accumulatedTorque = SHVec3::Zero; + + SHVec3 linearLock = SHVec3::One; + SHVec3 angularLock = SHVec3::One; + + float gravityScale = 1.0f; + float mass = 1.0f; + float drag = 0.01f; + float angularDrag = 0.01f; + + SHVec3 position = SHVec3::Zero; + SHQuaternion orientation = SHQuaternion::Identity; + bool useGravity = true; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHGhostBody () noexcept = default; + SHGhostBody (const SHRigidBodyComponent& rigidBody) noexcept; + + }; + + +} // namespace SHADE diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp index f923add4..f2689209 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.cpp @@ -1,5 +1,7 @@ #include "SHpch.h" #include "SHTrajectoryRenderingSubSystem.h" + +#include "../../../../SHGhostBody.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h" #include "Graphics/Devices/SHVkLogicalDevice.h" @@ -85,17 +87,25 @@ namespace SHADE { std::vector positions{}; std::vector quats{}; - physicsSystem->SimulateBody - (positions, quats, - SHPhysicsSystem::SimulateBodyInfo - { - .bodyEID = entityToSimulate, - .force = comp.GetSimulationForce(), - .continuousForce = false, + + SHGhostBody defaultGhostBody{}; + + SHPhysicsSystem::SimulateBodyInfo simulateInfo + { + .bodyEID = entityToSimulate, + .force = comp.GetSimulationForce(), + .continuousForce = false, .timeStep = comp.GetSimulationTimestep(), .maxSteps = static_cast(comp.GetSimulationMaxSteps()), - } - ); + }; + + SHPhysicsSystem::SimulateBodyOutput output + { + .positions = &positions + , .orientations = &quats + }; + + physicsSystem->SimulateBody(defaultGhostBody, simulateInfo, output); comp.ResetSimulationInfo(); diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index b26f89d9..1017098f 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -150,6 +150,16 @@ namespace SHADE return rigidBody ? SHQuaternion{ rigidBody->getTransform().getOrientation() }.ToEuler() : SHVec3::Zero; } + SHVec3 SHRigidBodyComponent::GetLocalInertia() const noexcept + { + return rigidBody ? SHVec3{ rigidBody->getLocalInertiaTensor() } : SHVec3::Zero; + } + + SHVec3 SHRigidBodyComponent::GetLocalCentroid() const noexcept + { + return rigidBody ? SHVec3{ rigidBody->getLocalCenterOfMass() } : SHVec3::Zero; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index a1cbe786..8f5fe3d4 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -103,6 +103,9 @@ namespace SHADE [[nodiscard]] SHVec3 GetPosition () const noexcept; [[nodiscard]] SHVec3 GetRotation () const noexcept; + [[nodiscard]] SHVec3 GetLocalInertia () const noexcept; + [[nodiscard]] SHVec3 GetLocalCentroid () const noexcept; + /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index f19002e6..75ed50f4 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -14,6 +14,7 @@ #include "SHPhysicsSystem.h" // Project Headers +#include "../../../SHGhostBody.h" #include "Assets/SHAssetMacros.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHEntityManager.h" @@ -236,44 +237,22 @@ namespace SHADE return IS_COLLIDING; } - void SHPhysicsSystem::SimulateBody(std::vector& positions, std::vector& orientations, const SimulateBodyInfo& simInfo) + void SHPhysicsSystem::SimulateBody(SHGhostBody& ghostBody, SimulateBodyInfo& simInfo, SimulateBodyOutput& output) { // Check for a valid rigidbody const auto* rigidBody = SHComponentManager::GetComponent_s(simInfo.bodyEID); if (!rigidBody) { - SHLOG_WARNING("Entity {} does not have a rigid body to simulate!", simInfo.bodyEID) - return; - } - - // Ignore non-dynamic bodies - if (rigidBody->type != SHRigidBodyComponent::Type::DYNAMIC) - { - SHLOG_WARNING("Entity {} is not a dynamic body. We cannot simulate non-dynamic bodies!", simInfo.bodyEID) - return; + SHLOG_WARNING("Entity {} does not have a rigid body to simulate! This body will collide with everything!", simInfo.bodyEID) } // Prepare simulation info (I'm basically declaring an entire body here) - SHVec3 bodyPosition = rigidBody->GetPosition(); - SHQuaternion bodyOrientation = SHQuaternion::FromEuler(rigidBody->GetRotation()); - SHVec3 linearVelocity = rigidBody->GetLinearVelocity(); - SHVec3 angularVelocity = rigidBody->GetAngularVelocity(); - float invMass = 1.0f / rigidBody->GetMass(); - SHVec3 localInvInertia = rigidBody->rigidBody->getLocalInertiaTensor(); - SHVec3 worldInvInertia = SHVec3::One; - SHVec3 localCentroid = rigidBody->rigidBody->getLocalCenterOfMass(); - SHVec3 worldCentroid = SHVec3::One; - SHVec3 appliedForce = simInfo.force; - SHVec3 appliedTorque = simInfo.torque; - SHVec3 accumulatedForce = SHVec3::Zero; - SHVec3 accumulatedTorque = SHVec3::Zero; + float invMass = 1.0f / ghostBody.mass; + SHVec3 worldInvInertia = SHVec3::One; + SHVec3 worldCentroid = SHVec3::One; - const SHVec3& LINEAR_LOCK = rigidBody->rigidBody->getLinearLockAxisFactor(); - const SHVec3& ANGULAR_LOCK = rigidBody->rigidBody->getAngularLockAxisFactor(); - - // Invert the inertia - for (size_t i = 0; i < SHVec3::SIZE; ++i) - localInvInertia[i] = 1.0f / localInvInertia[i]; + // Asserts. Don't be an idiot. + SHASSERT(invMass > 0, "GhostBody's mass in invalid") // Build raycast layer from colliders. If none exist....then this never stops simulating technically. // I'm too lazy to handle that case, so I'll just throw an error. @@ -300,24 +279,24 @@ namespace SHADE int iterationCounter = simInfo.maxSteps; do { - raycastInfo.distance = linearVelocity.Length() * simInfo.timeStep; // Do not take the entire velocity's length as that is for an entire second. - raycastInfo.ray.position = bodyPosition; - raycastInfo.ray.direction = SHVec3::Normalise(linearVelocity); + raycastInfo.distance = ghostBody.linearVelocity.Length() * simInfo.timeStep; // Do not take the entire velocity's length as that is for an entire second. + raycastInfo.ray.position = ghostBody.position; + raycastInfo.ray.direction = SHVec3::Normalise(ghostBody.linearVelocity); terminate = !Raycast(raycastInfo).empty() || iterationCounter == 0; if (terminate) return; // Compute world space data - const SHMatrix R = SHMatrix::Rotate(bodyOrientation); + const SHMatrix R = SHMatrix::Rotate(ghostBody.orientation); const SHMatrix RT = SHMatrix::Transpose(R); SHMatrix localInertiaTensor = SHMatrix::Identity; // Set the diagonals - localInertiaTensor.m[0][0] = localInvInertia.x; - localInertiaTensor.m[1][1] = localInvInertia.y; - localInertiaTensor.m[2][2] = localInvInertia.z; + localInertiaTensor.m[0][0] = ghostBody.localInvInertia.x; + localInertiaTensor.m[1][1] = ghostBody.localInvInertia.y; + localInertiaTensor.m[2][2] = ghostBody.localInvInertia.z; localInertiaTensor *= RT; const SHVec3 DIAGONALS { localInertiaTensor.m[0][0], localInertiaTensor.m[1][1], localInertiaTensor.m[2][2] }; @@ -325,42 +304,47 @@ namespace SHADE worldInvInertia = R * DIAGONALS; // Compute world centroid - worldCentroid = (R * localCentroid) + bodyPosition; + worldCentroid = (R * ghostBody.localCentroid) + ghostBody.position; // Apply forces - accumulatedForce += appliedForce; - angularVelocity += worldInvInertia * SHVec3::Cross(bodyPosition + simInfo.forceOffset, simInfo.force); - accumulatedTorque += appliedTorque; + ghostBody.accumulatedForce += simInfo.force; + ghostBody.angularVelocity += worldInvInertia * SHVec3::Cross(ghostBody.position + simInfo.forceOffset, simInfo.force); + ghostBody.accumulatedTorque += simInfo.torque; // Integrate Velocities // Integrate forces and gravity into linear velocity - const SHVec3 LINEAR_ACCELERATION = accumulatedForce * invMass; - const SHVec3 GRAVITATIONAL_ACCELERATION = simInfo.simulateGravity ? worldState.settings.gravity * rigidBody->GetGravityScale() : SHVec3::Zero; + const SHVec3 LINEAR_ACCELERATION = ghostBody.accumulatedForce * invMass; + const SHVec3 GRAVITATIONAL_ACCELERATION = ghostBody.gravityScale ? worldState.settings.gravity * ghostBody.gravityScale : SHVec3::Zero; - linearVelocity += (LINEAR_ACCELERATION + GRAVITATIONAL_ACCELERATION) * simInfo.timeStep * LINEAR_LOCK; - angularVelocity += worldInvInertia * (accumulatedTorque * simInfo.timeStep); + ghostBody.linearVelocity += (LINEAR_ACCELERATION + GRAVITATIONAL_ACCELERATION) * simInfo.timeStep * ghostBody.linearLock; + ghostBody.angularVelocity += worldInvInertia * (ghostBody.accumulatedTorque * simInfo.timeStep); // Apply drag (exponentially applied) - linearVelocity *= 1.0f / (1.0f + simInfo.timeStep * rigidBody->drag); - angularVelocity *= 1.0f / (1.0f + simInfo.timeStep * rigidBody->angularDrag); + ghostBody.linearVelocity *= 1.0f / (1.0f + simInfo.timeStep * ghostBody.drag); + ghostBody.angularVelocity *= 1.0f / (1.0f + simInfo.timeStep * ghostBody.angularDrag); // Integrate Positions & Orientations - const SHQuaternion QV = SHQuaternion{ angularVelocity.x * simInfo.timeStep, angularVelocity.y * simInfo.timeStep, angularVelocity.z * simInfo.timeStep, 0.0f } * 0.5f; + const SHQuaternion QV = SHQuaternion{ ghostBody.angularVelocity.x * simInfo.timeStep, ghostBody.angularVelocity.y * simInfo.timeStep, ghostBody.angularVelocity.z * simInfo.timeStep, 0.0f } * 0.5f; - bodyPosition += linearVelocity * simInfo.timeStep; - bodyOrientation += bodyOrientation * QV * SHQuaternion::FromEuler(ANGULAR_LOCK); - bodyOrientation = SHQuaternion::Normalise(bodyOrientation); + ghostBody.position += ghostBody.linearVelocity * simInfo.timeStep; + ghostBody.orientation += ghostBody.orientation * QV * SHQuaternion::FromEuler(ghostBody.angularLock); + ghostBody.orientation = SHQuaternion::Normalise(ghostBody.orientation); + + // Clear forces + ghostBody.accumulatedForce = SHVec3::Zero; + ghostBody.accumulatedTorque = SHVec3::Zero; - // Clear forces after the first frame if (!simInfo.continuousForce) { - accumulatedForce = SHVec3::Zero; - accumulatedTorque = SHVec3::Zero; - appliedForce = SHVec3::Zero; - appliedTorque = SHVec3::Zero; + simInfo.force = SHVec3::Zero; + simInfo.torque = SHVec3::Zero; } - positions.emplace_back(bodyPosition); + if (output.positions) + output.positions->emplace_back(ghostBody.position); + + if (output.orientations) + output.orientations->emplace_back(ghostBody.orientation); --iterationCounter; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 0a1e2057..c81bf3a9 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -28,6 +28,7 @@ namespace SHADE { + struct SHGhostBody; /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -51,41 +52,54 @@ namespace SHADE /** * @brief * Used to simulate the motion of a rigid body, ignoring collision detection and response. - * @param bodyEID - * The EntityID of the Rigid Body to simulate. - * @param force - * The force applied onto the Rigid Body. - * @param forceOffset - * The position to apply the force onto the body relative to it's local Center of Mass. - * @param torque - * The torque to apply onto the Rigid Body. - * @param continuousForce - * If the force should be applied every step throughout the simulation. Defaults to false.
- * True : The force indicated is added to the body every step, therefore it has constant acceleration. - * False: The force is applied only in the first step, therefore it has constant speed. - * @param timeStep - * The timestep for each step of the simulation. Defaults to 0.016s (The default Fixed DT) - * @param maxSteps - * The number of steps to run the simulation for. Defaults to -1. - * < 0 : Runs until the object may hit something. Hit detection is done through raycasting. - * = 0 : Runs only the current step and checks if it may hit something. - * > 0 : Runs for the given number of steps or until it may hit something. */ struct SimulateBodyInfo { + public: + + // The EntityID of the Actual Rigid Body to simulate. If none is passed it, + // the Ghost Body will attempt to collide with everything. EntityID bodyEID = MAX_EID; + // The force applied onto the Ghost Body. SHVec3 force = SHVec3::Zero; + + // The position where the force is applied offset from the local centroid. SHVec3 forceOffset = SHVec3::Zero; + + // The torque to apply onto the Ghost Body. SHVec3 torque = SHVec3::Zero; - // Whether or not to clear the force after the first iteration + /* + If the force should be applied every step throughout the simulation. Defaults to false. + True : The force indicated is added to the body every step, therefore it has constant acceleration. + False: The force is applied only in the first step, therefore it has constant speed. + */ bool continuousForce = false; - bool simulateGravity = true; + + // The timestep for each step of the simulation. Defaults to 0.016s (The default Fixed DT) float timeStep = static_cast(SHPhysicsConstants::DEFAULT_FIXED_DT); + + /* + The number of steps to run the simulation for. Defaults to -1. + < 0 : Runs until the object may hit something. Hit detection is done through raycasting. + = 0 : Runs only the current step and checks if it may hit something. + > 0 : Runs for the given number of steps or until it may hit something. + */ int maxSteps = -1; }; + /** + * @brief + * Contains the output for the simulate body method. + */ + struct SimulateBodyOutput + { + public: + std::vector* positions = nullptr; + std::vector* orientations = nullptr; + }; + /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ @@ -159,15 +173,16 @@ namespace SHADE /** * @brief - * Simulates the motion of a body until it collides with something. - * @param positions - * The output vector for the position of the body in each timestep. - * @param orientations - * The output vector for the orientations of the body in each timestep. + * Simulates a non-existent body in the physics world. + * The simulation will run based on the information passed in. + * @param ghostBody + * The definition of the body passed in. * @param simInfo - * The information for simulating the body. + * The information for how the simulation will run. + * @param output + * The transform results for position and orientations. */ - void SimulateBody(std::vector& positions, std::vector& orientations, const SimulateBodyInfo& simInfo); + void SimulateBody(SHGhostBody& ghostBody, SimulateBodyInfo& simInfo, SimulateBodyOutput& output); /*---------------------------------------------------------------------------------*/ /* System Routines */