Merge branch 'main' into SP3-8-serialization

This commit is contained in:
Sri Sham Haran 2022-10-14 16:05:53 +08:00
commit a7ed10c0b4
69 changed files with 2726 additions and 1306 deletions

View File

@ -56,46 +56,58 @@ namespace Sandbox
)
{
// Set working directory
SHADE::SHFileUtilities::SetWorkDirToExecDir();
SHFileUtilities::SetWorkDirToExecDir();
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
// Create Systems
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHPhysicsSystem>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHSystemManager::CreateSystem<SHScriptEngine>();
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHTransformSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHAudioSystem>();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
SHSystemManager::CreateSystem<SHEditor>();
SHSystemManager::GetSystem<SHEditor>()->SetSDLWindow(sdlWindow);
#endif
// Create Routines
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::UpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameSetUpRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::UpdateRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPreUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsFixedUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformUpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
#ifdef SHEDITOR
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
#endif
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHColliderComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::RenderRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::EndRoutine>();
SHComponentManager::CreateComponentSparseSet<SHRigidBodyComponent>();
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
//TODO: REMOVE AFTER PRESENTATION
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
//SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
//TODO: REMOVE AFTER PRESENTATION
@ -103,19 +115,12 @@ namespace Sandbox
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
// Set up graphics system and windows
graphicsSystem->SetWindow(&window);
SHADE::SHSystemManager::Init();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
SHADE::SHEditor::Initialise(sdlWindow);
#else
#endif
SHSystemManager::Init();
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
@ -124,26 +129,15 @@ namespace Sandbox
void SBApplication::Update(void)
{
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>();
//TODO: Change true to window is open
while (!window.WindowShouldClose())
{
SHFrameRateController::UpdateFRC();
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
SHSceneManager::UpdateSceneManager();
SHSceneManager::SceneUpdate(1/60.0f);
//#ifdef SHEDITOR
//#endif
graphicsSystem->BeginRender();
#ifdef SHEDITOR
SHADE::SHEditor::Update(0.16f);
#endif
graphicsSystem->Run(1.0f);
graphicsSystem->EndRender();
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
SHSceneManager::SceneUpdate(0.016f);
SHSystemManager::RunRoutines(false, 0.016f);
}
// Finish all graphics jobs first
@ -154,13 +148,12 @@ namespace Sandbox
void SBApplication::Exit(void)
{
#ifdef SHEDITOR
SHADE::SHEditor::Exit();
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
#endif
#endif
SHSceneManager::Exit();
SHADE::SHSystemManager::Exit();
SHSystemManager::Exit();
}
}

View File

@ -99,13 +99,15 @@ namespace Sandbox
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
//Set initial positions
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f)});
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) });
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber());
transform.SetWorldScale(TEST_OBJ_SCALE);
auto* box = collider.AddBoundingBox();
box->SetHalfExtents(transform.GetWorldScale() * 0.5f);
if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN)
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
else
collider.AddBoundingSphere(0.5f, SHVec3::Zero);
stressTestObjects.emplace_back(entity);
}
@ -133,12 +135,12 @@ namespace Sandbox
floorRenderable.SetMaterial(customMat);
floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
floorTransform.SetWorldScale({7.5f, 0.5f, 7.5});
floorTransform.SetWorldPosition({0.0f, -3.0f, -5.0f});
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox();
auto* floorBox = floorCollider.AddBoundingBox();
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
// Create blank entity with a script

View File

@ -6,11 +6,11 @@
//#==============================================================#
//|| SHADE Includes ||
//#==============================================================#
#include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp"
#include "Editor/SHEditorWidgets.hpp"
#include "SHHierarchyPanel.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Editor/SHEditor.hpp"
#include "Scene/SHSceneManager.h"
#include "Editor/DragDrop/SHDragDrop.hpp"
#include "Tools/SHException.h"
@ -62,7 +62,8 @@ namespace SHADE
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
SHEditor::selectedEntities.clear();
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->selectedEntities.clear();
}
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
ImGui::End();
@ -102,7 +103,9 @@ namespace SHADE
//Get node data (Children, eid, selected)
auto& children = currentNode->GetChildren();
EntityID eid = currentNode->GetEntityID();
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end());
auto editor = SHSystemManager::GetSystem<SHEditor>();
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
@ -140,8 +143,8 @@ namespace SHADE
{
if(!isSelected)
{
SHEditor::selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid);
editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid);
}
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
{
@ -163,19 +166,19 @@ namespace SHADE
if (!isSelected)
{
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
SHEditor::selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid);
editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid);
}//if not selected
else
{
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
{
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin();
auto it = std::ranges::remove(editor->selectedEntities, eid).begin();
}//if mod ctrl is not pressed
else
{
SHEditor::selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid);
editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid);
}
}//if selected
}//if left mouse button released

View File

@ -12,19 +12,20 @@
#include "Editor/IconsMaterialDesign.h"
#include "ECS_Base/Components/SHComponent.h"
#include "Editor/SHEditorWidgets.hpp"
#include "Physics/Components/SHColliderComponent.h"
#include "Reflection/SHReflectionMetadata.h"
namespace SHADE
{
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
static void DrawContextMenu(T* component)
{
if(!component)
if (!component)
return;
rttr::string_view componentName = rttr::type::get<T>().get_name();
if (ImGui::BeginPopupContextItem(componentName.data()))
{
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
{
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
@ -56,26 +57,26 @@ namespace SHADE
{
auto const& type = property.get_type();
if(type.is_enumeration())
if (type.is_enumeration())
{
auto enumAlign = type.get_enumeration();
auto names = enumAlign.get_names();
std::vector<const char*> list;
for(auto const& name : names)
for (auto const& name : names)
list.push_back(name.data());
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx)
{
auto enumAlign = property.get_enumeration();
auto values = enumAlign.get_values();
auto it = std::next(values.begin(), idx);
property.set_value(component, *it);
});
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& idx)
{
auto enumAlign = property.get_enumeration();
auto values = enumAlign.get_values();
auto it = std::next(values.begin(), idx);
property.set_value(component, *it);
});
}
else if(type.is_arithmetic())
else if (type.is_arithmetic())
{
if (type == rttr::type::get<bool>())
{
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);});
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); });
}
//else if (type == rttr::type::get<char>())
//{
@ -85,39 +86,39 @@ namespace SHADE
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin && metaMax)
if (metaMin && metaMax)
{
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
}
else
{
SHEditorWidgets::DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
}
}
else if (type == rttr::type::get<uint8_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu");
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu");
}
else
{
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
}
}
else if (type == rttr::type::get<uint16_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu");
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu");
}
else
{
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
}
}
else if (type == rttr::type::get<uint32_t>())
@ -126,50 +127,50 @@ namespace SHADE
auto metaMax = property.get_metadata(META::max);
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu");
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu");
}
else
{
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu");
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
}
}
else if (type == rttr::type::get<uint64_t>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu");
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu");
}
else
{
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
}
}
else if (type == rttr::type::get<float>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
}
else
{
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
}
}
else if (type == rttr::type::get<double>())
{
auto metaMin = property.get_metadata(META::min);
auto metaMax = property.get_metadata(META::max);
if(metaMin.is_valid() && metaMax.is_valid())
if (metaMin.is_valid() && metaMax.is_valid())
{
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);});
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); });
}
else
{
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f);
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f);
}
}
}
@ -183,9 +184,74 @@ namespace SHADE
}
else if (type == rttr::type::get<SHVec2>())
{
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
}
}
}
else DrawContextMenu(component);
}
template<>
static void DrawComponent(SHColliderComponent* component)
{
if (!component)
return;
const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data()))
{
DrawContextMenu(component);
auto& colliders = component->GetColliders();
int const size = static_cast<int>(colliders.size());
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
for (int i{}; i < size; ++i)
{
SHCollider& collider = component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos();
if (collider.GetType() == SHCollider::Type::BOX)
{
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
}
else if (collider.GetType() == SHCollider::Type::SPHERE)
{
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);});
}
else if (collider.GetType() == SHCollider::Type::CAPSULE)
{
}
{
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); });
SHEditorWidgets::EndPanel();
}
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
{
component->RemoveCollider(i);
}
SHEditorWidgets::EndPanel();
}
ImGui::EndChild();
if (ImGui::BeginMenu("Add Collider"))
{
if(ImGui::Selectable("Box Collider"))
{
component->AddBoundingBox();
}
if(ImGui::Selectable("Sphere Collider"))
{
component->AddBoundingSphere();
}
ImGui::EndMenu();
}
}
else DrawContextMenu(component);

View File

