From b06098e4c7bbb39186a2eced08bf7f338d310042 Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sat, 17 May 2025 22:44:43 +0200 Subject: [PATCH] feat(renderer): added aabb selection outline --- assets/shaders/outline.vs | 2 +- core/src/math_helper.cpp | 17 +++++++++++++++++ core/src/math_helper.h | 5 ++++- core/src/rendering/renderer.cpp | 30 +++++++++++++++++++++++++++++- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/assets/shaders/outline.vs b/assets/shaders/outline.vs index e3eeb5b..2a4540c 100644 --- a/assets/shaders/outline.vs +++ b/assets/shaders/outline.vs @@ -9,10 +9,10 @@ uniform mat4 model; uniform mat4 view; uniform mat4 projection; uniform vec3 scale; +uniform float thickness; void main() { - float thickness = 0.4; vec3 distFromEdge = sign(aPos) * 0.5 - aPos; vec3 tVec = (scale * sign(aPos) * 0.5 - distFromEdge * thickness) / scale; diff --git a/core/src/math_helper.cpp b/core/src/math_helper.cpp index 3d8a4b3..384d95e 100644 --- a/core/src/math_helper.cpp +++ b/core/src/math_helper.cpp @@ -100,4 +100,21 @@ void get_closest_points_between_segments(const glm::vec3 &p_p0, const glm::vec3 r_ps = (1 - s) * p_p0 + s * p_p1; r_qt = (1 - t) * p_q0 + t * p_q1; +} + +void expandAABB(glm::vec3& min, glm::vec3& max, glm::vec3 point) { + min = glm::vec3(glm::min(min.x, point.x), glm::min(min.y, point.y), glm::min(min.z, point.z)); + max = glm::vec3(glm::max(max.x, point.x), glm::max(max.y, point.y), glm::max(max.z, point.z)); +} + +void computeAABBFromPoints(glm::vec3& min, glm::vec3& max, glm::vec3* points, int count) { + if (count == 0) return; + + min = points[0]; + max = points[0]; + + for (int i = 0; i < count; i++) { + min = glm::vec3(glm::min(min.x, points[i].x), glm::min(min.y, points[i].y), glm::min(min.z, points[i].z)); + max = glm::vec3(glm::max(max.x, points[i].x), glm::max(max.y, points[i].y), glm::max(max.z, points[i].z)); + } } \ No newline at end of file diff --git a/core/src/math_helper.h b/core/src/math_helper.h index 65c316c..7f8f6cc 100644 --- a/core/src/math_helper.h +++ b/core/src/math_helper.h @@ -2,4 +2,7 @@ #include // From godot/editor/plugins/gizmos/gizmo_3d_helper.h -void get_closest_points_between_segments(const glm::vec3 &p_p0, const glm::vec3 &p_p1, const glm::vec3 &p_q0, const glm::vec3 &p_q1, glm::vec3 &r_ps, glm::vec3 &r_qt); \ No newline at end of file +void get_closest_points_between_segments(const glm::vec3 &p_p0, const glm::vec3 &p_p1, const glm::vec3 &p_q0, const glm::vec3 &p_q1, glm::vec3 &r_ps, glm::vec3 &r_qt); + +void expandAABB(glm::vec3& min, glm::vec3& max, glm::vec3 point); +void computeAABBFromPoints(glm::vec3& min, glm::vec3& max, glm::vec3* points, int count); \ No newline at end of file diff --git a/core/src/rendering/renderer.cpp b/core/src/rendering/renderer.cpp index eb6ed3c..77e168a 100644 --- a/core/src/rendering/renderer.cpp +++ b/core/src/rendering/renderer.cpp @@ -17,6 +17,7 @@ #include "datatypes/cframe.h" #include "datatypes/color3.h" #include "handles.h" +#include "math_helper.h" #include "rendering/torus.h" #include "shader.h" #include "mesh.h" @@ -437,16 +438,27 @@ void renderOutlines() { // Pass in the camera position outlineShader->set("viewPos", camera.cameraPos); + outlineShader->set("thickness", 0.4f); // outlineShader->set("color", glm::vec3(1.f, 0.f, 0.f)); - // Sort by nearest + glm::vec3 min, max; + bool first = true; + for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { InstanceRef inst = *it; if (inst->GetClass() != &Part::TYPE) continue; std::shared_ptr part = std::dynamic_pointer_cast(inst); if (!part->selected) continue; + if (first) + min = part->position(), max = part->position(); + first = false; + + Vector3 aabbSize = part->GetAABB(); + expandAABB(min, max, part->position() - aabbSize / 2.f); + expandAABB(min, max, part->position() + aabbSize / 2.f); + glm::mat4 model = part->cframe; model = glm::scale(model, (glm::vec3)part->size + glm::vec3(0.2)); outlineShader->set("model", model); @@ -455,6 +467,22 @@ void renderOutlines() { OUTLINE_MESH->bind(); glDrawArrays(GL_TRIANGLES, 0, OUTLINE_MESH->vertexCount); } + + // Render AABB of selected parts + if (first) return; + + glm::vec3 outlineSize, outlinePos; + outlineSize = (max - min); + outlinePos = (max + min) / 2.f; + + glm::mat4 model = glm::translate(glm::mat4(1.0f), outlinePos); + model = glm::scale(model, outlineSize + glm::vec3(0.1)); + outlineShader->set("model", model); + outlineShader->set("scale", outlineSize + glm::vec3(0.05)); + outlineShader->set("thickness", 0.2f); + + OUTLINE_MESH->bind(); + glDrawArrays(GL_TRIANGLES, 0, OUTLINE_MESH->vertexCount); } void renderRotationArcs() {