From a8b950f3db772c3c0b88e84d9dcf6988f02b3dd0 Mon Sep 17 00:00:00 2001 From: Ruben Tytgat Date: Mon, 2 Dec 2024 18:08:13 +0100 Subject: [PATCH] Collider AABBs, debug camera inspector --- CHANGELOG.md | 5 ++ CMakeLists.txt | 2 +- sdks/miller-sdk | 2 +- sdks/rangers-sdk | 2 +- sdks/wars-sdk | 2 +- src/ui/ToolBar.cpp | 28 +++++++ src/utilities/BoundingBoxes.cpp | 133 +++++++++++++++++++++++++------- src/utilities/BoundingBoxes.h | 4 + 8 files changed, 147 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bf1b83..a0d0517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.1.58 +* Added panel that allows direct editing of debug camera parameters. +* Selection box now also works for box, cylinder and capsule colliders. + + # v0.1.57 * Fixed a bug in object placement introduced in the previous version. diff --git a/CMakeLists.txt b/CMakeLists.txt index 10b2b69..20bbb64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.28) # DevTools -project(devtools VERSION 0.1.57 +project(devtools VERSION 0.1.58 DESCRIPTION "Hedgehog Engine 2 DevTools" LANGUAGES CXX) diff --git a/sdks/miller-sdk b/sdks/miller-sdk index 4a0288e..4d843de 160000 --- a/sdks/miller-sdk +++ b/sdks/miller-sdk @@ -1 +1 @@ -Subproject commit 4a0288ee77db33ad5633ad6f8f05c7c5b62498d4 +Subproject commit 4d843de80772d34de9942dbb49143dc02d78c29f diff --git a/sdks/rangers-sdk b/sdks/rangers-sdk index 357f467..3adddd9 160000 --- a/sdks/rangers-sdk +++ b/sdks/rangers-sdk @@ -1 +1 @@ -Subproject commit 357f467ed87bce3be530621517d750a22c7aec00 +Subproject commit 3adddd91840de4abe1512b24a05c028480f9b2b9 diff --git a/sdks/wars-sdk b/sdks/wars-sdk index 4d00f3e..2b40d47 160000 --- a/sdks/wars-sdk +++ b/sdks/wars-sdk @@ -1 +1 @@ -Subproject commit 4d00f3ebc208bdc37e2d039cb370dc0ec717c6a6 +Subproject commit 2b40d4704ae179de04c3f6306cbc9a8d8961d5c8 diff --git a/src/ui/ToolBar.cpp b/src/ui/ToolBar.cpp index 7c8c049..46929c1 100644 --- a/src/ui/ToolBar.cpp +++ b/src/ui/ToolBar.cpp @@ -1,6 +1,7 @@ #include "ToolBar.h" #include #include +#include #include "Desktop.h" #include "SettingsManager.h" #include "GlobalSettings.h" @@ -188,11 +189,38 @@ void ToolBar::Render() { bool tempDebugCameraLocked{ debugCameraLocked }; ImGui::Checkbox("Lock debug camera position", &tempDebugCameraLocked); + ImGui::SameLine(); if (debugCameraLocked != tempDebugCameraLocked) debugCameraMgr->GetCamera()->SetLocked(tempDebugCameraLocked); + static bool showCameraInfo{}; + ImGui::Checkbox("Show camera information", &showCameraInfo); ImGui::SameLine(); + + if (showCameraInfo) { +#ifdef DEVTOOLS_TARGET_SDK_wars + auto& camCtrl = *((hh::game::FreeCameraController*)&*debugCameraMgr->GetCamera()->controller); +#else + auto& camCtrl = *((hh::game::DefaultFreeCameraController*)&*debugCameraMgr->GetCamera()->controller)->padController; +#endif + if (ImGui::Begin("Debug camera options")) { + Editor("Origin / reset position", camCtrl.unk3.camera.origin); + Editor("Position offset", camCtrl.unk3.camera.position); + Editor("Yaw", camCtrl.unk3.camera.yaw); + Editor("Pitch", camCtrl.unk3.camera.pitch); + Editor("Roll", camCtrl.unk3.camera.roll); + Editor("Zoom", camCtrl.unk3.camera.zoom); + Editor("Near clip", camCtrl.unk3.viewport.nearClip); + Editor("Far clip", camCtrl.unk3.viewport.farClip); + Editor("Field of view", camCtrl.unk3.viewport.fov); + ImGui::Separator(); + Editor("Current speed", camCtrl.currentSpeed); + Editor("Speed options", camCtrl.speedOptions); + Editor("Current speed option index", camCtrl.currentSpeedOptionIdx); + } + ImGui::End(); + } } ImGui::Checkbox("Render debug visuals", &GOCVisualDebugDrawRenderer::instance->enabled); diff --git a/src/utilities/BoundingBoxes.cpp b/src/utilities/BoundingBoxes.cpp index 10d7934..b3a1dee 100644 --- a/src/utilities/BoundingBoxes.cpp +++ b/src/utilities/BoundingBoxes.cpp @@ -2,12 +2,7 @@ bool AddToAabb(hh::game::GameObject* object, csl::geom::Aabb& aabb) { if (auto* visual = object->GetComponent()) { - aabb.min.x() = std::fminf(aabb.min.x(), visual->transformedAabb.min.x()); - aabb.min.y() = std::fminf(aabb.min.y(), visual->transformedAabb.min.y()); - aabb.min.z() = std::fminf(aabb.min.z(), visual->transformedAabb.min.z()); - aabb.max.x() = std::fmaxf(aabb.max.x(), visual->transformedAabb.max.x()); - aabb.max.y() = std::fmaxf(aabb.max.y(), visual->transformedAabb.max.y()); - aabb.max.z() = std::fmaxf(aabb.max.z(), visual->transformedAabb.max.z()); + AddAabb(aabb, visual->transformedAabb); return true; } @@ -16,9 +11,25 @@ bool AddToAabb(hh::game::GameObject* object, csl::geom::Aabb& aabb) { for (auto* component : object->components) { if (component->pStaticClass == hh::physics::GOCSphereCollider::GetClass()) { - auto* coll = static_cast(component); - tempAabb.min = coll->GetWorldTransform() * Eigen::Vector3f{ -coll->radius, -coll->radius, -coll->radius }; - tempAabb.max = coll->GetWorldTransform() * Eigen::Vector3f{ coll->radius, coll->radius, coll->radius }; + tempAabb = CalcAabb(*static_cast(component)); + colliderCount++; + if (colliderCount > 1) + break; + } + if (component->pStaticClass == hh::physics::GOCBoxCollider::GetClass()) { + tempAabb = CalcAabb(*static_cast(component)); + colliderCount++; + if (colliderCount > 1) + break; + } + if (component->pStaticClass == hh::physics::GOCCylinderCollider::GetClass()) { + tempAabb = CalcAabb(*static_cast(component)); + colliderCount++; + if (colliderCount > 1) + break; + } + if (component->pStaticClass == hh::physics::GOCCapsuleCollider::GetClass()) { + tempAabb = CalcAabb(*static_cast(component)); colliderCount++; if (colliderCount > 1) break; @@ -26,22 +37,12 @@ bool AddToAabb(hh::game::GameObject* object, csl::geom::Aabb& aabb) { } if (colliderCount == 1) { - aabb.min.x() = std::fminf(aabb.min.x(), tempAabb.min.x()); - aabb.min.y() = std::fminf(aabb.min.y(), tempAabb.min.y()); - aabb.min.z() = std::fminf(aabb.min.z(), tempAabb.min.z()); - aabb.max.x() = std::fmaxf(aabb.max.x(), tempAabb.max.x()); - aabb.max.y() = std::fmaxf(aabb.max.y(), tempAabb.max.y()); - aabb.max.z() = std::fmaxf(aabb.max.z(), tempAabb.max.z()); + AddAabb(aabb, tempAabb); return true; } if (auto* gocTransform = object->GetComponent()) { - aabb.min.x() = std::fminf(aabb.min.x(), gocTransform->GetFrame().fullTransform.position.x()); - aabb.min.y() = std::fminf(aabb.min.y(), gocTransform->GetFrame().fullTransform.position.y()); - aabb.min.z() = std::fminf(aabb.min.z(), gocTransform->GetFrame().fullTransform.position.z()); - aabb.max.x() = std::fmaxf(aabb.max.x(), gocTransform->GetFrame().fullTransform.position.x()); - aabb.max.y() = std::fmaxf(aabb.max.y(), gocTransform->GetFrame().fullTransform.position.y()); - aabb.max.z() = std::fmaxf(aabb.max.z(), gocTransform->GetFrame().fullTransform.position.z()); + aabb.AddPoint(gocTransform->GetFrame().fullTransform.position); return true; } @@ -49,12 +50,7 @@ bool AddToAabb(hh::game::GameObject* object, csl::geom::Aabb& aabb) { } bool AddToAabb(hh::game::ObjectData* objectData, csl::geom::Aabb& aabb) { - aabb.min.x() = std::fminf(aabb.min.x(), objectData->transform.position.x()); - aabb.min.y() = std::fminf(aabb.min.y(), objectData->transform.position.y()); - aabb.min.z() = std::fminf(aabb.min.z(), objectData->transform.position.z()); - aabb.max.x() = std::fmaxf(aabb.max.x(), objectData->transform.position.x()); - aabb.max.y() = std::fmaxf(aabb.max.y(), objectData->transform.position.y()); - aabb.max.z() = std::fmaxf(aabb.max.z(), objectData->transform.position.z()); + aabb.AddPoint(objectData->transform.position); return true; } @@ -139,3 +135,86 @@ csl::geom::Aabb CalcAabb(const csl::geom::Obb& obb) return res; } + +csl::geom::Aabb CalcAabb(const hh::physics::GOCSphereCollider& coll) { + auto tf = coll.GetWorldTransform(); + + Eigen::Matrix3f rot; + Eigen::Matrix3f scale; + + tf.computeRotationScaling(&rot, &scale); + + Eigen::Affine3f transform{}; + transform.fromPositionOrientationScale(tf.translation(), Eigen::Quaternionf::Identity(), scale.diagonal()); + + return { + transform * Eigen::Vector3f{ -coll.radius, -coll.radius, -coll.radius }, + transform * Eigen::Vector3f{ coll.radius, coll.radius, coll.radius }, + }; +} + +csl::geom::Aabb CalcAabb(const hh::physics::GOCBoxCollider& coll) { + auto tf = coll.GetWorldTransform(); + + csl::math::Vector3 corners[8]{ + tf * csl::math::Vector3{ -coll.dimensions.x(), -coll.dimensions.y(), -coll.dimensions.z() }, + tf * csl::math::Vector3{ -coll.dimensions.x(), -coll.dimensions.y(), coll.dimensions.z() }, + tf * csl::math::Vector3{ -coll.dimensions.x(), coll.dimensions.y(), -coll.dimensions.z() }, + tf * csl::math::Vector3{ coll.dimensions.x(), -coll.dimensions.y(), -coll.dimensions.z() }, + tf * csl::math::Vector3{ coll.dimensions.x(), coll.dimensions.y(), -coll.dimensions.z() }, + tf * csl::math::Vector3{ coll.dimensions.x(), -coll.dimensions.y(), coll.dimensions.z() }, + tf * csl::math::Vector3{ -coll.dimensions.x(), coll.dimensions.y(), coll.dimensions.z() }, + tf * csl::math::Vector3{ coll.dimensions.x(), coll.dimensions.y(), coll.dimensions.z() }, + }; + + csl::geom::Aabb res{ { INFINITY, INFINITY, INFINITY }, { -INFINITY, -INFINITY, -INFINITY } }; + + for (size_t i = 0; i < 8; i++) + res.AddPoint(corners[i]); + + return res; +} + +csl::geom::Aabb CalcAabb(const hh::physics::GOCCylinderCollider& coll) { + auto tf = coll.GetWorldTransform(); + + csl::math::Vector3 corners[8]{ + tf * csl::math::Vector3{ -coll.radius, -coll.halfHeight, -coll.radius }, + tf * csl::math::Vector3{ -coll.radius, -coll.halfHeight, coll.radius }, + tf * csl::math::Vector3{ -coll.radius, coll.halfHeight, -coll.radius }, + tf * csl::math::Vector3{ coll.radius, -coll.halfHeight, -coll.radius }, + tf * csl::math::Vector3{ coll.radius, coll.halfHeight, -coll.radius }, + tf * csl::math::Vector3{ coll.radius, -coll.halfHeight, coll.radius }, + tf * csl::math::Vector3{ -coll.radius, coll.halfHeight, coll.radius }, + tf * csl::math::Vector3{ coll.radius, coll.halfHeight, coll.radius }, + }; + + csl::geom::Aabb res{ { INFINITY, INFINITY, INFINITY }, { -INFINITY, -INFINITY, -INFINITY } }; + + for (size_t i = 0; i < 8; i++) + res.AddPoint(corners[i]); + + return res; +} + +csl::geom::Aabb CalcAabb(const hh::physics::GOCCapsuleCollider& coll) { + auto tf = coll.GetWorldTransform(); + + csl::math::Vector3 corners[8]{ + tf * csl::math::Vector3{ -coll.radius, -(coll.halfHeight + coll.radius), -coll.radius }, + tf * csl::math::Vector3{ -coll.radius, -(coll.halfHeight + coll.radius), coll.radius }, + tf * csl::math::Vector3{ -coll.radius, (coll.halfHeight + coll.radius), -coll.radius }, + tf * csl::math::Vector3{ coll.radius, -(coll.halfHeight + coll.radius), -coll.radius }, + tf * csl::math::Vector3{ coll.radius, (coll.halfHeight + coll.radius), -coll.radius }, + tf * csl::math::Vector3{ coll.radius, -(coll.halfHeight + coll.radius), coll.radius }, + tf * csl::math::Vector3{ -coll.radius, (coll.halfHeight + coll.radius), coll.radius }, + tf * csl::math::Vector3{ coll.radius, (coll.halfHeight + coll.radius), coll.radius }, + }; + + csl::geom::Aabb res{ { INFINITY, INFINITY, INFINITY }, { -INFINITY, -INFINITY, -INFINITY } }; + + for (size_t i = 0; i < 8; i++) + res.AddPoint(corners[i]); + + return res; +} diff --git a/src/utilities/BoundingBoxes.h b/src/utilities/BoundingBoxes.h index 0dfa100..9ee5a21 100644 --- a/src/utilities/BoundingBoxes.h +++ b/src/utilities/BoundingBoxes.h @@ -9,3 +9,7 @@ csl::geom::Aabb Union(const csl::geom::Aabb& one, const csl::geom::Aabb& other); csl::geom::Aabb CalcAabb(const csl::geom::Sphere& sphere); csl::geom::Aabb CalcAabb(const csl::geom::Cylinder& sphere); csl::geom::Aabb CalcAabb(const csl::geom::Obb& sphere); +csl::geom::Aabb CalcAabb(const hh::physics::GOCSphereCollider& coll); +csl::geom::Aabb CalcAabb(const hh::physics::GOCBoxCollider& coll); +csl::geom::Aabb CalcAabb(const hh::physics::GOCCylinderCollider& coll); +csl::geom::Aabb CalcAabb(const hh::physics::GOCCapsuleCollider& coll);