@ -1,5 +1,6 @@
#include "SHpch.h"
#include "Editor/SHEditor.hpp"
#include "SHEditorInspector.h"
#include "ECS_Base/SHECSMacros.h"
@ -7,7 +8,6 @@
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp"
#include "Editor/SHEditorWidgets.hpp"
#include "SHEditorComponentView.hpp"
@ -24,12 +24,15 @@
namespace SHADE
{
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
void DrawAddComponentButton(EntityID const& eid)
bool DrawAddComponentButton(EntityID const& eid)
{
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()))
bool selected = false;
if(!SHComponentManager::HasComponent<ComponentType>(eid))
{
SHComponentManager::AddComponent<ComponentType>(eid);
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
SHComponentManager::AddComponent<ComponentType>(eid);
}
return selected;
}
SHEditorInspector::SHEditorInspector()
@ -47,15 +50,10 @@ namespace SHADE
SHEditorWindow::Update();
if (Begin())
{
if (ImGui::Button("AUDIO"))
auto editor = SHSystemManager::GetSystem<SHEditor>();
if (editor && !editor->selectedEntities.empty())
{
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
audioSystem->PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
}
if (!SHEditor::selectedEntities.empty())
{
EntityID const& eid = SHEditor::selectedEntities[0];
EntityID const& eid = editor->selectedEntities[0];
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
@ -90,7 +88,13 @@ namespace SHADE
DrawAddComponentButton<SHTransformComponent>(eid);
DrawAddComponentButton<SHRenderable>(eid);
DrawAddComponentButton<SHColliderComponent>(eid);
DrawAddComponentButton<SHRigidBodyComponent>(eid);
if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
{
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
{
SHComponentManager::AddComponent<SHTransformComponent>(eid);
}
}
ImGui::EndMenu();
}

View File

@ -3,11 +3,11 @@
//#==============================================================#
//|| SHADE Includes ||
//#==============================================================#
#include "Editor/SHEditor.hpp"
#include "SHEditorMenuBar.h"
#include "Editor/IconsMaterialDesign.h"
#include "Editor/Command/SHCommandManager.h"
#include "Scripting/SHScriptEngine.h"
#include "Editor/SHEditor.hpp"
#include "ECS_Base/Managers/SHSystemManager.h"
//#==============================================================#
@ -95,7 +95,8 @@ namespace SHADE
{
if(ImGui::Selectable(style.to_string().c_str()))
{
SHEditor::SetStyle(style.convert<SHEditor::Style>());
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->SetStyle(style.convert<SHEditor::Style>());
}
}
ImGui::EndMenu();

View File

@ -60,18 +60,18 @@ RTTR_REGISTRATION
namespace SHADE
{
//#==============================================================#
//|| Initialise static members ||
//|| Init static members ||
//#==============================================================#
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
SHEditor::EditorWindowMap SHEditor::editorWindows{};
SHEditor::EditorWindowID SHEditor::windowCount{};
std::vector<EntityID> SHEditor::selectedEntities;
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
//std::vector<EntityID> SHEditor::selectedEntities;
//#==============================================================#
//|| Public Member Functions ||
//#==============================================================#
void SHEditor::Initialise(SDL_Window* const sdlWindow)
void SHEditor::Init()
{
IMGUI_CHECKVERSION();
if(auto context = ImGui::CreateContext())
@ -90,28 +90,28 @@ namespace SHADE
InitFonts();
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id2 = SHFamilyID<SHSystem>::GetID<SHTransformSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
InitBackend(sdlWindow);
InitBackend();
SetStyle(Style::SHADE);
//Add editor windows
CreateEditorWindow<SHEditorMenuBar>();
CreateEditorWindow<SHHierarchyPanel>();
CreateEditorWindow<SHEditorInspector>();
CreateEditorWindow<SHEditorProfiler>();
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
}
void SHEditor::Update(float const dt)
void SHEditor::Update(double const dt)
{
(void)dt;
NewFrame();
for (const auto& window : editorWindows | std::views::values)
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{
if(window->isOpen)
window->Update();
@ -147,7 +147,7 @@ namespace SHADE
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
io.Fonts->Build();
@ -260,7 +260,7 @@ namespace SHADE
//#==============================================================#
//|| Private Member Functions ||
//#==============================================================#
void SHEditor::InitBackend(SDL_Window* sdlWindow)
void SHEditor::InitBackend()
{
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
{
@ -322,4 +322,9 @@ namespace SHADE
}
void SHEditor::EditorRoutine::Execute(double dt) noexcept
{
reinterpret_cast<SHEditor*>(system)->Update(dt);
}
}//namespace SHADE

View File

@ -11,6 +11,8 @@
//#==============================================================#
#include "SH_API.h"
#include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/Handle.h"
#include "EditorWindow/SHEditorWindow.h"
#include "Tools/SHLogger.h"
@ -28,11 +30,7 @@ namespace SHADE
class SHVkCommandBuffer;
class SHVkCommandPool;
/**
* @brief SHEditor static class contains editor variables and implementation of editor functions.
*
*/
class SH_API SHEditor
class SHEditorWindowManager
{
public:
//#==============================================================#
@ -41,46 +39,6 @@ namespace SHADE
using EditorWindowID = uint8_t;
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
/**
* @brief Style options
*
*/
enum class Style : uint8_t
{
SHADE,
DARK,
LIGHT,
CLASSIC
};
/**
* @brief Initialise the editor
*
* @param sdlWindow pointer to SDL_Window object created in application
*/
static void Initialise(SDL_Window* sdlWindow);
/**
* @brief Update the editor and add to ImGui DrawList
*
* @param dt Delta-time of the frame
*/
static void Update(float dt);
/**
* @brief Safely shutdown the editor
*
*/
static void Exit();
/**
* @brief Set the Style for the editor
*
* @param style Desired style
*/
static void SetStyle(Style style);
/**
* @brief Get ID for the Editor Window Type
*
@ -100,39 +58,6 @@ namespace SHADE
return id;
}
/**
* @brief Get pointer to the Editor Window
*
* @tparam T Type of editor window to retrieve
* @return T* Pointer to the editor window
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
// List of selected entities
static std::vector<EntityID> selectedEntities;
private:
/**
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
*
* @param sdlWindow Pointer to SDL_Window
*/
static void InitBackend(SDL_Window* sdlWindow);
/**
* @brief Start new frame for editor
*
*/
static void NewFrame();
/**
* @brief Perform ImGui and ImGui Backend Render
*
*/
static void Render();
/**
* @brief Create an Editor Window
*
@ -153,16 +78,114 @@ namespace SHADE
}
}
static void InitFonts() noexcept;
// Handle to command pool used for ImGui Vulkan Backend
static Handle<SHVkCommandPool> imguiCommandPool;
// Handle to command buffer used for ImGui Vulkan Backend
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
/**
* @brief Get pointer to the Editor Window
*
* @tparam T Type of editor window to retrieve
* @return T* Pointer to the editor window
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
private:
// Number of windows; used for Editor Window ID Generation
static EditorWindowID windowCount;
// Map of Editor Windows
static EditorWindowMap editorWindows;
friend class SHEditor;
};
/**
* @brief SHEditor static class contains editor variables and implementation of editor functions.
*
*/
class SH_API SHEditor final : public SHSystem
{
public:
class SH_API EditorRoutine final : public SHSystemRoutine
{
public:
EditorRoutine() = default;
void Execute(double dt) noexcept override final;
};
/**
* @brief Style options
*
*/
enum class Style : uint8_t
{
SHADE,
DARK,
LIGHT,
CLASSIC
};
/**
* @brief Initialise the editor
*
* @param sdlWindow pointer to SDL_Window object created in application
*/
void Init();
/**
* @brief Update the editor and add to ImGui DrawList
*
* @param dt Delta-time of the frame
*/
void Update(double dt);
/**
* @brief Safely shutdown the editor
*
*/
void Exit();
/**
* @brief Set the Style for the editor
*
* @param style Desired style
*/
void SetStyle(Style style);
/**
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
*
* @param sdlWindow Pointer to SDL_Window
*/
void InitBackend();
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
// List of selected entities
std::vector<EntityID> selectedEntities;
private:
/**
* @brief Start new frame for editor
*
*/
void NewFrame();
/**
* @brief Perform ImGui and ImGui Backend Render
*
*/
void Render();
void InitFonts() noexcept;
// Handle to command pool used for ImGui Vulkan Backend
Handle<SHVkCommandPool> imguiCommandPool;
// Handle to command buffer used for ImGui Vulkan Backend
Handle<SHVkCommandBuffer> imguiCommandBuffer;
SDL_Window* sdlWindow;
};//class SHEditor
}//namespace SHADE

View File

@ -26,7 +26,7 @@ namespace SHADE
{
class SH_API SHEditorWidgets
{
public:
public:
//#==============================================================#
//|| Constructor ||
//#==============================================================#
@ -35,6 +35,118 @@ namespace SHADE
//#==============================================================#
//|| Custom Widgets ||
//#==============================================================#
inline static ImVector<ImRect> panelStack{};
static void BeginPanel(std::string_view const& name, const ImVec2& size)
{
ImGui::BeginGroup();
auto cursorPos = ImGui::GetCursorScreenPos();
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
auto frameHeight = ImGui::GetFrameHeight();
ImGui::BeginGroup();
ImVec2 effectiveSize = size;
if (size.x < 0.0f)
effectiveSize.x = ImGui::GetContentRegionAvail().x;
else
effectiveSize.x = size.x;
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::SameLine(0.0f, 0.0f);
ImGui::BeginGroup();
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::SameLine(0.0f, 0.0f);
ImGui::TextUnformatted(name.data());
auto labelMin = ImGui::GetItemRectMin();
auto labelMax = ImGui::GetItemRectMax();
ImGui::SameLine(0.0f, 0.0f);
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
ImGui::BeginGroup();
ImGui::PopStyleVar(2);
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
auto itemWidth = ImGui::CalcItemWidth();
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
panelStack.push_back(ImRect(labelMin, labelMax));
}
static void EndPanel()
{
ImGui::PopItemWidth();
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
auto frameHeight = ImGui::GetFrameHeight();
ImGui::EndGroup();
ImGui::EndGroup();
ImGui::SameLine(0.0f, 0.0f);
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
ImGui::EndGroup();
auto itemMin = ImGui::GetItemRectMin();
auto itemMax = ImGui::GetItemRectMax();
auto labelRect = panelStack.back();
panelStack.pop_back();
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
labelRect.Min.x -= itemSpacing.x;
labelRect.Max.x += itemSpacing.x;
for (int i = 0; i < 4; ++i)
{
switch (i)
{
// left half-plane
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
// right half-plane
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
// top
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break;
// bottom
case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
}
ImGui::GetWindowDrawList()->AddRect(
frameRect.Min, frameRect.Max,
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)),
halfFrame.x);
ImGui::PopClipRect();
}
ImGui::PopStyleVar(2);
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->Size.x += frameHeight;
ImGui::Dummy(ImVec2(0.0f, 0.0f));
ImGui::EndGroup();
}
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
@ -44,7 +156,7 @@ namespace SHADE
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
}
template <typename T, std::size_t N>
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
@ -53,7 +165,7 @@ namespace SHADE
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
const ImGuiContext& g = *GImGui;
bool valueChanged = false;
ImGui::BeginGroup();
@ -69,15 +181,15 @@ namespace SHADE
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
ImGui::SetNextItemWidth(80.0f);
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
const ImVec2 min = ImGui::GetItemRectMin();
const ImVec2 max = ImGui::GetItemRectMax();
const float spacing = g.Style.FrameRounding;
const float halfSpacing = spacing / 2;
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
ImGuiColors::colors[i], 4);
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
ImGui::PopID();
ImGui::PopItemWidth();
@ -85,10 +197,10 @@ namespace SHADE
ImGui::EndColumns();
ImGui::PopID();
ImGui::EndGroup();
return valueChanged;
}
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
ImGuiSliderFlags flags = 0)
@ -99,98 +211,98 @@ namespace SHADE
{
changed = true;
}
if (changed)
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
}
return changed;
}
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
ImGuiSliderFlags flags = 0)
{
SHVec3 values = get();
bool changed = false;
if (DragN<float, 3>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags))
if (DragN<float, 3>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags))
{
changed = true;
}
if (changed)
{
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
}
return changed;
}
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
ImGuiSliderFlags flags = 0)
{
SHVec4 values = get();
bool changed = false;
if (DragN<float, 4>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags))
if (DragN<float, 4>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags))
{
changed = true;
}
if (changed)
{
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
}
return changed;
}
//#==============================================================#
//|| Widget Extensions ||
//#==============================================================#
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
{
bool value = get();
if (ImGui::Checkbox(label.c_str(), &value))
{
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
return true;
}
return false;
}
template<typename T>
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
{
T type = get();
for (size_t i = 0; i < listTypes.size(); i++)
{
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
{
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
}
ImGui::SameLine();
}
return true;
}
static bool InputText(const std::string& label, const std::function<std::string(void)> get,
const std::function<void(std::string)> set, ImGuiInputTextFlags flag = 0,
ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0)
@ -199,35 +311,35 @@ namespace SHADE
if (ImGui::InputText(label.c_str(), &text, flag, callback, userData))
{
if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
return true;
}
return false;
}
template <typename T>
static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function<T(void)> get, std::function<void(T const&)> set,
float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
{
T value = get();
std::cout << value <<" \n";
std::cout << value << " \n";
//bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags);
if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags))
{
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
return true;
}
return false;
}
static bool DragFloat(const std::string& fieldLabel, std::function<float(void)> get, std::function<void(float const&)> set,
float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
{
@ -236,18 +348,18 @@ namespace SHADE
if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
{
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
return true;
}
return false;
}
static bool DragInt(const std::string& fieldLabel, std::function<int(void)> get, std::function<void(int const&)> set,
float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
{
@ -256,35 +368,35 @@ namespace SHADE
if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
{
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
else if (ImGui::IsItemDeactivatedAfterEdit())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
return true;
}
return false;
}
template <typename T>
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> set,
template <typename T>
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> set,
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
{
T value = get();
if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags))
{
T value = get();
if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags))
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
return true;
}
return false;
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
return true;
}
return false;
}
static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function<float(void)> get, std::function<void(float const&)> set,
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
{
@ -292,17 +404,17 @@ namespace SHADE
if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
return true;
}
return false;
}
static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function<int(void)> get, std::function<void(int const&)> set,
const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
{
@ -310,26 +422,26 @@ namespace SHADE
if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
return true;
}
return false;
}
static bool ComboBox(const std::string& fieldLabel, std::vector<const char*> list, std::function<int(void)> get, std::function<void(int const&)> set)
{
bool edited = false;
int selected = get();
ImGui::PushID(fieldLabel.c_str());
ImGui::Text(fieldLabel.c_str()); ImGui::SameLine();
if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast<int>(list.size())))
{
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
}
ImGui::PopID();
return edited;

View File

@ -105,6 +105,17 @@ namespace SHADE
vk::Buffer GetVkBuffer (void) const noexcept;
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
template <typename T>
T GetDataFromMappedPointer(uint32_t index) const noexcept
{
if (mappedPtr && index < sizeStored / sizeof (T))
{
return (static_cast<T*>(mappedPtr))[index];
}
else
return {};
};
};
}

View File

@ -461,6 +461,11 @@ namespace SHADE
);
}
void SHVkCommandBuffer::CopyImageToBuffer(const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
{
vkCommandBuffer.copyImageToBuffer (src, vk::ImageLayout::eTransferSrcOptimal, dst, copyInfo);
}
void SHVkCommandBuffer::PipelineBarrier(
vk::PipelineStageFlags srcStage,
vk::PipelineStageFlags dstStage,

View File

@ -120,7 +120,8 @@ namespace SHADE
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
// Buffer Copy
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
// memory barriers
void PipelineBarrier (

View File

@ -110,6 +110,7 @@ namespace SHADE
// Clear CPU buffers
drawData.clear();
transformData.clear();
eidData.clear();
matPropsData.reset();
matPropsDataSize = 0;
@ -119,6 +120,7 @@ namespace SHADE
{
drawDataBuffer[i].Free();
transformDataBuffer[i].Free();
eidBuffer[i].Free();
matPropsBuffer[i].Free();
}
}
@ -206,7 +208,31 @@ namespace SHADE
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
}
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
void SHBatch::UpdateEIDBuffer(uint32_t frameIndex)
{
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{
SHLOG_WARNING("[SHBatch] Attempted to update eid buffers with an invalid frame index.");
return;
}
// Reset Transform Data
eidData.clear();
// Populate on the CPU
for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables)
{
eidData.emplace_back(renderable->GetEID());
}
// Transfer to GPU
if (eidBuffer[frameIndex])
eidBuffer[frameIndex]->WriteToMemory(eidData.data(), static_cast<EntityID>(eidData.size() * sizeof(EntityID)), 0, 0);
}
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
{
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{
@ -237,6 +263,11 @@ namespace SHADE
// - Transform data
transformData.reserve(numTotalElements);
transformData.clear();
// - EID data
eidData.reserve(numTotalElements);
eidData.clear();
// - Material Properties Data
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
@ -277,7 +308,8 @@ namespace SHADE
for (const SHRenderable* renderable : subBatch.Renderables)
{
// Transform
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(renderable->GetEID());
EntityID eid = renderable->GetEID();
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
if (!transform)
{
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
@ -287,6 +319,8 @@ namespace SHADE
{
transformData.emplace_back(transform->GetTRS());
}
eidData.emplace_back(eid);
// Material Properties
if (!EMPTY_MAT_PROPS)
@ -317,6 +351,12 @@ namespace SHADE
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
BuffUsage::eVertexBuffer
);
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(eidData.size() * sizeof(EntityID));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, eidBuffer[frameIndex], eidData.data(), EID_DATA_BYTES,
BuffUsage::eVertexBuffer
);
// - Material Properties Buffer
rebuildMaterialBuffers(frameIndex, descPool);
@ -339,6 +379,7 @@ namespace SHADE
static std::array<uint32_t, 1> dynamicOffset { 0 };
cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::EID, eidBuffer[frameIndex], 0);
if (matPropsDescSet[frameIndex])
{
cmdBuffer->BindDescriptorSet

View File

@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Math/SHMatrix.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "ECS_Base/SHECSMacros.h"
namespace SHADE
{
@ -78,6 +79,7 @@ namespace SHADE
void Clear();
void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void UpdateTransformBuffer(uint32_t frameIndex);
void UpdateEIDBuffer(uint32_t frameIndex);
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
@ -109,14 +111,16 @@ namespace SHADE
// CPU Buffers
std::vector<vk::DrawIndexedIndirectCommand> drawData;
std::vector<SHMatrix> transformData;
std::vector<EntityID> eidData;
std::unique_ptr<char> matPropsData;
Byte matPropsDataSize = 0;
Byte singleMatPropAlignedSize = 0;
Byte singleMatPropSize = 0;
Byte singleMatPropSize = 0;
bool isCPUBuffersDirty = true;
// GPU Buffers
TripleBuffer drawDataBuffer;
TripleBuffer transformDataBuffer;
TripleBuffer eidBuffer;
TripleBuffer matPropsBuffer;
TripleDescSet matPropsDescSet;

View File

@ -83,8 +83,9 @@ namespace SHADE
{
for (auto& batch : batches)
{
batch.UpdateMaterialBuffer(frameIndex, descPool);
batch.UpdateMaterialBuffer(frameIndex, descPool);
batch.UpdateTransformBuffer(frameIndex);
batch.UpdateEIDBuffer(frameIndex);
}
}

View File

@ -91,9 +91,10 @@ namespace SHADE
{
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, {SHVertexAttribute(SHAttribFormat::MAT_4D)}); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // EID at binding 8
}
void SHGraphicsGlobalData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept

View File

@ -144,6 +144,14 @@ namespace SHADE
*/
/***************************************************************************/
static constexpr uint32_t TRANSFORM = 4;
/***************************************************************************/
/*!
\brief
Vertex buffer bindings for the eid buffer.
*/
/***************************************************************************/
static constexpr uint32_t EID = 5;
};
/*******************************************************************************/

View File

@ -32,6 +32,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkSampler.h"
#include "Assets/Asset Types/SHTextureAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
namespace SHADE
{
@ -143,26 +144,22 @@ namespace SHADE
// Initialize world render graph
worldRenderGraph->Init(device, swapchain);
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Depth Buffer", "Present" }, {}); // no predecessors
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors
//First subpass to write to G-Buffer
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
//gBufferWriteSubpass->AddColorOutput("Scene");
gBufferWriteSubpass->AddColorOutput("Present");
gBufferWriteSubpass->AddColorOutput("Entity ID");
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL);
//writeSubpass->AddColorOutput("Normals");
// //Second subpass to read from G-Buffer
//auto compositeSubpass = node->AddSubpass("G-Buffer Composite");
//compositeSubpass->AddColorOutput("Present"); // TODO: This should be "Composite" and then composite will write to swapchain image "Present"
//compositeSubpass->AddInput("Normals");
//compositeSubpass->AddInput("Position");
// TODO: Use macro to add this node when SH_EDITOR is enabled
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
@ -201,6 +198,15 @@ namespace SHADE
cubeFS->Reflect();
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
mousePickSystem = resourceManager.Create<SHMousePickSystem>();
std::vector<Handle<SHVkCommandPool>> cmdPools;
cmdPools.reserve(swapchain->GetNumImages());
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
}
/***************************************************************************/
@ -400,10 +406,10 @@ namespace SHADE
}
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
auto& currFrameData = renderContext.GetCurrentFrameData();
mousePickSystem->Run(graphicsQueue, CURR_FRAME_IDX);
// #BackEndTest: queues an image for presentation
if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess)

View File

