From bc726b0a83aadad605286facd4b9a16dc8d26fa7 Mon Sep 17 00:00:00 2001
From: Sebastian Pape <Sebastian.Pape@rwth-aachen.de>
Date: Fri, 24 Aug 2018 14:31:12 +0200
Subject: [PATCH] Fixed covering of objects in selection system Added point
 intersection to Selector to make the trash can intersection more efficient

---
 demos/optical_bench/src/object_manager.cpp   |  9 +++----
 demos/optical_bench/src/optical_bench.cpp    |  1 +
 demos/optical_bench/src/selection_system.cpp | 27 +++++++++++++++-----
 demos/optical_bench/src/selection_system.hpp |  1 +
 demos/optical_bench/src/selector.cpp         | 17 ++++++++++++
 demos/optical_bench/src/selector.hpp         |  1 +
 6 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/demos/optical_bench/src/object_manager.cpp b/demos/optical_bench/src/object_manager.cpp
index 6984843e..e3bf4c5c 100644
--- a/demos/optical_bench/src/object_manager.cpp
+++ b/demos/optical_bench/src/object_manager.cpp
@@ -53,7 +53,7 @@ ObjectManager::ObjectManager(phx::Engine* engine, phx::Scene* scene,
 
   bin_->GetFirstComponent<phx::Transform>()->Translate(
       glm::vec3(0.0f, 0.0f, -1.5f));  // Position on floor
-  // glm::vec3(0.50f, 1.0f, 1.0f));  // Position on table
+      // glm::vec3(0.50f, 1.0f, 1.0f));  // Position on table
 
   auto transform = bin_->GetFirstComponent<phx::Transform>();
   for (auto i = 0u; i < transform->GetChildCount(); i++) {
@@ -233,7 +233,6 @@ void ObjectManager::IntersectionThreadFunction() {
   std::vector<glm::vec3> lenses;
   std::vector<glm::vec3> targets;
 
-  float dist = 0;
   bool updated_since_invalidation = false;
   while (intersector_run_) {
     // Update data
@@ -251,16 +250,14 @@ void ObjectManager::IntersectionThreadFunction() {
     current_frame_res = -1;
 
     for (auto i = 0u; i < lenses.size(); i++) {
-      dist = select_bin->Intersect(lenses[i], glm::vec3(0, 1, 0));
-      if (dist == 0) {
+      if (select_bin->Intersect(lenses[i])) {
         current_lens_res = i;
         break;
       }
     }
 
     for (auto i = 0u; i < targets.size(); i++) {
-      dist = select_bin->Intersect(targets[i], glm::vec3(0, 1, 0));
-      if (dist == 0) {
+      if (select_bin->Intersect(targets[i])) {
         current_frame_res = i;
         break;
       }
diff --git a/demos/optical_bench/src/optical_bench.cpp b/demos/optical_bench/src/optical_bench.cpp
index d93d8f30..ac597ca9 100644
--- a/demos/optical_bench/src/optical_bench.cpp
+++ b/demos/optical_bench/src/optical_bench.cpp
@@ -138,6 +138,7 @@ int main(int argc, char** args) {
     static bool usage = true;
     if (key == '.') contextManager->EnableUsageCallback(usage);
     if (key == 'l') object_manager->PrintLensInfos();
+    if (key == 'n') object_manager->GetMenuManager()->NextMenu();
     usage = !usage;
   });
 
diff --git a/demos/optical_bench/src/selection_system.cpp b/demos/optical_bench/src/selection_system.cpp
index 38384810..57c5ee03 100644
--- a/demos/optical_bench/src/selection_system.cpp
+++ b/demos/optical_bench/src/selection_system.cpp
@@ -98,6 +98,7 @@ void SelectionSystem::Update(const phx::FrameTimer::TimeInfo& time_info) {
 void SelectionSystem::Grab(phx::Transform* con) {
   selector_output_mutex_.lock();
   selector_currently_grabbed_entity_ = selector_result_entity_;
+  selector_currently_grabbed_distance_ = selector_result_distance_;
   selector_output_mutex_.unlock();
 
   selector_input_mutex_.lock();
@@ -118,6 +119,7 @@ void SelectionSystem::Release() {
   selector_currently_grabbed_entity_->GetFirstComponent<phx::Selector>()
       ->Release();
   selector_currently_grabbed_entity_ = nullptr;
+  selector_currently_grabbed_distance_ = INFINITY;
 }
 
 void SelectionSystem::Move(phx::Transform* con) {
@@ -137,6 +139,9 @@ phx::Entity* SelectionSystem::GetHovered() {
 float SelectionSystem::GetIntersectionDistance() {
   selector_output_mutex_.lock();
   float res = selector_result_distance_;
+  if (selector_currently_grabbed_entity_ != nullptr) {
+    res = selector_currently_grabbed_distance_;
+  }
   selector_output_mutex_.unlock();
   return res;
 }
@@ -145,7 +150,8 @@ void SelectionSystem::IntersectionThreadFunction() {
   std::vector<phx::Entity*> entities;
   glm::vec3 ori;
   glm::vec3 dir;
-  float closest_intersection;
+  float intersection_distance_res;
+  float closest_intersection_found;
   float current_intersection;
   phx::Entity* res;
   phx::Selector* curr;
@@ -156,7 +162,8 @@ void SelectionSystem::IntersectionThreadFunction() {
     dir = selector_direction_;
     entities = selector_entities_;
     selector_input_mutex_.unlock();
-    closest_intersection = INFINITY;
+    intersection_distance_res = INFINITY;
+    closest_intersection_found = INFINITY;
     res = nullptr;
 
     for (auto i = 0u; i < entities.size(); ++i) {
@@ -170,16 +177,22 @@ void SelectionSystem::IntersectionThreadFunction() {
       current_intersection = curr->Intersect(ori, dir);
 
       if (current_intersection >= 0.0f &&
-          current_intersection < curr->GetIntersectionDistance() &&
-          current_intersection < closest_intersection) {
-        res = entities[i];
-        closest_intersection = current_intersection;
+          current_intersection < closest_intersection_found) {
+        closest_intersection_found = current_intersection;
+        // If valid
+        if (current_intersection < curr->GetIntersectionDistance()) {
+          res = entities[i];
+          intersection_distance_res = current_intersection;
+        } else {
+          res = nullptr;
+          intersection_distance_res = INFINITY;
+        }
       }
     }
 
     selector_output_mutex_.lock();
     selector_result_entity_ = res;
-    selector_result_distance_ = closest_intersection;
+    selector_result_distance_ = intersection_distance_res;
     selector_output_mutex_.unlock();
   }
 }
diff --git a/demos/optical_bench/src/selection_system.hpp b/demos/optical_bench/src/selection_system.hpp
index 38c45238..ea6bad5e 100644
--- a/demos/optical_bench/src/selection_system.hpp
+++ b/demos/optical_bench/src/selection_system.hpp
@@ -76,6 +76,7 @@ class SelectionSystem : public phx::System {
   float selector_result_distance_;
 
   phx::Entity* selector_currently_grabbed_entity_ = nullptr;
+  float selector_currently_grabbed_distance_ = INFINITY;
   phx::Entity* selector_currently_hovered_entity_ = nullptr;
   glm::mat4 selector_relative_grab_;
   glm::mat4 selector_relative_hover_;
diff --git a/demos/optical_bench/src/selector.cpp b/demos/optical_bench/src/selector.cpp
index efb40179..032a9d05 100644
--- a/demos/optical_bench/src/selector.cpp
+++ b/demos/optical_bench/src/selector.cpp
@@ -131,6 +131,23 @@ float Selector::Intersect(glm::vec3 ray_origin, glm::vec3 ray_direction) {
   return -1.0f;
 }
 
+bool Selector::Intersect(glm::vec3 point) {
+  glm::vec3 transformed = glm::vec3(point);
+  // If transform present apply it
+  auto transform = GetEntity()->GetFirstComponent<phx::Transform>();
+  if (transform != nullptr) {
+    glm::vec4 new_point =
+        inverse(transform->GetGlobalMatrix()) * glm::vec4(point, 1.0f);
+    transformed = glm::vec3(new_point) / new_point.w;
+  }
+  return collider_.corner_min.x <= transformed.x &&
+         collider_.corner_max.x >= transformed.x &&
+         collider_.corner_min.y <= transformed.y &&
+         collider_.corner_max.y >= transformed.y &&
+         collider_.corner_min.z <= transformed.z &&
+         collider_.corner_max.z >= transformed.z;
+}
+
 void Selector::SetCollider(glm::vec3 c1, glm::vec3 c2) {
   SwapMinMaxVectorEntries(c1, c2);
   collider_.corner_max = c2;
diff --git a/demos/optical_bench/src/selector.hpp b/demos/optical_bench/src/selector.hpp
index 15b27b96..c2a6dccb 100644
--- a/demos/optical_bench/src/selector.hpp
+++ b/demos/optical_bench/src/selector.hpp
@@ -58,6 +58,7 @@ class Selector : public Component {
   }
 
   float Intersect(glm::vec3 ray_origin, glm::vec3 ray_direction);
+  bool Intersect(glm::vec3 point);
 
   // Set/Get Collider
   void SetCollider(MeshHandle& handle) {
-- 
GitLab