From 37aad4940654b04f2ade8f24afb66d0c42c01ed4 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 15 Nov 2022 21:09:24 +0800 Subject: [PATCH 1/3] Added requested rigidbody component view with debug information Changed DragVec controls to not push commands if ImGuiSliderFlags_ReadOnly is enabled --- .../Inspector/SHEditorComponentView.hpp | 93 ++++++++++++++++--- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 6 +- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 146e36c3..f8cec296 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -220,6 +220,86 @@ namespace SHADE } + template<> + static void DrawComponent(SHRigidBodyComponent* component) + { + if(!component) + return; + ImGui::PushID(SHFamilyID::GetID()); + + const auto componentType = rttr::type::get(); + SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); + ImGui::SameLine(); + if (ImGui::CollapsingHeader(componentType.get_name().data())) + { + DrawContextMenu(component); + + SHRigidBodyComponent::Type rbType = component->GetType(); + + auto enumAlign = rttr::type::get().get_enumeration(); + auto names = enumAlign.get_names(); + std::vector list; + for (auto const& name : names) + list.push_back(name.data()); + SHEditorWidgets::ComboBox("Type", list, [component] {return static_cast(component->GetType()); }, [component, enumAlign](int const& idx) + { + auto values = enumAlign.get_values(); + auto it = std::next(values.begin(), idx); + component->SetType((*it).convert()); + }, "RigidBody Type"); + + + if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields + { + SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); + SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag"); + SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag"); + SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity"); + } + if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields + { + SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "Interpolate"); + + SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + + SHEditorWidgets::TextLabel("Freeze Position"); + SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Freeze Position - X"); ImGui::SameLine(); + SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Freeze Position - Y"); ImGui::SameLine(); + SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Freeze Position - Z"); + + SHEditorWidgets::TextLabel("Freeze Rotation"); + SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Freeze Rotation - X"); ImGui::SameLine(); + SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Freeze Rotation - Y"); ImGui::SameLine(); + SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Freeze Rotation - Z"); + + SHEditorWidgets::EndPanel(); + } + + //Debug Info (Read-Only) + if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields + { + SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields + { + SHEditorWidgets::DragVec3("Velocity", { "X", "Y", "Z" }, [component] {return component->GetLinearVelocity(); }, [](SHVec3 const& value) {}, false, "Linear Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::DragVec3("Angular Velocity", { "X", "Y", "Z" }, [component] {return component->GetAngularVelocity(); }, [](SHVec3 const& value) {}, false, "Angular Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + } + if (rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields + { + SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + } + } + + } + else + { + DrawContextMenu(component); + } + ImGui::PopID(); + } + template<> static void DrawComponent(SHColliderComponent* component) { @@ -278,21 +358,12 @@ namespace SHADE [&collider] { auto offset = collider->GetRotationOffset(); - offset.x = SHMath::RadiansToDegrees(offset.x); - offset.y = SHMath::RadiansToDegrees(offset.y); - offset.z = SHMath::RadiansToDegrees(offset.z); return offset; }, [&collider](SHVec3 const& vec) { - const SHVec3 vecInRad - { - SHMath::DegreesToRadians(vec.x) - , SHMath::DegreesToRadians(vec.y) - , SHMath::DegreesToRadians(vec.z) - }; - collider->SetRotationOffset(vecInRad); - }); + collider->SetRotationOffset(vec); + }, true); SHEditorWidgets::EndPanel(); } diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 0855d68d..11b35cfc 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -219,7 +219,7 @@ namespace SHADE } bool const changed = DragN(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags); static bool startRecording = false; - if (changed) + if (!(flags & ImGuiSliderFlags_ReadOnly) && changed) { if(isAnAngleInRad) { @@ -255,7 +255,7 @@ namespace SHADE bool isHovered = false; bool const changed = DragN(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags, &isHovered); static bool startRecording = false; - if (changed) + if (!(flags & ImGuiSliderFlags_ReadOnly) && changed) { SHVec3 old = get(); if(isAnAngleInRad) @@ -293,7 +293,7 @@ namespace SHADE } bool const changed = DragN(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags); static bool startRecording = false; - if (changed) + if (!(flags & ImGuiSliderFlags_ReadOnly) && changed) { if(isAnAngleInRad) { From dc9291bc017f442081194490425edefdd0a4c233 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Wed, 16 Nov 2022 15:00:56 +0800 Subject: [PATCH 2/3] Added Audio class for playing audio from C# --- SHADE_Engine/src/AudioSystem/SHAudioSystem.h | 2 +- SHADE_Managed/premake5.lua | 7 +- SHADE_Managed/src/Audio/Audio.cxx | 101 ++++++++++++++++++ SHADE_Managed/src/Audio/Audio.hxx | 103 +++++++++++++++++++ 4 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 SHADE_Managed/src/Audio/Audio.cxx create mode 100644 SHADE_Managed/src/Audio/Audio.hxx diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index f19fcc3b..7196b40d 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -7,7 +7,7 @@ #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/SHECSMacros.h" -#include "Math/SHMath.h" +#include "Math/Vector/SHVec3.h" #include #include #include "SH_API.h" diff --git a/SHADE_Managed/premake5.lua b/SHADE_Managed/premake5.lua index 64f6e23e..2384cae8 100644 --- a/SHADE_Managed/premake5.lua +++ b/SHADE_Managed/premake5.lua @@ -39,13 +39,15 @@ project "SHADE_Managed" "%{IncludeDir.dotnet}\\include", "%{IncludeDir.reactphysics3d}\\include", "%{IncludeDir.VULKAN}\\include", + "%{IncludeDir.fmod}\\include", "%{wks.location}/SHADE_Engine/src" } libdirs { "%{IncludeDir.RTTR}/lib", - "%{IncludeDir.SDL}/lib" + "%{IncludeDir.SDL}/lib", + "%{IncludeDir.fmod}/lib" } links @@ -93,16 +95,19 @@ project "SHADE_Managed" symbols "On" defines {"_DEBUG"} links{"librttr_core_d.lib"} + links{"fmodstudioL_vc.lib", "fmodL_vc.lib"} filter "configurations:Release" optimize "On" defines{"_RELEASE"} links{"librttr_core.lib"} + links{"fmodstudio_vc.lib", "fmod_vc.lib"} filter "configurations:Publish" optimize "On" defines{"_RELEASE"} links{"librttr_core.lib"} + links{"fmodstudio_vc.lib", "fmod_vc.lib"} require "vstudio" diff --git a/SHADE_Managed/src/Audio/Audio.cxx b/SHADE_Managed/src/Audio/Audio.cxx new file mode 100644 index 00000000..52e29529 --- /dev/null +++ b/SHADE_Managed/src/Audio/Audio.cxx @@ -0,0 +1,101 @@ +/************************************************************************************//*! +\file Audio.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 16, 2022 +\brief Contains the function definitions of the managed Audio static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Header +#include "SHpch.h" +// Primary Header +#include "Audio.hxx" +// External Dependencies +#include "AudioSystem/SHAudioSystem.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + float Audio::BGMVolume::get() + { + auto audioSys = SHSystemManager::GetSystem(); + return audioSys->GetBgmVolume(); + } + void Audio::BGMVolume::set(float value) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->SetBgmVolume(System::Math::Clamp(value, 0.0f, 1.0f)); + } + float Audio::SFXVolume::get() + { + auto audioSys = SHSystemManager::GetSystem(); + return audioSys->GetSfxVolume(); + } + void Audio::SFXVolume::set(float value) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->SetSfxVolume(System::Math::Clamp(value, 0.0f, 1.0f)); + } + float Audio::MasterVolume::get() + { + auto audioSys = SHSystemManager::GetSystem(); + return audioSys->GetMasterVolume(); + } + void Audio::MasterVolume::set(float value) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->SetMasterVolume(System::Math::Clamp(value, 0.0f, 1.0f)); + } + bool Audio::IsPaused::get() + { + auto audioSys = SHSystemManager::GetSystem(); + return audioSys->GetPaused(); + } + void Audio::IsPaused::set(bool value) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->SetPaused(value); + } + + /*-----------------------------------------------------------------------------*/ + /* Playback Control Functions */ + /*-----------------------------------------------------------------------------*/ + void Audio::PlaySFXOnce2D(System::String^ path) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->PlayEventOnce(Convert::ToNative(path).data()); + } + + void Audio::PlaySFXOnce3D(System::String^ path, GameObject gameObject) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->PlayEventOnce(Convert::ToNative(path).data(), true, gameObject.GetEntity(), true); + } + + void Audio::PlayBGMOnce2D(System::String^ path) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->PlayEventOnce(Convert::ToNative(path).data(), false); + } + + void Audio::PlayBGMOnce3D(System::String^ path, GameObject gameObject) + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->PlayEventOnce(Convert::ToNative(path).data(), false, gameObject.GetEntity(), true); + } + + void Audio::StopAllSounds() + { + auto audioSys = SHSystemManager::GetSystem(); + audioSys->StopAllSounds(); + } +} diff --git a/SHADE_Managed/src/Audio/Audio.hxx b/SHADE_Managed/src/Audio/Audio.hxx new file mode 100644 index 00000000..d568dc90 --- /dev/null +++ b/SHADE_Managed/src/Audio/Audio.hxx @@ -0,0 +1,103 @@ +/************************************************************************************//*! +\file Audio.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 16, 2022 +\brief Contains the definitions of the managed Audio static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once +#include "Engine/GameObject.hxx" + +namespace SHADE +{ + /// + /// Static class that contains the functions for interfacing with the Audio system. + /// + public ref class Audio abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Volume of background music playback. Clamped between 0.0 and 1.0. + /// + static property float BGMVolume + { + float get(); + void set(float value); + } + /// + /// Volume of sound effects playback. Clamped between 0.0 and 1.0. + /// + static property float SFXVolume + { + float get(); + void set(float value); + } + /// + /// Overall volume for all audio playback. Clamped between 0.0 and 1.0. + /// + static property float MasterVolume + { + float get(); + void set(float value); + } + /// + /// Whether or not all audio playback is paused. + /// + static property bool IsPaused + { + bool get(); + void set(bool value); + } + + /*-----------------------------------------------------------------------------*/ + /* Playback Control Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Plays a sound effect without looping without spatial attenuation. + /// + /// + /// Path to the audio file relative to the working directory. + /// + static void PlaySFXOnce2D(System::String^ path); + /// + /// Plays a sound effect without looping with spatial attenuation. + /// + /// + /// Path to the audio file relative to the working directory. + /// + /// + /// Object whose position is used to play the sound effect. + /// + static void PlaySFXOnce3D(System::String^ path, GameObject gameObject); + /// + /// Plays background music without looping without spatial attenuation. + /// + /// + /// Path to the audio file relative to the working directory. + /// + static void PlayBGMOnce2D(System::String^ path); + /// + /// Plays background music without looping with spatial attenuation. + /// + /// + /// Path to the audio file relative to the working directory. + /// + /// + /// Object whose position is used to play the background music. + /// + static void PlayBGMOnce3D(System::String^ path, GameObject gameObject); + /// + /// Stops playback of all sound effects and music. + /// + static void StopAllSounds(); + }; +} From ba39c02f9f9d745dae9b22997308d3616ad0ec20 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Wed, 16 Nov 2022 15:28:42 +0800 Subject: [PATCH 3/3] Changed formatting slightly for RigidBody component view --- .../EditorWindow/Inspector/SHEditorComponentView.hpp | 9 +++++---- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index f8cec296..79891b82 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -251,13 +251,14 @@ namespace SHADE if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields { - SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); - SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag"); - SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag"); SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity"); + SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); } if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields { + SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag"); + SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag"); + SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "Interpolate"); SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); @@ -283,7 +284,7 @@ namespace SHADE if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields { SHEditorWidgets::DragVec3("Velocity", { "X", "Y", "Z" }, [component] {return component->GetLinearVelocity(); }, [](SHVec3 const& value) {}, false, "Linear Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); - SHEditorWidgets::DragVec3("Angular Velocity", { "X", "Y", "Z" }, [component] {return component->GetAngularVelocity(); }, [](SHVec3 const& value) {}, false, "Angular Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); + SHEditorWidgets::DragVec3("Angular\nVelocity", { "X", "Y", "Z" }, [component] {return component->GetAngularVelocity(); }, [](SHVec3 const& value) {}, false, "Angular Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); } if (rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields { diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 11b35cfc..bfde7525 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -166,14 +166,14 @@ namespace SHADE const ImGuiWindow* const window = ImGui::GetCurrentWindow(); if (window->SkipItems) return false; - + static constexpr float defaultLabelColWidth = 80.0f; const ImGuiContext& g = *GImGui; bool valueChanged = false; ImGui::BeginGroup(); ImGui::PushID(label.c_str()); PushMultiItemsWidthsAndLabels(componentLabels, 0.0f); ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize); - ImGui::SetColumnWidth(-1, 80.0f); + ImGui::SetColumnWidth(-1, defaultLabelColWidth); ImGui::Text(label.c_str()); if (isHovered) *isHovered |= ImGui::IsItemHovered();