@ -52,6 +52,7 @@ namespace SHADE
class SHVkShaderModule;
class SHMaterial;
class SHMaterialInstance;
class SHMousePickSystem;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -268,6 +269,7 @@ namespace SHADE
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
@ -294,7 +296,7 @@ namespace SHADE
SHWindow* window = nullptr;
// Middle End Resources
ResourceManager resourceManager;
ResourceManager resourceManager;
SHMeshLibrary meshLibrary;
SHTextureLibrary texLibrary;
SHSamplerCache samplerCache;
@ -322,5 +324,8 @@ namespace SHADE
Handle<SHMaterial> defaultMaterial;
Handle<SHRenderGraph> worldRenderGraph;
// Sub systems
Handle<SHMousePickSystem> mousePickSystem;
};
}

View File

@ -0,0 +1,71 @@
#include "SHpch.h"
#include "SHMousePickSystem.h"
#include "Input/SHInputManager.h"
#include "Graphics/Commands/SHVkCommandPool.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Synchronization/SHVkFence.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
{
pickedEID = 0;
// Create command buffers
for (auto& pool : cmdPools)
{
commandBuffers.push_back(pool->RequestCommandBuffer (SH_CMD_BUFFER_TYPE::PRIMARY));
}
// assign the attachment
entityIDAttachment = eidAttachment;
// Create the fence
afterCopyFence = logicalDevice->CreateFence();
uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
}
void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept
{
// if input detected
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
{
afterCopyFence->Reset();
// begin command buffer for recording
commandBuffers[frameIndex]->BeginRecording();
// transition the image for optimized copying
entityIDAttachment->TransitionImage (vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eTransferSrcOptimal, commandBuffers[frameIndex], vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eTransfer, 0);
// copy the image here. Last argument is 0 because the attachment isn't a swapchain image.
entityIDAttachment->CopyToBuffer(imageDataDstBuffer, commandBuffers[frameIndex], 0);
// end command buffer for recording
commandBuffers[frameIndex]->EndRecording();
// submit the command buffer to copy image to buffer
queue->SubmitCommandBuffer({ commandBuffers[frameIndex] }, {}, {}, vk::PipelineStageFlagBits::eColorAttachmentOutput, afterCopyFence);
// wait for the copy to be done
afterCopyFence->Wait(true, std::numeric_limits<uint64_t>::max());
int mouseX = 0, mouseY = 0;
SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY);
pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(mouseY * entityIDAttachment->GetWidth() + mouseX);
}
}
EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept
{
return pickedEID;
}
}

View File

@ -0,0 +1,47 @@
#pragma once
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
#include "ECS_Base/SHECSMacros.h"
#include "Math/Vector/SHVec2.h"
#include <span>
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkCommandPool;
class SHVkCommandBuffer;
class SHVkFence;
class SHVkQueue;
class SHVkBuffer;
class SHMousePickSystem
{
private:
//! Handle to the render graph resource that will contain the entity IDs
Handle<SHRenderGraphResource> entityIDAttachment;
//! Command buffers meant for copying image to buffer
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
//! After the attachment has copied its data to a buffer, we want to signal this fence
Handle<SHVkFence> afterCopyFence;
//! buffer to contain the attachment data after copying
Handle<SHVkBuffer> imageDataDstBuffer;
//! eid picked from screen
EntityID pickedEID;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
EntityID GetPickedEntity (void) const noexcept;
};
}

View File

@ -2,6 +2,8 @@
#include "SHPipelineLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
@ -20,6 +22,31 @@ namespace SHADE
// Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState());
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(subpassColorReferences.size());
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false,
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
// Actually construct the pipeline
newPipeline->ConstructPipeline();

View File

@ -137,22 +137,9 @@ namespace SHADE
{
VkBool32 logic_op_enable{ VK_FALSE };
vk::LogicOp logic_op{ VK_LOGIC_OP_COPY };
vk::LogicOp logic_op{ vk::LogicOp::eCopy };
std::vector<vk::PipelineColorBlendAttachmentState> attachments =
{
vk::PipelineColorBlendAttachmentState
{
.blendEnable = true,
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
};
std::vector<vk::PipelineColorBlendAttachmentState> attachments{};
};
// TODO: Specialization constants

View File

@ -40,7 +40,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{
// If we set to
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@ -50,7 +50,7 @@ namespace SHADE
format = swapchainHdl->GetSurfaceFormatKHR().format;
}
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, createFlags));
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags));
}
/***************************************************************************/
@ -498,4 +498,13 @@ namespace SHADE
}
Handle<SHRenderGraphResource> SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept
{
if (graphResources.contains(resourceName))
{
return graphResources.at(resourceName);
}
return {};
}
}

View File

@ -75,7 +75,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
void Generate (void) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
@ -85,7 +85,8 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
Handle<SHRenderGraphResource> GetRenderGraphResource (std::string const& resourceName) const noexcept;
};
}

View File

@ -261,6 +261,7 @@ namespace SHADE
return {};
}
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetDrawPipline(vsFsPair);
if (!pipeline)
{
@ -301,4 +302,12 @@ namespace SHADE
return subpasses[subpassIndexing.at(subpassName.data())];
}
Handle<SHRenderGraphResource> SHRenderGraphNode::GetResource(uint32_t resourceIndex) const noexcept
{
if (resourceIndex < attResources.size())
return attResources[resourceIndex];
else
return {};
}
}

View File

@ -105,6 +105,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
Handle<SHVkRenderpass> GetRenderpass(void) const noexcept;
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
friend class SHRenderGraph;
};

View File

