From 3d69d8bf3f5676a404c0a250d6834555f7e61e9e Mon Sep 17 00:00:00 2001 From: T1ti <40864460+T1ti@users.noreply.github.com> Date: Wed, 25 Sep 2024 05:06:49 +0200 Subject: [PATCH] fix drag selection selecting objects behind camera and add objects bounding radius --- src/noggit/ModelInstance.cpp | 5 +++++ src/noggit/SceneObject.hpp | 4 ++++ src/noggit/WMOInstance.cpp | 5 +++++ src/noggit/World.cpp | 12 +++++++++--- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/noggit/ModelInstance.cpp b/src/noggit/ModelInstance.cpp index 64eee77e..d39efadb 100755 --- a/src/noggit/ModelInstance.cpp +++ b/src/noggit/ModelInstance.cpp @@ -209,6 +209,11 @@ void ModelInstance::recalcExtents() size_cat = glm::distance(bounding_of_rotated_points.max, bounding_of_rotated_points.min); + // Calculate bounding radius + // glm::vec3 center = (extents[0] + extents[1]) / 2.0f; + glm::vec3 halfExtents = (extents[1] - extents[0]) / 2.0f; + bounding_radius = glm::length(halfExtents); + _need_recalc_extents = false; } diff --git a/src/noggit/SceneObject.hpp b/src/noggit/SceneObject.hpp index 1f8974cc..9f5b3428 100755 --- a/src/noggit/SceneObject.hpp +++ b/src/noggit/SceneObject.hpp @@ -71,6 +71,9 @@ public: [[nodiscard]] virtual std::array const& getExtents() { ensureExtents(); return extents; } + [[nodiscard]] + float const& getBoundingRadius() { ensureExtents(); return bounding_radius; } + glm::vec3 const getServerPos() { return glm::vec3(ZEROPOINT - pos.z, ZEROPOINT - pos.x, pos.y); } bool _grouped = false; @@ -89,6 +92,7 @@ protected: glm::mat4x4 _transform_mat = glm::mat4x4(); glm::mat4x4 _transform_mat_inverted = glm::mat4x4(); std::array extents; + float bounding_radius; Noggit::NoggitRenderContext _context; diff --git a/src/noggit/WMOInstance.cpp b/src/noggit/WMOInstance.cpp index cc1b296a..38137767 100755 --- a/src/noggit/WMOInstance.cpp +++ b/src/noggit/WMOInstance.cpp @@ -282,6 +282,11 @@ void WMOInstance::recalcExtents() extents[0] = wmo_aabb.min; extents[1] = wmo_aabb.max; + // Calculate bounding radius + // glm::vec3 center = (extents[0] + extents[1]) / 2.0f; + glm::vec3 halfExtents = (extents[1] - extents[0]) / 2.0f; + bounding_radius = glm::length(halfExtents); + _need_recalc_extents = false; } diff --git a/src/noggit/World.cpp b/src/noggit/World.cpp index 5bb8ad43..affcaf08 100755 --- a/src/noggit/World.cpp +++ b/src/noggit/World.cpp @@ -3607,9 +3607,15 @@ void World::select_objects_in_area( { for (auto& instance : pair.second) { - auto model = instance->transformMatrix(); + // auto transform_mat = instance->transformMatrix(); glm::mat4 VPmatrix = projection * view; glm::vec4 screenPos = VPmatrix * glm::vec4(instance->pos, 1.0f); + + // if screenPos.w < 0.0f, object is behind camera + // check object bounding radius instead to compare the object's size, if it clips with the camera. + if (screenPos.w < -instance->getBoundingRadius()) + continue; + screenPos.x /= screenPos.w; screenPos.y /= screenPos.w; @@ -3620,13 +3626,13 @@ void World::select_objects_in_area( screenPos.x *= viewport_width; screenPos.y *= viewport_height; - auto depth = glm::distance(camera_position, instance->pos); + float depth = glm::distance(camera_position, instance->pos); if (depth <= user_depth) { const glm::vec2 screenPos2D = glm::vec2(screenPos); if (misc::pointInside(screenPos2D, selection_box)) { - auto uid = instance->uid; + unsigned int uid = instance->uid; auto modelInstance = _model_instance_storage.get_instance(uid); if (modelInstance && modelInstance.value().index() == eEntry_Object) { auto obj = std::get(modelInstance.value());