@ -3,6 +3,8 @@
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Graphics/Images/SHVkImageView.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
@ -43,7 +45,7 @@ namespace SHADE
*/
/***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
: logicalDevice {logicalDevice}
, swapchain{ swapchain }
, resourceType{ type }
@ -59,7 +61,7 @@ namespace SHADE
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
{
imageAspectFlags = vk::ImageAspectFlags{};
usage = {};
usage = usageFlags;
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (resourceType)
@ -242,4 +244,59 @@ namespace SHADE
}
}
void SHRenderGraphResource::TransitionImage(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, Handle<SHVkCommandBuffer> commandBuffer, vk::PipelineStageFlagBits srcStage, vk::PipelineStageFlagBits dstStage, uint32_t frameIndex) noexcept
{
vk::ImageMemoryBarrier barrier;
barrier.oldLayout = oldLayout;
barrier.newLayout = newLayout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = images[frameIndex]->GetVkImage(),
barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = mipLevels;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1; // always 1 since we wont have array of images for attachments
commandBuffer->PipelineBarrier(srcStage, dstStage, {}, {}, {}, {barrier});
}
void SHRenderGraphResource::CopyToBuffer(Handle<SHVkBuffer> dstBuffer, Handle<SHVkCommandBuffer> commandBuffer, uint32_t frameIndex) const noexcept
{
vk::ImageSubresourceLayers subResource
{
.aspectMask = SHVkUtil::IsDepthOnlyFormat(resourceFormat) ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eColor,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1
};
vk::BufferImageCopy region
{
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = subResource,
.imageOffset = vk::Offset3D {0,0,0},
.imageExtent = vk::Extent3D {width, height, 1}
};
commandBuffer->CopyImageToBuffer(images[frameIndex]->GetVkImage(), dstBuffer->GetVkBuffer(), {region});
}
vk::Format SHRenderGraphResource::GetResourceFormat(void) const noexcept
{
return resourceFormat;
}
uint32_t SHRenderGraphResource::GetWidth(void) const noexcept
{
return width;
}
uint32_t SHRenderGraphResource::GetHeight(void) const noexcept
{
return height;
}
}

View File

@ -13,6 +13,8 @@ namespace SHADE
class SHVkImageView;
class SHVkLogicalDevice;
class SHVkSwapchain;
class SHVkCommandBuffer;
class SHVkBuffer;
class SH_API SHRenderGraphResource
{
@ -65,12 +67,24 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept;
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
void TransitionImage(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, Handle<SHVkCommandBuffer> commandBuffer, vk::PipelineStageFlagBits srcStage, vk::PipelineStageFlagBits dstStage, uint32_t frameIndex) noexcept;
void CopyToBuffer (Handle<SHVkBuffer> dstBuffer, Handle<SHVkCommandBuffer> commandBuffer, uint32_t frameIndex = 0) const noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
vk::Format GetResourceFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;

View File

@ -2,6 +2,8 @@
#include "SHSubpass.h"
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "SHRenderGraphNode.h"
#include "SHRenderGraphResource.h"
namespace SHADE
{
@ -207,4 +209,15 @@ namespace SHADE
{
return superBatch;
}
std::vector<vk::AttachmentReference> const& SHSubpass::GetColorAttachmentReferences(void) const noexcept
{
return colorReferences;
}
vk::Format SHSubpass::GetFormatFromAttachmentReference(uint32_t attachmentReference) const noexcept
{
return parentNode->GetResource(attachmentReference)->GetResourceFormat();
}
}

View File

@ -86,7 +86,8 @@ namespace SHADE
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
SHSubPassIndex GetIndex() const noexcept;
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
std::vector<vk::AttachmentReference> const& GetColorAttachmentReferences (void) const noexcept;
vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept;
friend class SHRenderGraphNode;
friend class SHRenderGraph;

View File

@ -23,6 +23,38 @@ namespace SHADE
IsDepthOnlyFormat(format);
}
bool SHVkUtil::IsBlendCompatible(vk::Format format) noexcept
{
// TODO: Update with all formats
switch (format)
{
case vk::Format::eR32Sint:
case vk::Format::eR32G32Sint:
case vk::Format::eR32G32B32Sint:
case vk::Format::eR32G32B32A32Sint:
return false;
case vk::Format::eR32Sfloat:
case vk::Format::eR32G32Sfloat:
case vk::Format::eR32G32B32Sfloat:
case vk::Format::eR32G32B32A32Sfloat:
return true;
}
return false;
}
uint32_t SHVkUtil::GetBytesPerPixelFromFormat(vk::Format format) noexcept
{
// TODO: Update with all formats
switch (format)
{
case vk::Format::eR32Sint:
case vk::Format::eR32Uint:
case vk::Format::eR32Sfloat:
return 4;
}
return 0;
}
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage)
{
if (bufferHandle)

View File

@ -19,9 +19,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
class SHVkUtil
{
public:
static bool IsDepthOnlyFormat (vk::Format format) noexcept;
static bool IsDepthStencilAttachment(vk::Format format) noexcept;
public:
static bool IsDepthOnlyFormat (vk::Format format) noexcept;
static bool IsDepthStencilAttachment (vk::Format format) noexcept;
static bool IsBlendCompatible (vk::Format format) noexcept;
static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept;
/***********************************************************************************/
/*!

View File

@ -43,7 +43,10 @@ namespace SHADE
void SHInputManager::UpdateInput(double dt) noexcept
{
//Keyboard and Mouse Buttons////////////////////////////////////////////////
//Keyboard and Mouse Buttons////////////////////////////////////////////////
//Write to lastKeys
memcpy(keysLast, keys, sizeof(keys));
//Poll
unsigned char keyboardState[MAX_KEYS];
//if (GetKeyboardState(keyboardState) == false) return;
@ -96,9 +99,6 @@ namespace SHADE
}
}
//Write to lastKeys
memcpy(keysLast, keys, sizeof(keys));
//Mouse Positioning/////////////////////////////////////
//https://stackoverflow.com/a/6423739

View File

@ -14,6 +14,9 @@
#include "SHBoundingBox.h"
// Project Headers
#include "Math/SHMathHelpers.h"
#include "Math/SHRay.h"
using namespace DirectX;
namespace SHADE
{
@ -21,89 +24,53 @@ namespace SHADE
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingBox::SHBoundingBox() noexcept
{
type = Type::BOX;
}
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
: SHShape {}
, center { c }
, halfExtents { hE }
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
Center = c;
Extents = hE;
}
SHBoundingBox::SHBoundingBox(const SHVec3* vertices, size_t numVertices) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
if (vertices == nullptr || numVertices < 2)
{
SHLOG_ERROR("Insufficient number of vertices passed into bounding box constructor!")
return;
}
SHVec3 min { std::numeric_limits<float>::max() };
SHVec3 max { std::numeric_limits<float>::min() };
for (size_t i = 0; i < numVertices; ++i)
{
const SHVec3& v = vertices[i];
min.x = SHMath::Min(min.x, v.x);
min.y = SHMath::Min(min.y, v.y);
min.z = SHMath::Min(min.z, v.z);
max.x = SHMath::Max(max.x, v.x);
max.y = SHMath::Max(max.y, v.y);
max.z = SHMath::Max(max.z, v.z);
}
center = SHVec3::Lerp(min, max, 0.5f);
halfExtents = SHVec3::Abs((max - min) * 0.5f);
}
SHBoundingBox::SHBoundingBox(const SHBoundingBox* boxes, size_t numBoxes) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
if (boxes == nullptr || numBoxes == 0)
{
SHLOG_ERROR("Insufficient number of boxes passed into bounding box constructor!")
return;
}
center = boxes->center;
halfExtents = boxes->halfExtents;
for (size_t i = 1; i < numBoxes; ++i)
*this = Combine(*this, boxes[i]);
}
SHBoundingBox::SHBoundingBox(const SHBoundingBox& rhs) noexcept
: SHShape {}
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{
type = Type::BOUNDING_BOX;
if (this == &rhs)
return;
type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
}
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
: SHShape {}
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{
type = Type::BOUNDING_BOX;
type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept
{
if (rhs.type != Type::BOUNDING_BOX)
if (rhs.type != Type::BOX)
{
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
}
else
else if (this != &rhs)
{
center = rhs.center;
halfExtents = rhs.halfExtents;
Center = rhs.Center;
Extents = rhs.Extents;
}
return *this;
@ -111,14 +78,14 @@ namespace SHADE
SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept
{
if (rhs.type != Type::BOUNDING_BOX)
if (rhs.type != Type::BOX)
{
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
}
else
{
center = rhs.center;
halfExtents = rhs.halfExtents;
Center = rhs.Center;
Extents = rhs.Extents;
}
return *this;
@ -128,24 +95,24 @@ namespace SHADE
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
const SHVec3& SHBoundingBox::GetCenter() const noexcept
SHVec3 SHBoundingBox::GetCenter() const noexcept
{
return center;
return Center;
}
const SHVec3& SHBoundingBox::GetHalfExtents() const noexcept
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept
{
return halfExtents;
return Extents;
}
SHVec3 SHBoundingBox::GetMin() const noexcept
{
return center - halfExtents;
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
}
SHVec3 SHBoundingBox::GetMax() const noexcept
{
return center + halfExtents;
return SHVec3{ Center.x + Extents.x, Center.y + Extents.y, Center.z + Extents.z };
}
/*-----------------------------------------------------------------------------------*/
@ -154,36 +121,42 @@ namespace SHADE
void SHBoundingBox::SetCenter(const SHVec3& newCenter) noexcept
{
center = newCenter;
Center = newCenter;
}
void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept
{
halfExtents = newHalfExtents;
Extents = newHalfExtents;
}
void SHBoundingBox::SetMin(const SHVec3& min) noexcept
{
const SHVec3 MAX = center + halfExtents;
const SHVec3 MAX = GetMax();
center = SHVec3::Lerp(min, MAX, 0.5f);
halfExtents = SHVec3::Abs((MAX - min) * 0.5f);
Center = SHVec3::Lerp(min, MAX, 0.5f);
Extents = SHVec3::Abs((MAX - min) * 0.5f);
}
void SHBoundingBox::SetMax(const SHVec3& max) noexcept
{
const SHVec3 MIN = center - halfExtents;
const SHVec3 MIN = GetMin();
center = SHVec3::Lerp(MIN, max, 0.5f);
halfExtents = SHVec3::Abs((max - MIN) * 0.5f);
Center = SHVec3::Lerp(MIN, max, 0.5f);
Extents = SHVec3::Abs((max - MIN) * 0.5f);
}
void SHBoundingBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
{
center = SHVec3::Lerp(min, max, 0.5f);
halfExtents = SHVec3::Abs((max - min) * 0.5f);
Center = SHVec3::Lerp(min, max, 0.5f);
Extents = SHVec3::Abs((max - min) * 0.5f);
}
std::vector<SHVec3> SHBoundingBox::GetVertices() const noexcept
{
std::vector<SHVec3> vertices{ 8 };
GetCorners(vertices.data());
return vertices;
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
@ -191,38 +164,29 @@ namespace SHADE
bool SHBoundingBox::TestPoint(const SHVec3& point) noexcept
{
const SHVec3 V = SHVec3::Abs(point - center);
for (size_t i = 0; i < SHVec3::SIZE; ++i)
{
if (V[i] > halfExtents[i])
return false;
}
return BoundingBox::Contains(point);
}
return true;
bool SHBoundingBox::Raycast(const SHRay& ray, float& distance) noexcept
{
return BoundingBox::Intersects(ray.position, ray.direction, distance);
}
bool SHBoundingBox::Contains(const SHBoundingBox& rhs) const noexcept
{
const SHVec3 V = SHVec3::Abs(rhs.center - center);
for (size_t i = 0; i < SHVec3::SIZE; ++i)
{
if (V[i] > rhs.halfExtents[i])
return false;
}
return true;
return BoundingBox::Contains(rhs);
}
float SHBoundingBox::Volume() const noexcept
{
return 8.0f * (halfExtents.x * halfExtents.y * halfExtents.z);
return 8.0f * (Extents.x * Extents.y * Extents.z);
}
float SHBoundingBox::SurfaceArea() const noexcept
{
return 8.0f * ((halfExtents.x * halfExtents.y)
+ (halfExtents.x * halfExtents.z)
+ (halfExtents.y * halfExtents.z));
return 8.0f * ((Extents.x * Extents.y)
+ (Extents.x * Extents.z)
+ (Extents.y * Extents.z));
}
/*-----------------------------------------------------------------------------------*/
@ -231,37 +195,31 @@ namespace SHADE
SHBoundingBox SHBoundingBox::Combine(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept
{
if (lhs.Contains(rhs))
return lhs;
if (rhs.Contains(lhs))
return rhs;
const SHVec3 LHS_MIN = lhs.GetMin();
const SHVec3 LHS_MAX = lhs.GetMax();
const SHVec3 RHS_MIN = rhs.GetMin();
const SHVec3 RHS_MAX = rhs.GetMax();
SHVec3 min = SHVec3::Min({ LHS_MIN, RHS_MIN });
SHVec3 max = SHVec3::Max({ LHS_MAX, RHS_MAX });
SHBoundingBox result{ lhs };
result.SetMinMax(min, max);
SHBoundingBox result;
CreateMerged(result, lhs, rhs);
return result;
}
bool SHBoundingBox::Intersect(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept
{
const SHVec3 V = SHVec3::Abs(lhs.center - rhs.center);
const SHVec3 D = lhs.halfExtents + rhs.halfExtents;
return lhs.Intersects(rhs);
}
for (size_t i = 0; i < SHVec3::SIZE; ++i)
{
if (V[i] > D[i])
return false;
}
SHBoundingBox SHBoundingBox::BuildFromBoxes(const SHBoundingBox* boxes, size_t numBoxes) noexcept
{
SHBoundingBox result;
return true;
for (size_t i = 1; i < numBoxes; ++i)
CreateMerged(result, boxes[i - 1], boxes[i]);
return result;
}
SHBoundingBox SHBoundingBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
{
SHBoundingBox result;
CreateFromPoints(result, numVertices, vertices, stride);
return result;
}
} // namespace SHADE

View File

@ -22,32 +22,43 @@ namespace SHADE
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
// TODO(Diren): Use DirectX BoundingBox instead of custom
class SH_API SHBoundingBox : public SHShape
class SH_API SHBoundingBox : public SHShape,
private DirectX::BoundingBox
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t NUM_VERTICES = 8;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept;
SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
~SHBoundingBox () override = default;
SHBoundingBox (const SHBoundingBox& rhs) noexcept;
SHBoundingBox (SHBoundingBox&& rhs) noexcept;
SHBoundingBox () noexcept;
SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
SHBoundingBox (const SHBoundingBox& rhs) noexcept;
SHBoundingBox (SHBoundingBox&& rhs) noexcept;
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept;
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept;
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] const SHVec3& GetCenter () const noexcept;
[[nodiscard]] const SHVec3& GetHalfExtents () const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
@ -59,31 +70,25 @@ namespace SHADE
void SetMax (const SHVec3& max) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override;
[[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override;
[[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override;
[[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept;
[[nodiscard]] float Volume () const noexcept;
[[nodiscard]] float SurfaceArea () const noexcept;
[[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept;
[[nodiscard]] float Volume () const noexcept;
[[nodiscard]] float SurfaceArea () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 center;
SHVec3 halfExtents;
[[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
};

View File

@ -0,0 +1,183 @@
/****************************************************************************************
* \file SHBoundingSphere.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Bounding Sphere
*
* \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 <SHpch.h>
// Primary Header
#include "SHBoundingSphere.h"
// Project Headers
#include "Math/SHMathHelpers.h"
#include "Math/SHRay.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere::SHBoundingSphere() noexcept
{
type = Type::SPHERE;
}
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
{
type = Type::SPHERE;
Center = center;
Radius = radius;
}
SHBoundingSphere::SHBoundingSphere(const SHBoundingSphere& rhs) noexcept
{
if (this == &rhs)
return;
type = Type::SPHERE;
Center = rhs.Center;
Radius = rhs.Radius;
}
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
{
type = Type::SPHERE;
Center = rhs.Center;
Radius = rhs.Radius;
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere& SHBoundingSphere::operator=(const SHBoundingSphere& rhs) noexcept
{
if (rhs.type != Type::SPHERE)
{
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
}
else if (this != &rhs)
{
Center = rhs.Center;
Radius = rhs.Radius;
}
return *this;
}
SHBoundingSphere& SHBoundingSphere::operator=(SHBoundingSphere&& rhs) noexcept
{
if (rhs.type != Type::SPHERE)
{
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
}
else
{
Center = rhs.Center;
Radius = rhs.Radius;
}
return *this;
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3 SHBoundingSphere::GetCenter() const noexcept
{
return Center;
}
float SHBoundingSphere::GetRadius() const noexcept
{
return Radius;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHBoundingSphere::SetCenter(const SHVec3& center) noexcept
{
Center = center;
}
void SHBoundingSphere::SetRadius(float radius) noexcept
{
Radius = radius;
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHBoundingSphere::TestPoint(const SHVec3& point) noexcept
{
return BoundingSphere::Contains(point);
}
bool SHBoundingSphere::Raycast(const SHRay& ray, float& distance) noexcept
{
return Intersects(ray.position, ray.direction, distance);
}
bool SHBoundingSphere::Contains(const SHBoundingSphere& rhs) const noexcept
{
return BoundingSphere::Contains(rhs);
}
float SHBoundingSphere::Volume() const noexcept
{
return (4.0f / 3.0f) * SHMath::PI * (Radius * Radius * Radius);
}
float SHBoundingSphere::SurfaceArea() const noexcept
{
return 4.0f * SHMath::PI * (Radius * Radius);
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere SHBoundingSphere::Combine(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept
{
SHBoundingSphere result;
CreateMerged(result, lhs, rhs);
return result;
}
bool SHBoundingSphere::Intersect(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept
{
return lhs.Intersects(rhs);
}
SHBoundingSphere SHBoundingSphere::BuildFromSpheres(const SHBoundingSphere* spheres, size_t numSpheres) noexcept
{
SHBoundingSphere result;
for (size_t i = 1; i < numSpheres; ++i)
CreateMerged(result, spheres[i - 1], spheres[i]);
return result;
}
SHBoundingSphere SHBoundingSphere::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
{
SHBoundingSphere result;
CreateFromPoints(result, numVertices, vertices, stride);
return result;
}
} // namespace SHADE

View File

@ -0,0 +1,83 @@
/****************************************************************************************
* \file SHBoundingSphere.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Bounding Sphere.
*
* \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 <DirectXCollision.h>
// Project Headers
#include "SHShape.h"
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHBoundingSphere : public SHShape,
private DirectX::BoundingSphere
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHBoundingSphere () noexcept;
SHBoundingSphere (const SHVec3& center, float radius) noexcept;
SHBoundingSphere (const SHBoundingSphere& rhs) noexcept;
SHBoundingSphere (SHBoundingSphere&& rhs) noexcept;
~SHBoundingSphere () override = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHBoundingSphere& operator= (const SHBoundingSphere& rhs) noexcept;
SHBoundingSphere& operator= (SHBoundingSphere&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] float GetRadius () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& center) noexcept;
void SetRadius (float radius) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override;
[[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override;
[[nodiscard]] bool Contains (const SHBoundingSphere& rhs) const noexcept;
[[nodiscard]] float Volume () const noexcept;
[[nodiscard]] float SurfaceArea () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHBoundingSphere Combine (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept;
[[nodiscard]] static bool Intersect (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept;
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
};
} // namespace SHADE

View File

@ -11,8 +11,9 @@
#pragma once
// Project Headers
#include "Math/Transform/SHTransform.h"
#include "SH_API.h"
#include "Math/SHRay.h"
namespace SHADE
{
@ -29,11 +30,10 @@ namespace SHADE
enum class Type
{
BOUNDING_BOX
BOX
, SPHERE
, CAPSULE
, CONVEX_HULL
, TRIANGLE
, COUNT
, NONE = -1
@ -69,7 +69,8 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0;
[[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0;
[[nodiscard]] virtual bool Raycast (const SHRay& ray, float& distance) noexcept = 0;
protected:
/*---------------------------------------------------------------------------------*/

View File

@ -0,0 +1,297 @@
/****************************************************************************************
* \file SHColour.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Colour.
*
* \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 <SHpch.h>
#include <DirectXColors.h>
// Primary Header
#include "SHColour.h"
// Project Headers
#include "SHMathHelpers.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHColour SHColour::BEIGE = DirectX::Colors::Beige;
const SHColour SHColour::BLACK = DirectX::Colors::Black;
const SHColour SHColour::BLUE = DirectX::Colors::Blue;
const SHColour SHColour::BROWN = DirectX::Colors::Brown;
const SHColour SHColour::CHOCOLATE = DirectX::Colors::Chocolate;
const SHColour SHColour::CORAL = DirectX::Colors::Coral;
const SHColour SHColour::CRIMSON = DirectX::Colors::Crimson;
const SHColour SHColour::CYAN = DirectX::Colors::Cyan;
const SHColour SHColour::DARKBLUE = DirectX::Colors::DarkBlue;
const SHColour SHColour::DARKGRAY = DirectX::Colors::DarkGray;
const SHColour SHColour::DARKGREEN = DirectX::Colors::DarkGreen;
const SHColour SHColour::DARKMAGENTA = DirectX::Colors::DarkMagenta;
const SHColour SHColour::DARKORANGE = DirectX::Colors::DarkOrange;
const SHColour SHColour::DARKRED = DirectX::Colors::DarkRed;
const SHColour SHColour::DEEPPINK = DirectX::Colors::DeepPink;
const SHColour SHColour::FORESTGREEN = DirectX::Colors::ForestGreen;
const SHColour SHColour::FUCHSIA = DirectX::Colors::Fuchsia;
const SHColour SHColour::GOLD = DirectX::Colors::Gold;
const SHColour SHColour::GRAY = DirectX::Colors::Gray;
const SHColour SHColour::GREEN = DirectX::Colors::Green;
const SHColour SHColour::HOTPINK = DirectX::Colors::HotPink;
const SHColour SHColour::INDIGO = DirectX::Colors::Indigo;
const SHColour SHColour::LAVENDER = DirectX::Colors::Lavender;
const SHColour SHColour::LIGHTBLUE = DirectX::Colors::LightBlue;
const SHColour SHColour::LIGHTGRAY = DirectX::Colors::LightGray;
const SHColour SHColour::LIGHTGREEN = DirectX::Colors::LightGreen;
const SHColour SHColour::LIGHTPINK = DirectX::Colors::LightPink;
const SHColour SHColour::LIGHTYELLOW = DirectX::Colors::LightYellow;
const SHColour SHColour::LIME = DirectX::Colors::Lime;
const SHColour SHColour::LIMEGREEN = DirectX::Colors::LimeGreen;
const SHColour SHColour::MAGENTA = DirectX::Colors::Magenta;
const SHColour SHColour::MAROON = DirectX::Colors::Maroon;
const SHColour SHColour::MEDIUMBLUE = DirectX::Colors::MediumBlue;
const SHColour SHColour::MEDIUMPURPLE = DirectX::Colors::MediumPurple;
const SHColour SHColour::NAVY = DirectX::Colors::Navy;
const SHColour SHColour::OLIVE = DirectX::Colors::Olive;
const SHColour SHColour::ORANGE = DirectX::Colors::Orange;
const SHColour SHColour::ORCHID = DirectX::Colors::Orchid;
const SHColour SHColour::PINK = DirectX::Colors::Pink;
const SHColour SHColour::PURPLE = DirectX::Colors::Purple;
const SHColour SHColour::RED = DirectX::Colors::Red;
const SHColour SHColour::ROYALBLUE = DirectX::Colors::RoyalBlue;
const SHColour SHColour::SALMON = DirectX::Colors::Salmon;
const SHColour SHColour::SANDYBROWN = DirectX::Colors::SandyBrown;
const SHColour SHColour::SILVER = DirectX::Colors::Silver;
const SHColour SHColour::SKYBLUE = DirectX::Colors::SkyBlue;
const SHColour SHColour::SLATEGRAY = DirectX::Colors::SlateGray;
const SHColour SHColour::SNOW = DirectX::Colors::Snow;
const SHColour SHColour::STEELBLUE = DirectX::Colors::SteelBlue;
const SHColour SHColour::TAN = DirectX::Colors::Tan;
const SHColour SHColour::TEAL = DirectX::Colors::Teal;
const SHColour SHColour::TURQUOISE = DirectX::Colors::Turquoise;
const SHColour SHColour::VIOLET = DirectX::Colors::Violet;
const SHColour SHColour::WHITE = DirectX::Colors::White;
const SHColour SHColour::YELLOW = DirectX::Colors::Yellow;
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHColour::SHColour() noexcept
: SHVec4 { 0.0f, 0.0f, 0.0f, 1.0f }
{}
SHColour::SHColour(float r, float g, float b) noexcept
: SHVec4 { r, g, b, 1.0f }
{}
SHColour::SHColour(float r, float g, float b, float a) noexcept
: SHVec4 { r, g, b, a }
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept
: SHVec4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
static_cast<float>(b) / 255.0f,
1.0f
}
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
: SHVec4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
static_cast<float>(b) / 255.0f,
static_cast<float>(a) / 255.0f
}
{}
SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept
: SHVec4 { colour.x, colour.y, colour.z, 1.0f }
{}
SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept
: SHVec4
{
XMVectorGetX(colour),
XMVectorGetY(colour),
XMVectorGetZ(colour),
XMVectorGetW(colour)
}
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHColour::operator==(const SHColour& rhs) const noexcept
{
return XMColorEqual(*this, rhs);
}
bool SHColour::operator!=(const SHColour& rhs) const noexcept
{
return XMColorNotEqual(*this, rhs);
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHColourHSV SHColour::ToHSV() noexcept
{
SHColourHSV hsv;
const float MIN = SHMath::Min({ x, y, z });
const float MAX = SHMath::Max({ x, y, z });
hsv.v = MAX;
const float DELTA = MAX - MIN;
hsv.s = (MAX != 0.0f) ? DELTA / MAX : 0.0f;
static const float SIN_60 = sin(SHMath::DegreesToRadians(60.0f));
if (DELTA == 0.0f)
hsv.h = 0.0f;
else if (x == MAX)
hsv.h = (y - z) / DELTA;
else if (y == MAX)
hsv.h = 2.0f + (z - x) / DELTA;
else
hsv.h = 4.0f + (x - y) / DELTA;
hsv.h *= 60;
if (hsv.h < 0.0f)
hsv.h += 360.f;
return hsv;
}
void SHColour::Negate() noexcept
{
XMStoreFloat4(this, XMColorNegative(*this));
}
void SHColour::Saturate() noexcept
{
XMStoreFloat4(this, XMVectorSaturate(*this));
}
void SHColour::AdjustSaturation(float saturation) noexcept
{
XMStoreFloat4(this, XMColorAdjustSaturation(*this, saturation));
}
void SHColour::AdjustContrast(float contrast) noexcept
{
XMStoreFloat4(this, XMColorAdjustContrast(*this, contrast));
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHColour SHColour::Modulate(const SHColour& lhs, const SHColour& rhs) noexcept
{
SHColour result;
XMStoreFloat4(&result, XMColorModulate(lhs, rhs));
return result;
}
SHColour SHColour::FromHSV(float hue, float saturation, float value)
{
if (hue < 0.0f || saturation < 0.0f || value < 0.0f)
throw std::invalid_argument("One or more of the hsv values are invalid!");
SHColour colour;
if (saturation == 0.0f)
{
colour.x = colour.y = colour.z = value;
}
else
{
hue /= 60.0f;
const int SECTOR = static_cast<int>(hue);
const float F = hue - static_cast<float>(SECTOR);
const float P = value * (1.0f - saturation);
const float Q = value * (1.0f - saturation * F);
const float T = value * (1.0f - saturation * (1.0f - F));
switch (SECTOR)
{
case 0:
{
colour.x = value;
colour.y = T;
colour.z = P;
break;
}
case 1:
{
colour.x = Q;
colour.y = value;
colour.z = P;
break;
}
case 2:
{
colour.x = P;
colour.y = value;
colour.z = T;
break;
}
case 3:
{
colour.x = P;
colour.y = Q;
colour.z = value;
break;
}
case 4:
{
colour.x = T;
colour.y = P;
colour.z = value;
break;
}
default:
{
colour.x = value;
colour.y = P;
colour.z = Q;
break;
}
}
}
return colour;
}
SHColour SHColour::FromHSV(const SHColourHSV& hsv)
{
return FromHSV(hsv.h, hsv.s, hsv.v);
}
} // namespace SHADE

View File

@ -0,0 +1,166 @@
/****************************************************************************************
* \file SHColour.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Colour.
*
* \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 <DirectXMath.h>
// Project Headers
#include "SH_API.h"
#include "Vector/SHVec3.h"
#include "Vector/SHVec4.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHColour;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
struct SH_API SHColourHSV
{
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
float h = 0.0f;
float s = 0.0f;
float v = 0.0f;
};
class SH_API SHColour : private SHVec4
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHColour () noexcept;
SHColour (float r, float g, float b) noexcept;
SHColour (float r, float g, float b, float a) noexcept;
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
SHColour (const SHVec3& colour) noexcept;
SHColour (const DirectX::XMFLOAT3& colour) noexcept;
SHColour (const DirectX::XMVECTORF32& colour) noexcept;
SHColour (const SHColour&) = default;
SHColour (SHColour&&) = default;
~SHColour () = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHColour& operator= (const SHColour&) = default;
SHColour& operator= (SHColour&&) = default;
bool operator== (const SHColour& rhs) const noexcept;
bool operator!= (const SHColour& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] inline float& r() noexcept { return x; }
[[nodiscard]] inline float& g() noexcept { return y; }
[[nodiscard]] inline float& b() noexcept { return z; }
[[nodiscard]] inline float& a() noexcept { return w; }
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHColourHSV ToHSV () noexcept;
void Negate () noexcept;
void Saturate () noexcept;
void AdjustSaturation (float saturation) noexcept;
void AdjustContrast (float contrast) noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHColour Modulate (const SHColour& lhs, const SHColour& rhs) noexcept;
[[nodiscard]] static SHColour FromHSV (float hue, float saturation, float value);
[[nodiscard]] static SHColour FromHSV (const SHColourHSV& hsv);
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static const SHColour BEIGE ;
static const SHColour BLACK ;
static const SHColour BLUE ;
static const SHColour BROWN ;
static const SHColour CHOCOLATE ;
static const SHColour CORAL ;
static const SHColour CRIMSON ;
static const SHColour CYAN ;
static const SHColour DARKBLUE ;
static const SHColour DARKGRAY ;
static const SHColour DARKGREEN ;
static const SHColour DARKMAGENTA ;
static const SHColour DARKORANGE ;
static const SHColour DARKRED ;
static const SHColour DEEPPINK ;
static const SHColour FORESTGREEN ;
static const SHColour FUCHSIA ;
static const SHColour GOLD ;
static const SHColour GRAY ;
static const SHColour GREEN ;
static const SHColour HOTPINK ;
static const SHColour INDIGO ;
static const SHColour LAVENDER ;
static const SHColour LIGHTBLUE ;
static const SHColour LIGHTGRAY ;
static const SHColour LIGHTGREEN ;
static const SHColour LIGHTPINK ;
static const SHColour LIGHTYELLOW ;
static const SHColour LIME ;
static const SHColour LIMEGREEN ;
static const SHColour MAGENTA ;
static const SHColour MAROON ;
static const SHColour MEDIUMBLUE ;
static const SHColour MEDIUMPURPLE;
static const SHColour NAVY ;
static const SHColour OLIVE ;
static const SHColour ORANGE ;
static const SHColour ORCHID ;
static const SHColour PINK ;
static const SHColour PURPLE ;
static const SHColour RED ;
static const SHColour ROYALBLUE ;
static const SHColour SALMON ;
static const SHColour SANDYBROWN ;
static const SHColour SILVER ;
static const SHColour SKYBLUE ;
static const SHColour SLATEGRAY ;
static const SHColour SNOW ;
static const SHColour STEELBLUE ;
static const SHColour TAN ;
static const SHColour TEAL ;
static const SHColour TURQUOISE ;
static const SHColour VIOLET ;
static const SHColour WHITE ;
static const SHColour YELLOW;
};
} // namespace SHADE

View File

@ -334,6 +334,39 @@ namespace SHADE
return ss.str();
}
bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept
{
XMVECTOR s, r, t;
const XMMATRIX M = XMLoadFloat4x4(this);
if (!XMMatrixDecompose(&s, &r, &t, M))
return false;
SHQuaternion orientation;
XMStoreFloat3(&scale, s);
XMStoreFloat4(&orientation, r);
XMStoreFloat3(&translation, t);
rotation = orientation.ToEuler();
return true;
}
bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept
{
XMVECTOR s, r, t;
const XMMATRIX M = XMLoadFloat4x4(this);
if (!XMMatrixDecompose(&s, &r, &t, M))
return false;
XMStoreFloat3(&scale, s);
XMStoreFloat4(&orientation, r);
XMStoreFloat3(&translation, t);
return true;
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */

View File

@ -16,7 +16,6 @@
// Project Headers
#include "SH_API.h"
#include "Vector/SHVec4.h"
#include "SH_API.h"
namespace SHADE
{
@ -25,7 +24,6 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
class SHVec2;
class SHVec3;
class SHVec4;
class SHQuaternion;
/*-----------------------------------------------------------------------------------*/
@ -109,6 +107,24 @@ namespace SHADE
[[nodiscard]] float Determinant () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
/**
* @brief Decomposes a transformation matrix into translation, euler angles and scale.
* @param[out] scale The scaling factor of the matrix.
* @param[out] rotation The euler angles of the matrix.
* @param[out] translation The translation of the matrix.
* @return True if decomposition was successful.
*/
bool Decompose (SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept;
/**
* @brief Decomposes a transformation matrix into translation, orientation and scale.
* @param[out] scale The scaling factor of the matrix.
* @param[out] orientation The orientation of the matrix.
* @param[out] translation The translation of the matrix.
* @return True if decomposition was successful.
*/
bool Decompose (SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/

View File

@ -67,6 +67,19 @@ namespace SHADE
XMStoreFloat4(this, XMQuaternionRotationMatrix(M));
}
SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
const SHVec3& SHADE_VEC{ rp3dEuler };
const XMVECTOR V = XMLoadFloat3(&SHADE_VEC);
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V));
}
SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept
: XMFLOAT4( rp3dQuat.x, rp3dQuat.y, rp3dQuat.z, rp3dQuat.w )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
@ -176,6 +189,16 @@ namespace SHADE
return XMQuaternionNotEqual(Q1, Q2);
}
SHQuaternion::operator reactphysics3d::Quaternion() const noexcept
{
return reactphysics3d::Quaternion{ x, y, z, w };
}
SHQuaternion::operator reactphysics3d::Vector3() const noexcept
{
return reactphysics3d::Vector3{ ToEuler() };
}
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
{
return rhs * lhs;

View File

@ -11,6 +11,8 @@
#pragma once
#include <DirectXMath.h>
#include <reactphysics3d/mathematics/Quaternion.h>
#include <string>
// Project Headers
@ -46,12 +48,17 @@ namespace SHADE
SHQuaternion (const SHQuaternion& rhs) = default;
SHQuaternion (SHQuaternion&& rhs) = default;
SHQuaternion () noexcept;
SHQuaternion (float x, float y, float z, float w) noexcept;
SHQuaternion (float yaw, float pitch, float roll) noexcept;
SHQuaternion (const SHVec3& eulerAngles) noexcept;
SHQuaternion (const SHVec3& axis, float angleInRad) noexcept;
SHQuaternion (const SHMatrix& rotationMatrix) noexcept;
SHQuaternion () noexcept;
SHQuaternion (float x, float y, float z, float w) noexcept;
SHQuaternion (float yaw, float pitch, float roll) noexcept;
SHQuaternion (const SHVec3& eulerAngles) noexcept;
SHQuaternion (const SHVec3& axis, float angleInRad) noexcept;
SHQuaternion (const SHMatrix& rotationMatrix) noexcept;
// Conversion from other math types
SHQuaternion (const reactphysics3d::Vector3& rp3dEuler) noexcept;
SHQuaternion (const reactphysics3d::Quaternion& rp3dQuat) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
@ -76,6 +83,11 @@ namespace SHADE
[[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept;
// Conversion to other math types used by SHADE
operator reactphysics3d::Quaternion () const noexcept;
operator reactphysics3d::Vector3 () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/

View File

@ -0,0 +1,60 @@
/****************************************************************************************
* \file SHRay.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Ray.
*
* \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 <SHpch.h>
// Primary Header
#include "SHRay.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHRay::SHRay() noexcept
: direction { 0.0f, 0.0f, 1.0f }
{}
SHRay::SHRay(const SHVec3& pos, const SHVec3& dir) noexcept
: position { pos }
, direction { dir }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHRay::operator==(const SHRay& rhs) noexcept
{
const XMVECTOR LHS_POS = XMLoadFloat3(&position);
const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position);
const XMVECTOR LHS_DIR = XMLoadFloat3(&direction);
const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction);
return XMVector3Equal(LHS_POS, RHS_POS) && XMVector3NotEqual(LHS_DIR, RHS_DIR);
}
bool SHRay::operator!=(const SHRay& rhs) noexcept
{
const XMVECTOR LHS_POS = XMLoadFloat3(&position);
const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position);
const XMVECTOR LHS_DIR = XMLoadFloat3(&direction);
const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction);
return XMVector3NotEqual(LHS_POS, RHS_POS) || XMVector3NotEqual(LHS_DIR, RHS_DIR);
}
} // namespace SHADE

View File

@ -0,0 +1,54 @@
/****************************************************************************************
* \file SHRay.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Ray.
*
* \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 <DirectXMath.h>
// Project Headers
#include "SH_API.h"
#include "Vector/SHVec3.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
struct SH_API SHRay
{
public:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 position;
SHVec3 direction;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHRay() noexcept;
SHRay(const SHVec3& pos, const SHVec3& dir) noexcept;
SHRay(const SHRay& rhs) noexcept = default;
SHRay(SHRay&& rhs) noexcept = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHRay& operator= (const SHRay& rhs) noexcept = default;
SHRay& operator= (SHRay&& rhs) noexcept = default;
[[nodiscard]] bool operator==(const SHRay& rhs) noexcept;
[[nodiscard]] bool operator!=(const SHRay& rhs) noexcept;
};
} // namespace SHADE

View File

@ -38,6 +38,10 @@ namespace SHADE
: XMFLOAT2( 0.0f, 0.0f )
{}
SHVec2::SHVec2(const XMFLOAT2& xmfloat2) noexcept
: XMFLOAT2 ( xmfloat2.x, xmfloat2.y )
{}
SHVec2::SHVec2(float n) noexcept
: XMFLOAT2( n, n )
{}
@ -46,10 +50,19 @@ namespace SHADE
: XMFLOAT2( _x, _y )
{}
SHVec2::SHVec2(const reactphysics3d::Vector2& rp3dVec2) noexcept
: XMFLOAT2( rp3dVec2.x, rp3dVec2.y )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec2::operator XMVECTOR() const noexcept
{
return XMLoadFloat2(this);
}
SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept
{
return *this = *this + rhs;
@ -83,22 +96,16 @@ namespace SHADE
SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorAdd(V1, V2));
XMStoreFloat2(&result, XMVectorAdd(*this, rhs));
return result;
}
SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorSubtract(V1, V2));
XMStoreFloat2(&result, XMVectorSubtract(*this, rhs));
return result;
}
@ -110,59 +117,43 @@ namespace SHADE
SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorMultiply(V1, V2));
XMStoreFloat2(&result, XMVectorMultiply(*this, rhs));
return result;
}
SHVec2 SHVec2::operator*(float rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, rhs));
XMStoreFloat2(&result, XMVectorScale(*this, rhs));
return result;
}
SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorDivide(V1, V2));
XMStoreFloat2(&result, XMVectorDivide(*this, rhs));
return result;
}
SHVec2 SHVec2::operator/(float rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, 1.0f / rhs));
XMStoreFloat2(&result, XMVectorScale(*this, 1.0f / rhs));
return result;
}
bool SHVec2::operator==(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2Equal(V1, V2);
return XMVector2Equal(*this, rhs);
}
bool SHVec2::operator!=(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2NotEqual(V1, V2);
return XMVector2NotEqual(*this, rhs);
}
float& SHVec2::operator[](int index)
@ -213,13 +204,16 @@ namespace SHADE
}
}
SHVec2::operator reactphysics3d::Vector2() const noexcept
{
return reactphysics3d::Vector2{ x, y };
}
SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorScale(V, lhs));
XMStoreFloat2(&result, XMVectorScale(rhs, lhs));
return result;
}
@ -229,16 +223,12 @@ namespace SHADE
float SHVec2::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat2(this);
return XMVectorGetX(XMVector2Length(V));
return XMVectorGetX(XMVector2Length(*this));
}
float SHVec2::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat2(this);
return XMVectorGetX(XMVector2LengthSq(V));
return XMVectorGetX(XMVector2LengthSq(*this));
}
std::string SHVec2::ToString() const noexcept
@ -251,20 +241,14 @@ namespace SHADE
float SHVec2::Dot(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2Dot(V1, V2));
return XMVectorGetX(XMVector2Dot(*this, rhs));
}
SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVector2Cross(V1, V2));
XMStoreFloat2(&result, XMVector2Cross(*this, rhs));
return result;
}
@ -276,9 +260,7 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&vec2);
XMStoreFloat2(&result, XMVector2Normalize(V));
XMStoreFloat2(&result, XMVector2Normalize(vec2));
return result;
}
@ -297,10 +279,10 @@ namespace SHADE
SHVec2 result;
XMVECTOR min = XMLoadFloat2(&(*vec2s.begin()));
XMVECTOR min = *vec2s.begin();
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat2(&(*it));
const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp);
}
@ -318,10 +300,10 @@ namespace SHADE
SHVec2 result;
XMVECTOR max = XMLoadFloat2(&(*vec2s.begin()));
XMVECTOR max = *vec2s.begin();
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat2(&(*it));
const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp);
}
@ -333,11 +315,7 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMVECTOR MIN = XMLoadFloat2(&vMin);
const XMVECTOR MAX = XMLoadFloat2(&vMax);
XMStoreFloat2(&result, XMVectorClamp(V, MIN, MAX));
XMStoreFloat2(&result, XMVectorClamp(v, vMin, vMax));
return result;
}
@ -345,10 +323,7 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(&a);
const XMVECTOR V2 = XMLoadFloat2(&b);
XMStoreFloat2(&result, XMVectorLerp(V1, V2, t));
XMStoreFloat2(&result, XMVectorLerp(a, b, t));
return result;
}
@ -369,10 +344,7 @@ namespace SHADE
float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat2(&lhs);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2AngleBetweenVectors(V1, V2));
return XMVectorGetX(XMVector2AngleBetweenVectors(lhs, rhs));
}
float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept
@ -384,11 +356,10 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR U = XMLoadFloat2(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat2(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
XMStoreFloat2(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result;
}
@ -396,10 +367,8 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMVECTOR N = XMLoadFloat2(&normal);
XMStoreFloat2(&result, XMVector2Reflect(V, N));
XMStoreFloat2(&result, XMVector2Reflect(v, normal));
return result;
}
@ -407,10 +376,9 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat2(&result, XMVector2Transform(V, R));
XMStoreFloat2(&result, XMVector2Transform(v, R));
return result;
}
@ -418,10 +386,9 @@ namespace SHADE
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat2(&result, XMVector2TransformCoord(V, TF));
XMStoreFloat2(&result, XMVector2TransformCoord(v, TF));
return result;
}

View File

@ -11,6 +11,8 @@
#pragma once
#include <DirectXMath.h>
#include <reactphysics3d/mathematics/Vector2.h>
#include <string>
#include <initializer_list>
@ -52,9 +54,14 @@ namespace SHADE
SHVec2 (SHVec2&& rhs) = default;
~SHVec2 () = default;
SHVec2 () noexcept;
SHVec2 (float n) noexcept;
SHVec2 (float x, float y) noexcept;
SHVec2 () noexcept;
SHVec2 (const XMFLOAT2& xmfloat2) noexcept;
SHVec2 (float n) noexcept;
SHVec2 (float x, float y) noexcept;
// Conversion from other math types to SHADE
SHVec2 (const reactphysics3d::Vector2& rp3dVec2) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
@ -63,6 +70,11 @@ namespace SHADE
SHVec2& operator= (const SHVec2& rhs) = default;
SHVec2& operator= (SHVec2&& rhs) = default;
// Conversion to other math types used by SHADE
operator DirectX::XMVECTOR () const noexcept;
operator reactphysics3d::Vector2 () const noexcept;
SHVec2& operator+= (const SHVec2& rhs) noexcept;
SHVec2& operator-= (const SHVec2& rhs) noexcept;
SHVec2& operator*= (const SHVec2& rhs) noexcept;
@ -86,6 +98,7 @@ namespace SHADE
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/

View File

@ -14,6 +14,7 @@
#include "SHVec3.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Math/SHQuaternion.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
@ -23,6 +24,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f };
SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f };
@ -43,6 +45,10 @@ namespace SHADE
: XMFLOAT3( 0.0f, 0.0f, 0.0f )
{}
SHVec3::SHVec3(const XMFLOAT3& xmfloat3) noexcept
: XMFLOAT3 ( xmfloat3.x, xmfloat3.y, xmfloat3.z )
{}
SHVec3::SHVec3(float n) noexcept
: XMFLOAT3( n, n, n )
{}
@ -51,10 +57,24 @@ namespace SHADE
: XMFLOAT3( _x, _y, _z )
{}
SHVec3::SHVec3(const reactphysics3d::Vector3& rp3dVec3) noexcept
: XMFLOAT3( rp3dVec3.x, rp3dVec3.y, rp3dVec3.z )
{}
SHVec3::SHVec3(const reactphysics3d::Quaternion& rp3dVec3) noexcept
: XMFLOAT3( SHQuaternion{rp3dVec3}.ToEuler() )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3::operator XMVECTOR() const noexcept
{
return XMLoadFloat3(this);
}
SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept
{
return *this = *this + rhs;
@ -88,22 +108,16 @@ namespace SHADE
SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorAdd(V1, V2));
XMStoreFloat3(&result, XMVectorAdd(*this, rhs));
return result;
}
SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorSubtract(V1, V2));
XMStoreFloat3(&result, XMVectorSubtract(*this, rhs));
return result;
}
@ -116,59 +130,43 @@ namespace SHADE
SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorMultiply(V1, V2));
XMStoreFloat3(&result, XMVectorMultiply(*this, rhs));
return result;
}
SHVec3 SHVec3::operator*(float rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, rhs));
XMStoreFloat3(&result, XMVectorScale(*this, rhs));
return result;
}
SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorDivide(V1, V2));
XMStoreFloat3(&result, XMVectorDivide(*this, rhs));
return result;
}
SHVec3 SHVec3::operator/(float rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, 1.0f / rhs));
XMStoreFloat3(&result, XMVectorScale(*this, 1.0f / rhs));
return result;
}
bool SHVec3::operator==(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3Equal(V1, V2);
return XMVector3Equal(*this, rhs);
}
bool SHVec3::operator!=(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3NotEqual(V1, V2);
return XMVector3NotEqual(*this, rhs);
}
float& SHVec3::operator[](int index)
@ -223,13 +221,21 @@ namespace SHADE
}
}
SHVec3::operator reactphysics3d::Vector3() const noexcept
{
return reactphysics3d::Vector3{ x, y , z };
}
SHVec3::operator reactphysics3d::Quaternion() const noexcept
{
return reactphysics3d::Quaternion::fromEulerAngles(x, y, z);
}
SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorScale(V, lhs));
XMStoreFloat3(&result, XMVectorScale(rhs, lhs));
return result;
}
@ -239,16 +245,12 @@ namespace SHADE
float SHVec3::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat3(this);
return XMVectorGetX(XMVector3Length(V));
return XMVectorGetX(XMVector3Length(*this));
}
float SHVec3::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat3(this);
return XMVectorGetX(XMVector3LengthSq(V));
return XMVectorGetX(XMVector3LengthSq(*this));
}
std::string SHVec3::ToString() const noexcept
@ -261,20 +263,14 @@ namespace SHADE
float SHVec3::Dot(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
return XMVectorGetX(XMVector3Dot(*this, rhs));
}
SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVector3Cross(V1, V2));
XMStoreFloat3(&result, XMVector3Cross(*this, rhs));
return result;
}
@ -286,9 +282,7 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
XMStoreFloat3(&result, XMVector3Normalize(V));
XMStoreFloat3(&result, XMVector3Normalize(v));
return result;
}
@ -307,10 +301,10 @@ namespace SHADE
SHVec3 result;
XMVECTOR min = XMLoadFloat3(&(*vs.begin()));
XMVECTOR min = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat3(&(*it));
const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp);
}
@ -328,10 +322,10 @@ namespace SHADE
SHVec3 result;
XMVECTOR max = XMLoadFloat3(&(*vs.begin()));
XMVECTOR max = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat3(&(*it));
const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp);
}
@ -343,11 +337,7 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR MIN = XMLoadFloat3(&vMin);
const XMVECTOR MAX = XMLoadFloat3(&vMax);
XMStoreFloat3(&result, XMVectorClamp(V, MIN, MAX));
XMStoreFloat3(&result, XMVectorClamp(v, vMin, vMax));
return result;
}
@ -355,10 +345,7 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(&a);
const XMVECTOR V2 = XMLoadFloat3(&b);
XMStoreFloat3(&result, XMVectorLerp(V1, V2, t));
XMStoreFloat3(&result, XMVectorLerp(a, b, t));
return result;
}
@ -382,7 +369,7 @@ namespace SHADE
const XMVECTOR V1 = XMLoadFloat3(&lhs);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2));
return XMVectorGetX(XMVector3AngleBetweenVectors(lhs, rhs));
}
float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept
@ -399,22 +386,18 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR U = XMLoadFloat3(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat3(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
XMStoreFloat3(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result;
}
SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR N = XMLoadFloat3(&normal);
XMStoreFloat3(&result, XMVector3Reflect(V, N));
XMStoreFloat3(&result, XMVector3Reflect(v, normal));
return result;
}
@ -422,12 +405,9 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR Q = XMQuaternionRotationAxis(axis, angleInRad);
const XMVECTOR AXIS = XMLoadFloat3(&axis);
const XMVECTOR Q = XMQuaternionRotationAxis(AXIS, angleInRad);
XMStoreFloat3(&result, XMVector3Rotate(V, Q));
XMStoreFloat3(&result, XMVector3Rotate(v, Q));
return result;
}
@ -435,10 +415,9 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationX(angleInRad);
const XMMATRIX R = XMMatrixRotationX(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result;
}
@ -446,10 +425,9 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationY(angleInRad);
const XMMATRIX R = XMMatrixRotationY(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result;
}
@ -457,10 +435,9 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result;
}
@ -468,10 +445,9 @@ namespace SHADE
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat3(&result, XMVector3TransformCoord(V, TF));
XMStoreFloat3(&result, XMVector3TransformCoord(v, TF));
return result;
}
}

View File

@ -11,6 +11,9 @@
#pragma once
#include <DirectXMath.h>
#include <reactphysics3d/mathematics/Vector3.h>
#include <reactphysics3d/mathematics/Quaternion.h>
#include <string>
#include <initializer_list>
@ -58,39 +61,50 @@ namespace SHADE
~SHVec3 () = default;
SHVec3 () noexcept;
SHVec3 (const XMFLOAT3& xmfloat3) noexcept;
SHVec3 (float n) noexcept;
SHVec3 (float x, float y, float z) noexcept;
// Conversion from other math types to SHADE
SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept;
SHVec3 (const reactphysics3d::Quaternion& rp3dVec3) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHVec3& operator= (const SHVec3& rhs) = default;
SHVec3& operator= (SHVec3&& rhs) = default;
SHVec3& operator= (const SHVec3& rhs) = default;
SHVec3& operator= (SHVec3&& rhs) = default;
SHVec3& operator+= (const SHVec3& rhs) noexcept;
SHVec3& operator-= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (float rhs) noexcept;
SHVec3& operator/= (const SHVec3& rhs) noexcept;
SHVec3& operator/= (float rhs) noexcept;
// Conversion to other math types used by SHADE
[[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- () const noexcept;
[[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (float rhs) const noexcept;
operator reactphysics3d::Vector3 () const noexcept;
operator reactphysics3d::Quaternion () const noexcept;
operator DirectX::XMVECTOR () const noexcept;
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept;
SHVec3& operator+= (const SHVec3& rhs) noexcept;
SHVec3& operator-= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (float rhs) noexcept;
SHVec3& operator/= (const SHVec3& rhs) noexcept;
SHVec3& operator/= (float rhs) noexcept;
[[nodiscard]] float& operator[] (int index);
[[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
[[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- () const noexcept;
[[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept;
[[nodiscard]] float& operator[] (int index);
[[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Function Members */

View File

@ -38,6 +38,10 @@ namespace SHADE
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f )
{}
SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept
: XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w )
{}
SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept
: XMFLOAT4( _x, _y, _z, _w )
{}
@ -46,6 +50,11 @@ namespace SHADE
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec4::operator XMVECTOR() const noexcept
{
return XMLoadFloat4(this);
}
SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept
{
return *this = *this + rhs;
@ -79,22 +88,16 @@ namespace SHADE
SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorAdd(V1, V2));
XMStoreFloat4(&result, XMVectorAdd(*this, rhs));
return result;
}
SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorSubtract(V1, V2));
XMStoreFloat4(&result, XMVectorSubtract(*this, rhs));
return result;
}
@ -106,59 +109,43 @@ namespace SHADE
SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorMultiply(V1, V2));
XMStoreFloat4(&result, XMVectorMultiply(*this, rhs));
return result;
}
SHVec4 SHVec4::operator*(float rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, rhs));
XMStoreFloat4(&result, XMVectorScale(*this, rhs));
return result;
}
SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorDivide(V1, V2));
XMStoreFloat4(&result, XMVectorDivide(*this, rhs));
return result;
}
SHVec4 SHVec4::operator/(float rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, 1.0f / rhs));
XMStoreFloat4(&result, XMVectorScale(*this, 1.0f / rhs));
return result;
}
bool SHVec4::operator==(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4Equal(V1, V2);
return XMVector4Equal(*this, rhs);
}
bool SHVec4::operator!=(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4NotEqual(V1, V2);
return XMVector4NotEqual(*this, rhs);
}
float& SHVec4::operator[](int index)
@ -220,10 +207,8 @@ namespace SHADE
SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorScale(V, lhs));
XMStoreFloat4(&result, XMVectorScale(rhs, lhs));
return result;
}
@ -233,30 +218,22 @@ namespace SHADE
float SHVec4::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector4Length(V));
return XMVectorGetX(XMVector4Length(*this));
}
float SHVec4::Length3D() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector3Length(V));
return XMVectorGetX(XMVector3Length(*this));
}
float SHVec4::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector4LengthSq(V));
return XMVectorGetX(XMVector4LengthSq(*this));
}
float SHVec4::LengthSquared3D() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector3LengthSq(V));
return XMVectorGetX(XMVector3LengthSq(*this));
}
std::string SHVec4::ToString() const noexcept
@ -269,28 +246,19 @@ namespace SHADE
float SHVec4::Dot(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4Dot(V1, V2));
return XMVectorGetX(XMVector4Dot(*this, rhs));
}
float SHVec4::Dot3D(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
return XMVectorGetX(XMVector3Dot(*this, rhs));
}
SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVector3Cross(V1, V2));
XMStoreFloat4(&result, XMVector3Cross(*this, rhs));
result.w = 1.0f;
return result;
}
@ -299,11 +267,7 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V3 = XMLoadFloat4(this);
const XMVECTOR V1 = XMLoadFloat4(&v1);
const XMVECTOR V2 = XMLoadFloat4(&v2);
XMStoreFloat4(&result, XMVector4Cross(V3, V1, V2));
XMStoreFloat4(&result, XMVector4Cross(*this, v1, v2));
return result;
}
@ -315,9 +279,7 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
XMStoreFloat4(&result, XMVector4Normalize(V));
XMStoreFloat4(&result, XMVector4Normalize(v));
return result;
}
@ -325,9 +287,7 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
XMStoreFloat4(&result, XMVector3Normalize(V));
XMStoreFloat4(&result, XMVector3Normalize(v));
result.w = 1.0f;
return result;
}
@ -347,10 +307,10 @@ namespace SHADE
SHVec4 result;
XMVECTOR min = XMLoadFloat4(&(*vs.begin()));
XMVECTOR min = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat4(&(*it));
const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp);
}
@ -368,10 +328,10 @@ namespace SHADE
SHVec4 result;
XMVECTOR max = XMLoadFloat4(&(*vs.begin()));
XMVECTOR max = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat4(&(*it));
const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp);
}
@ -383,11 +343,7 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR MIN = XMLoadFloat4(&vMin);
const XMVECTOR MAX = XMLoadFloat4(&vMax);
XMStoreFloat4(&result, XMVectorClamp(V, MIN, MAX));
XMStoreFloat4(&result, XMVectorClamp(v, vMin, vMax));
return result;
}
@ -395,10 +351,7 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(&a);
const XMVECTOR V2 = XMLoadFloat4(&b);
XMStoreFloat4(&result, XMVectorLerp(V1, V2, t));
XMStoreFloat4(&result, XMVectorLerp(a, b, t));
return result;
}
@ -429,18 +382,12 @@ namespace SHADE
float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat4(&lhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4AngleBetweenVectors(V1, V2));
return XMVectorGetX(XMVector4AngleBetweenVectors(lhs,rhs));
}
float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat4(&lhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2));
return XMVectorGetX(XMVector3AngleBetweenVectors(lhs,rhs));
}
float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept
@ -467,11 +414,10 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result;
}
@ -479,11 +425,10 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot3D(v, u);
const float U_LENSQ = u.LengthSquared3D();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
result.w = 1.0f;
return result;
}
@ -491,11 +436,8 @@ namespace SHADE
SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector4Reflect(V, N));
XMStoreFloat4(&result, XMVector4Reflect(v, normal));
result.w = 1.0f;
return result;
}
@ -503,11 +445,8 @@ namespace SHADE
SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector3Reflect(V, N));
XMStoreFloat4(&result, XMVector3Reflect(v, normal));
result.w = 1.0f;
return result;
}
@ -516,10 +455,9 @@ namespace SHADE
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat4(&result, XMVector3TransformCoord(V, TF));
XMStoreFloat4(&result, XMVector3TransformCoord(v, TF));
return result;
}
}

View File

@ -52,8 +52,9 @@ namespace SHADE
SHVec4 (SHVec4&& rhs) = default;
~SHVec4 () = default;
SHVec4 () noexcept;
SHVec4 (float x, float y, float z, float w) noexcept;
SHVec4 () noexcept;
SHVec4 (const XMFLOAT4& xmfloat4) noexcept;
SHVec4 (float x, float y, float z, float w) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
@ -62,6 +63,8 @@ namespace SHADE
SHVec4& operator= (const SHVec4& rhs) = default;
SHVec4& operator= (SHVec4&& rhs) = default;
operator DirectX::XMVECTOR () const noexcept;
SHVec4& operator+= (const SHVec4& rhs) noexcept;
SHVec4& operator-= (const SHVec4& rhs) noexcept;
SHVec4& operator*= (const SHVec4& rhs) noexcept;

View File

@ -15,6 +15,7 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/SHMathHelpers.h"
#include "Physics/SHPhysicsSystem.h"
namespace SHADE
@ -24,7 +25,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHColliderComponent::SHColliderComponent() noexcept
: system { nullptr }
: system { nullptr }
, colliders {}
{}
/*-----------------------------------------------------------------------------------*/
@ -87,12 +89,17 @@ namespace SHADE
system->RemoveCollider(GetEID());
}
SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept
SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept
{
const auto TYPE = SHCollider::Type::BOX;
const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true);
auto& collider = colliders.emplace_back(BOX_PAIR).first;
auto boxPair = std::make_pair(SHCollider{TYPE}, true);
auto& collider = colliders.emplace_back(boxPair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.SetPositionOffset(posOffset);
collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents);
if (!system)
{
@ -101,23 +108,37 @@ namespace SHADE
}
// Notify Physics System
system->AddCollisionShape(GetEID(), collider.GetShape());
system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
}
//void SHColliderComponent::AddSphere() noexcept
//{
// const auto TYPE = SHCollider::Type::SPHERE;
SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
{
const auto TYPE = SHCollider::Type::SPHERE;
// if (!system)
// {
// SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
// return;
// }
auto spherePair = std::make_pair(SHCollider{ TYPE }, true);
auto& collider = colliders.emplace_back(spherePair).first;
// // Notify Physics System
//}
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.SetPositionOffset(posOffset);
const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
collider.SetAsBoundingSphere(MAX_SCALE * 0.5f);
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
return nullptr;
}
// Notify Physics System
system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
}
void SHColliderComponent::RemoveCollider(int index)
{

View File

@ -15,6 +15,13 @@
// Project Headers
#include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHCollider.h"
#include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE
{
@ -30,6 +37,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHPhysicsObject;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
@ -76,10 +84,11 @@ namespace SHADE
void OnCreate () override;
void OnDestroy () override;
SHBoundingBox* AddBoundingBox () noexcept;
void RemoveCollider (int index);
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
private:
/*---------------------------------------------------------------------------------*/

View File

@ -392,9 +392,9 @@ RTTR_REGISTRATION
registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type")
(
value("Static", SHRigidBodyComponent::Type::STATIC),
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC),
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC)
value("Static", SHRigidBodyComponent::Type::STATIC),
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC),
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC)
);
registration::class_<SHRigidBodyComponent>("RigidBody Component")

View File

@ -14,7 +14,13 @@
// Project Headers
#include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHPhysicsObject.h"
#include "Math/Vector/SHVec3.h"
#include "Math/SHQuaternion.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE
{
@ -30,6 +36,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHPhysicsObject;
public:
/*---------------------------------------------------------------------------------*/
@ -137,6 +144,9 @@ namespace SHADE
/* Data Members */
/*---------------------------------------------------------------------------------*/
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
@ -162,10 +172,6 @@ namespace SHADE
SHVec3 position;
SHQuaternion orientation;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
RTTR_ENABLE()
};
} // namespace SHADE

View File

@ -12,6 +12,9 @@
// Primary Header
#include "SHCollider.h"
// Project Headers
#include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h"
namespace SHADE
{
@ -25,34 +28,41 @@ namespace SHADE
, dirty { true }
, shape { nullptr }
{
CreateShape();
switch (type)
{
case Type::BOX:
{
SetAsBoundingBox(SHVec3::One);
break;
}
case Type::SPHERE:
{
SetAsBoundingSphere(1.0f);
break;
}
default: break;
}
}
SHCollider::SHCollider(const SHCollider& rhs) noexcept
: type { rhs.type}
, isTrigger { rhs.isTrigger }
, dirty { true }
, shape { nullptr }
{
CreateShape();
// TODO(Diren): Copy transform data over
}
: type { rhs.type}
, isTrigger { rhs.isTrigger }
, dirty { true }
, shape { rhs.shape }
, positionOffset { rhs.positionOffset }
{}
SHCollider::SHCollider(SHCollider&& rhs) noexcept
: type { rhs.type}
, isTrigger { rhs.isTrigger }
, dirty { true }
, shape { nullptr }
{
CreateShape();
// TODO(Diren): Copy transform data over
}
: type { rhs.type}
, isTrigger { rhs.isTrigger }
, dirty { true }
, shape { rhs.shape }
, positionOffset { rhs.positionOffset }
{}
SHCollider::~SHCollider() noexcept
{
delete shape;
shape = nullptr;
}
/*-----------------------------------------------------------------------------------*/
@ -61,26 +71,25 @@ namespace SHADE
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
{
type = rhs.type;
isTrigger = rhs.isTrigger;
dirty = true;
CreateShape();
// TODO(Diren): Copy transform data over
if (this == &rhs)
return *this;
type = rhs.type;
isTrigger = rhs.isTrigger;
dirty = true;
shape = rhs.shape;
positionOffset = rhs.positionOffset;
return *this;
}
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{
type = rhs.type;
isTrigger = rhs.isTrigger;
dirty = true;
CreateShape();
// TODO(Diren): Copy transform data over
type = rhs.type;
isTrigger = rhs.isTrigger;
dirty = true;
shape = rhs.shape;
positionOffset = rhs.positionOffset;
return *this;
}
@ -104,11 +113,6 @@ namespace SHADE
return type;
}
SHShape* SHCollider::GetShape() const noexcept
{
return shape;
}
float SHCollider::GetFriction() const noexcept
{
// TODO(Diren): Fix after implementing materials
@ -126,36 +130,37 @@ namespace SHADE
return 0.0f;
}
SHVec3 SHCollider::GetPosition() const noexcept
{
// TODO(Diren): Fix after linking transform data
return SHVec3::Zero;
}
const SHVec3& SHCollider::GetPositionOffset() const noexcept
{
return positionOffset;
}
SHQuaternion SHCollider::GetOrientation() const noexcept
SHShape* SHCollider::GetShape() noexcept
{
// TODO(Diren): Fix after linking transform data
return SHQuaternion::Identity;
dirty = true;
return shape;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollider::SetType(Type newType) noexcept
void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents)
{
if (type == newType)
return;
dirty = true;
type = Type::BOX;
type = newType;
CreateShape();
delete shape;
shape = new SHBoundingBox{ positionOffset, halfExtents };
}
void SHCollider::SetAsBoundingSphere(float radius)
{
dirty = true;
type = Type::SPHERE;
delete shape;
shape = new SHBoundingSphere{ positionOffset, radius };
}
void SHCollider::SetIsTrigger(bool trigger) noexcept
@ -184,32 +189,21 @@ namespace SHADE
dirty = true;
positionOffset = posOffset;
}
} // namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
void SHCollider::CreateShape()
{
// Remove current shape
delete shape;
registration::enumeration<SHCollider::Type>("Collider Type")
(
value("Box", SHCollider::Type::BOX),
value("Sphere", SHCollider::Type::SPHERE)
// TODO(Diren): Add More Shapes
);
switch (type)
{
case Type::BOX: CreateBoundingBox(); break;
case Type::SPHERE: CreateSphere(); break;
default: break;
}
}
void SHCollider::CreateBoundingBox()
{
shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One };
}
void SHCollider::CreateSphere()
{
}
} // namespace SHADE
registration::class_<SHCollider>("Collider")
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
// TODO(Diren): Add Physics Materials
}

View File

@ -10,8 +10,10 @@
#pragma once
#include <rttr/registration>
// Project Headers
#include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h"
namespace SHADE
@ -32,15 +34,13 @@ namespace SHADE
BOX
, SPHERE
, CAPSULE
, CONVEX_HULL
, CONVEX_MESH
};
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHCollider (Type colliderType);
SHCollider (Type colliderType = Type::BOX);
SHCollider (const SHCollider& rhs) noexcept;
SHCollider (SHCollider&& rhs) noexcept;
@ -62,28 +62,28 @@ namespace SHADE
[[nodiscard]] bool IsTrigger () const noexcept;
[[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] SHShape* GetShape () const noexcept;
[[nodiscard]] float GetFriction () const noexcept;
[[nodiscard]] float GetBounciness () const noexcept;
[[nodiscard]] float GetDensity () const noexcept;
[[nodiscard]] SHVec3 GetPosition () const noexcept;
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
[[nodiscard]] SHShape* GetShape () noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetType (Type newType) noexcept;
void SetAsBoundingBox (const SHVec3& halfExtents);
void SetAsBoundingSphere (float radius);
void SetIsTrigger (bool isTrigger) noexcept;
void SetFriction (float friction) noexcept;
void SetBounciness (float bounciness) noexcept;
void SetDensity (float density) noexcept;
void SetIsTrigger (bool isTrigger) noexcept;
void SetFriction (float friction) noexcept;
void SetBounciness (float bounciness) noexcept;
void SetDensity (float density) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept;
private:
/*---------------------------------------------------------------------------------*/
@ -96,13 +96,7 @@ namespace SHADE
SHShape* shape;
SHVec3 positionOffset;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateShape ();
void CreateBoundingBox ();
void CreateSphere ();
RTTR_ENABLE()
};
} // namespace SHADE

View File

@ -15,7 +15,8 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHPhysicsSystem.h"
#include "ECS_Base/Managers/SHComponentManager.h"
namespace SHADE
{
@ -23,16 +24,20 @@ namespace SHADE
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject::SHPhysicsObject() noexcept
: entityID { MAX_EID }
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
: entityID { eid }
, isRigidBody { false }
, hasColliders{ false }
, factory { physicsFactory }
, world { physicsWorld }
, rp3dBody { nullptr }
{}
SHPhysicsObject::~SHPhysicsObject() noexcept
{
rp3dBody = nullptr;
factory = nullptr;
world = nullptr;
rp3dBody = nullptr;
}
/*-----------------------------------------------------------------------------------*/
@ -44,10 +49,7 @@ namespace SHADE
SHVec3 result;
if (rp3dBody)
{
const auto& RP3D_RESULT = rp3dBody->getTransform().getPosition();
result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z };
}
result = SHVec3{ rp3dBody->getTransform().getPosition() };
return result;
}
@ -57,10 +59,7 @@ namespace SHADE
SHQuaternion result;
if (rp3dBody)
{
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w };
}
result = SHQuaternion{ rp3dBody->getTransform().getOrientation() };
return result;
}
@ -70,10 +69,7 @@ namespace SHADE
SHVec3 result;
if (rp3dBody)
{
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }.ToEuler();
}
result = SHQuaternion{ rp3dBody->getTransform().getOrientation() }.ToEuler();
return result;
}
@ -84,10 +80,14 @@ namespace SHADE
void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept
{
const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z };
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set position of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(RP3D_POS);
rp3dTF.setPosition(position);
rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation());
rp3dBody->setTransform(rp3dTF);
@ -96,11 +96,15 @@ namespace SHADE
void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept
{
const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w };
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set orientation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(RP3D_ORIENTATION);
rp3dTF.setOrientation(orientation);
rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
@ -108,14 +112,253 @@ namespace SHADE
void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept
{
const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z );
if (!rp3dBody)
{
SHLOG_ERROR("Cannot set rotation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(RP3D_ORIENTATION);
rp3dTF.setOrientation(rotation);
rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c)
{
// If collider already exists, recreate the collision body as a rigid body
if (hasColliders)
world->destroyCollisionBody(rp3dBody);
rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
isRigidBody = true;
rb->position = tf->GetWorldPosition();
rb->orientation = tf->GetWorldRotation();
if (hasColliders)
{
c->position = tf->GetWorldPosition();
c->orientation = tf->GetWorldRotation();
// Get array of colliders and add them back into the rigidbody
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
}
void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c)
{
if (rp3dBody == nullptr)
rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
hasColliders = true;
c->position = tf->GetWorldPosition();
c->orientation = tf->GetWorldRotation();
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
int SHPhysicsObject::AddCollider(SHCollider* collider)
{
switch (collider->GetType())
{
case SHCollider::Type::BOX:
{
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
break;
}
case SHCollider::Type::SPHERE:
{
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
return static_cast<int>(rp3dBody->getNbColliders()) - 1;
}
void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept
{
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(rp3dBody));
if (hasColliders)
{
// Preserve colliders as a collision body
rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation });
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
isRigidBody = false;
}
void SHPhysicsObject::DestroyCollisionBody() noexcept
{
// Remove all colliders
for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i)
{
auto* collider = rp3dBody->getCollider(i);
rp3dBody->removeCollider(collider);
}
}
void SHPhysicsObject::RemoveCollider(int index)
{
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
if (NUM_COLLIDERS == 0)
return;
if (index < 0 || index >= NUM_COLLIDERS)
throw std::invalid_argument("Index out of range!");
auto* collider = rp3dBody->getCollider(index);
rp3dBody->removeCollider(collider);
}
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept
{
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
if (rb->dirtyFlags == 0)
return;
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
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<rp3d::BodyType>(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;
for (auto& [collider, dirty] : c->colliders)
{
if (!dirty)
continue;
// Update offsets
auto* rp3dCollider = rp3dBody->getCollider(index);
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
rp3dBoxShape->setHalfExtents(box->GetHalfExtents());
break;
}
case SHCollider::Type::SPHERE:
{
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
rp3dSphereShape->setRadius(sphere->GetRadius());
break;
}
default: break;
}
dirty = false;
++index;
}
}
} // namespace SHADE

View File

@ -13,9 +13,9 @@
#include <reactphysics3d/reactphysics3d.h>
// Project Headers
#include "Math/Vector/SHVec3.h"
#include "Math/SHQuaternion.h"
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h"
namespace SHADE
{
@ -31,15 +31,13 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHRigidBodyComponent;
friend class SHColliderComponent;
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHPhysicsObject () noexcept;
SHPhysicsObject (EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept;
SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default;
SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default;
virtual ~SHPhysicsObject () noexcept;
@ -63,9 +61,24 @@ namespace SHADE
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) noexcept;
void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c);
void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c);
int AddCollider (SHCollider* collider);
void DestroyRigidBody (SHColliderComponent* c) noexcept;
void RemoveCollider (int index);
void DestroyCollisionBody () noexcept;
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
void SyncColliders (SHColliderComponent* c) const noexcept;
private:
/*---------------------------------------------------------------------------------*/
@ -76,14 +89,9 @@ namespace SHADE
bool isRigidBody;
bool hasColliders;
rp3d::PhysicsCommon* factory;
rp3d::PhysicsWorld* world;
rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body
rp3d::Transform prevTransform; // Cached transform for interpolation
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
};
} // namespace SHADE

View File

@ -68,10 +68,7 @@ namespace SHADE
if (world)
{
const auto RP3D_GRAVITY = world->getGravity();
result.x = RP3D_GRAVITY.x;
result.y = RP3D_GRAVITY.y;
result.z = RP3D_GRAVITY.z;
result = world->getGravity();
}
else
{
@ -112,8 +109,7 @@ namespace SHADE
{
if (world)
{
const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z };
world->setGravity(G);
world->setGravity(gravity);
}
else
{
@ -161,8 +157,7 @@ namespace SHADE
{
if (world)
{
const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z };
world->setGravity(G);
world->setGravity(settings.gravity);
world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations);
world->setNbIterationsPositionSolver(settings.numPositionSolverIterations);
world->enableSleeping(settings.sleepingEnabled);
@ -203,138 +198,33 @@ namespace SHADE
void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept
{
#ifdef _DEBUG
SHLOG_INFO("Adding a Rigidbody to the Physics World.")
#endif
//#ifdef _DEBUG
// SHLOG_INFO("Adding a Rigidbody to the Physics World.")
//#endif
// Check if entity is already a physics object
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
auto* physicsObject = CreatePhysicsObject(entityID);
// Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Possibly redundant
if (!SHADE_TF)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
// If collider already exists
if (physicsObject->hasColliders)
world->destroyCollisionBody(physicsObject->rp3dBody);
physicsObject->rp3dBody = world->createRigidBody(RP3D_TF);
physicsObject->isRigidBody = true;
// Recreate colliders
if (physicsObject->hasColliders)
{
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
}
physicsObject->CreateRigidBody
(
EnsureTransform(entityID),
SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID),
SHComponentManager::GetComponent_s<SHColliderComponent>(entityID)
);
}
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept
{
#ifdef _DEBUG
SHLOG_INFO("Adding a Collider to the Physics World.")
#endif
//#ifdef _DEBUG
// SHLOG_INFO("Adding a Collider to the Physics World.")
//#endif
// Check if entity is already a physics object
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
auto* physicsObject = CreatePhysicsObject(entityID);
// Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Possibly redundant
if (!SHADE_TF)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
// No rb
if (!physicsObject->isRigidBody)
physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF);
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
physicsObject->hasColliders = true;
physicsObject->CreateCollisionBody
(
EnsureTransform(entityID),
SHComponentManager::GetComponent<SHColliderComponent>(entityID)
);
}
void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept
@ -343,6 +233,13 @@ namespace SHADE
SHLOG_INFO("Removing a Rigidbody from the Physics World.")
#endif
auto* physicsObject = GetPhysicsObject(entityID);
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s<SHColliderComponent>(entityID));
if (physicsObject->rp3dBody == nullptr)
DestroyPhysicsObject(entityID);
}
void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept
@ -392,33 +289,10 @@ namespace SHADE
}
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape)
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
{
auto* physicsObject = GetPhysicsObject(entityID);
switch (shape->GetType())
{
case SHShape::Type::BOUNDING_BOX:
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
rp3d::Transform tf = rp3d::Transform::identity();
physicsObject->rp3dBody->addCollider(newBox, tf);
break;
}
case SHShape::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
physicsObject->AddCollider(collider);
}
void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index)
@ -475,6 +349,7 @@ namespace SHADE
if (system->worldUpdated)
{
system->SyncTransforms();
// TODO(Diren): Handle trigger messages for scripting
}
}
@ -483,18 +358,43 @@ namespace SHADE
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept
{
const auto it = map.find(entityID);
if (it == map.end())
{
auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second;
return newPhysicsObject;
}
return &(it->second);
}
SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept
{
const auto it = map.find(entityID);
if (it == map.end())
{
SHLOG_ERROR("Entity {} is not in the physics system!", entityID)
//SHLOG_ERROR("Entity {} is not in the physics system!", entityID)
return nullptr;
}
return &(it->second);
}
void SHPhysicsSystem::DestroyPhysicsObject(EntityID entityID) noexcept
{
map.erase(entityID);
}
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
{
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
if (RP3D_ACTIVE != componentActive)
physicsObject->rp3dBody->setIsActive(componentActive);
}
void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept
{
if (denseArray.empty())
@ -505,23 +405,16 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
if (comp.dirtyFlags > 0)
{
SyncRigidBody(physicsObject, &comp);
comp.dirtyFlags = 0;
}
physicsObject->SyncRigidBody(&comp);
}
}
@ -535,29 +428,23 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
SyncCollider(physicsObject, &comp);
physicsObject->SyncColliders(&comp);
}
}
void SHPhysicsSystem::SyncTransforms() noexcept
{
for (auto& pair : map)
for (auto& [entityID, physicsObject] : map)
{
const EntityID ENTITY_ID = pair.first;
SHPhysicsObject& physicsObject = pair.second;
rp3d::Vector3 rp3dPos;
rp3d::Quaternion rp3dRot;
@ -567,7 +454,7 @@ namespace SHADE
if (physicsObject.isRigidBody)
{
auto const* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(ENTITY_ID);
auto* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID);
if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
continue;
@ -585,6 +472,16 @@ namespace SHADE
rp3dPos = CURRENT_TF.getPosition();
rp3dRot = CURRENT_TF.getOrientation();
}
rbComponent->position = CURRENT_TF.getPosition();
rbComponent->orientation = CURRENT_TF.getOrientation();
if (physicsObject.hasColliders)
{
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
}
else
{
@ -593,155 +490,29 @@ namespace SHADE
}
// Convert RP3D Transform to SHADE
const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z };
const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler();
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
tfComponent->SetWorldPosition(rp3dPos);
tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler());
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(ENTITY_ID);
tfComponent->SetWorldPosition(SHADE_POS);
tfComponent->SetWorldRotation(SHADE_ROT);
// Cache transforms
physicsObject.prevTransform = CURRENT_TF;
}
}
void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept
SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID)
{
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody);
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
const uint16_t RB_FLAGS = comp->dirtyFlags;
const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U;
for (size_t i = 0; i < NUM_FLAGS; ++i)
// Possibly redundant
if (!tf)
{
// Check if current dirty flag has been set to true
if (RB_FLAGS & 1U << i)
{
switch (i)
{
case 0: // Gravity
{
rigidBody->enableGravity(comp->IsGravityEnabled());
break;
}
case 1: // Sleeping
{
rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep());
break;
}
case 2: // Linear Constraints
{
SetRP3DLinearConstraints(rigidBody, comp->flags);
break;
}
case 3: // Angular Constraints
{
SetRP3DAngularConstraints(rigidBody, comp->flags);
break;
}
case 4: // Type
{
rigidBody->setType(static_cast<rp3d::BodyType>(comp->GetType()));
break;
}
case 5: // Mass
{
rigidBody->setMass(comp->GetMass());
break;
}
case 6: // Drag
{
rigidBody->setLinearDamping(comp->GetDrag());
break;
}
case 7: // Angular Drag
{
rigidBody->setAngularDamping(comp->GetAngularDrag());
break;
}
case 8: // Linear Velocity
{
const SHVec3& SHADE_VEL = comp->GetLinearVelocity();
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
rigidBody->setLinearVelocity(RP3D_VEL);
break;
}
case 9: // Angular Velocity
{
const SHVec3& SHADE_VEL = comp->GetAngularVelocity();
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
rigidBody->setAngularVelocity(RP3D_VEL);
break;
}
default: break;
}
}
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
tf = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
return tf;
}
void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
{
const rp3d::Vector3 CONSTRAINTS
{
rbFlags & 1U << 2 ? 0.0f : 1.0f,
rbFlags & 1U << 3 ? 0.0f : 1.0f,
rbFlags & 1U << 4 ? 0.0f : 1.0f
};
rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS);
}
void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
{
const rp3d::Vector3 CONSTRAINTS
{
rbFlags & 1U << 5 ? 0.0f : 1.0f,
rbFlags & 1U << 6 ? 0.0f : 1.0f,
rbFlags & 1U << 7 ? 0.0f : 1.0f
};
rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS);
}
void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept
{
int index = 0;
for (auto& [collider, dirty] : comp->colliders)
{
if (!dirty)
continue;
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(physicsObject->rp3dBody->getCollider(index)->getCollisionShape());
rp3dBoxShape->setHalfExtents(RP3D_EXTENTS);
if (rp3dBoxShape)
{
SHLOG_INFO("Updating box things")
}
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
default: break;
}
dirty = false;
++index;
}
}
} // namespace SHADE

View File

@ -19,6 +19,7 @@
#include "SHPhysicsObject.h"
#include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h"
#include "ECS_Base/System/SHSystemRoutine.h"
@ -81,8 +82,8 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
void Init () override;
void Exit () override;
void Init () override;
void Exit () override;
void AddRigidBody (EntityID entityID) noexcept;
void AddCollider (EntityID entityID) noexcept;
@ -100,7 +101,7 @@ namespace SHADE
void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept;
void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept;
void AddCollisionShape (EntityID entityID, SHShape* shape);
void AddCollisionShape (EntityID entityID, SHCollider* collider);
void RemoveCollisionShape (EntityID entityID, int index);
/*---------------------------------------------------------------------------------*/
@ -185,18 +186,18 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void DestroyPhysicsObject (EntityID entityID) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
// TODO(Diren): Trigger handling
static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept;
static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept;
// TODO(Diren): Remove when responsibility shifted to editor
SHTransformComponent* EnsureTransform (EntityID entityID);
};

View File

@ -571,9 +571,9 @@ namespace SHADE
{
SHSceneNode* newNode = new SHSceneNode{entityID};
#ifdef _DEBUG
SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
#endif
//#ifdef _DEBUG
// SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
//#endif
entityNodeMap.emplace(entityID, newNode);
return newNode;

View File

@ -30,8 +30,9 @@ project "SHADE_Managed"
"%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}",
"%{IncludeDir.yamlcpp}",
"%{IncludeDir.RTTR}/include",
"%{IncludeDir.RTTR}/include",
"%{IncludeDir.dotnet}\\include",
"%{IncludeDir.reactphysics3d}\\include",
"%{wks.location}/SHADE_Engine/src"
}

View File

@ -22,6 +22,7 @@ layout(location = 0) in struct
layout(location = 2) flat in struct
{
int materialIndex;
uint eid;
} In2;
//layout (set = 0, binding = )
@ -33,12 +34,13 @@ layout (set = 3, binding = 0) buffer MaterialProperties // For materials
} MatProp;
layout(location = 0) out vec4 outColor;
layout(location = 1) out uint outEntityID;
void main()
{
outColor = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) +
MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha;
outEntityID = In2.eid;
//outColor = vec4 (1.0f);
}

Binary file not shown.

View File

@ -8,6 +8,7 @@ layout(location = 1) in vec2 aUV;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aTangent;
layout(location = 4) in mat4 worldTransform;
layout(location = 8) in uint eid;
layout(location = 0) out struct
@ -21,6 +22,8 @@ layout(location = 0) out struct
layout(location = 2) out struct
{
int materialIndex;
uint eid;
} Out2;
layout(set = 2, binding = 0) uniform CameraData
@ -33,6 +36,7 @@ void main()
{
Out.uv = aUV;
Out2.materialIndex = gl_InstanceIndex;
Out2.eid = eid;
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
Out.vertColor = vec4 (aVertexPos, 1.0f);
}

Binary file not shown.