Skip to content
Snippets Groups Projects
Select Git revision
  • main
  • vac_in_initial_conditions
2 results

README.md

Blame
  • object_manager.cpp 8.90 KiB
    //------------------------------------------------------------------------------
    // Project Phoenix
    //
    // Copyright (c) 2017-2018 RWTH Aachen University, Germany,
    // Virtual Reality & Immersive Visualization Group.
    //------------------------------------------------------------------------------
    //                                 License
    //
    // Licensed under the 3-Clause BSD License (the "License");
    // you may not use this file except in compliance with the License.
    // See the file LICENSE for the full text.
    // You may obtain a copy of the License at
    //
    //     https://opensource.org/licenses/BSD-3-Clause
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    //------------------------------------------------------------------------------
    
    #include "object_manager.hpp"
    
    #include "phx/rendering/components/transform.hpp"
    #include "selector.hpp"
    
    #include "phx/rendering/components/material_handle.hpp"
    #include "phx/resources/loaders/scene_loader.hpp"
    #include "phx/resources/resource_utils.hpp"
    #include "phx/resources/types/material.hpp"
    #include "phx/resources/types/model.hpp"
    #include "phx/suppress_warnings.hpp"
    
    SUPPRESS_WARNINGS_BEGIN
    #include "glm/glm.hpp"
    #include "glm/gtx/rotate_vector.hpp"
    #include "glm/gtx/string_cast.hpp"
    SUPPRESS_WARNINGS_END
    
    ObjectManager::ObjectManager(phx::Engine* engine, phx::Scene* scene,
                                 OptixContextManager* manager)
        : phx::System(engine) {
      manager_ = manager;
      scene_ = scene;
      selection_system_ = engine->GetSystem<SelectionSystem>();
    
      bin_ = phx::SceneLoader::InsertModelIntoScene(
          "models/opticalBench/room/bin.obj", scene);
      auto select_bin = bin_->AddComponent<phx::Selector>(bin_);
      select_bin->SetMove(nullptr);  // deactivate move
      select_bin->SetInteractable(false);
    
      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
    
      auto transform = bin_->GetFirstComponent<phx::Transform>();
      for (auto i = 0u; i < transform->GetChildCount(); i++) {
        auto handle = transform->GetChild(i)
                          ->GetEntity()
                          ->GetFirstComponent<phx::MaterialHandle>();
        if (handle->GetMaterial()->GetName().compare("Base") == 0) {
          bin_mat_ = handle;
        }
      }
    
      bin_mat_->GetMaterial()->SetAmbientColor(kBinColorBase_);
      bin_mat_->GetMaterial()->SetDiffuseColor(kBinColorBase_);
    
      // intersection
      intersection_thread_ =
          std::thread(&ObjectManager::IntersectionThreadFunction, this);
    
      // Lens axis
      center_axis_ = phx::SceneLoader::InsertModelIntoScene(
          "models/opticalBench/table/Axis.obj", scene);
      center_axis_->GetFirstComponent<phx::Transform>()
          ->GetChild(0)
          ->GetEntity()
          ->GetFirstComponent<phx::MaterialHandle>()
          ->GetMaterial()
          ->SetAmbientColor(glm::vec3(1, 0, 0));
      ShowCenterAxis(false);
    }
    
    ObjectManager::~ObjectManager() {}
    
    void ObjectManager::Update(const phx::FrameTimer::TimeInfo&) {
      UpdateThreadData();
    
      Lens* current_lens = nullptr;
      TestPatternFrame* current_target = nullptr;
    
      intersector_output_mutex_.lock();
      intersector_invalidation_mutex_.lock();
      if (!intersector_data_invalidated_) {
        if (intersector_res_lens_ >= 0)
          current_lens = registered_lenses_[intersector_res_lens_];
        if (intersector_res_target_ >= 0)
          current_target = registered_frames_[intersector_res_target_];
      }
      intersector_invalidation_mutex_.unlock();
      intersector_output_mutex_.unlock();
    
      if (current_lens != nullptr || current_target != nullptr) {
        bin_mat_->GetMaterial()->SetAmbientColor(kBinColorHighlight);
        bin_mat_->GetMaterial()->SetDiffuseColor(kBinColorHighlight);
      } else {
        bin_mat_->GetMaterial()->SetAmbientColor(kBinColorBase_);
        bin_mat_->GetMaterial()->SetDiffuseColor(kBinColorBase_);
      }
    
      if (current_lens != nullptr) {
        if (!current_lens->IsGrabbed()) DeleteLens(current_lens);
      }
      if (current_target != nullptr) {
        if (!current_target->IsGrabbed()) DeleteTarget(current_target);
      }
    }
    
    Lens* ObjectManager::CreateLens(glm::vec3 pos) {
      auto lens = new Lens(engine_, scene_, manager_, Lens::CONVEX, Lens::CONVEX,
                           optix::make_float3(pos.x, pos.y, pos.z), 0.1f, 0.025f,
                           0.8f, 1.0f);
      lens->ChangedWaveLength(current_wavelength_nm_);
      registered_lenses_.push_back(lens);
      menu_->RegisterLens(lens);
      make_invalid_ = true;
    
      return lens;
    }
    
    TestPatternFrame* ObjectManager::CreateTarget(glm::vec3 pos,
                                                  std::string image) {
      auto target = new TestPatternFrame(scene_, manager_, image, pos);
      registered_frames_.push_back(target);
      make_invalid_ = true;
      return target;
    }
    
    void ObjectManager::DeleteLens(Lens* l) {
      registered_lenses_.erase(
          std::remove(registered_lenses_.begin(), registered_lenses_.end(), l),
          registered_lenses_.end());
    
      if (hmd_nav_ != nullptr) hmd_nav_->DeletedObject();
      menu_->UnregisterLens(l);
      make_invalid_ = true;
      selection_system_->ResetHoveredGrabbed();
      l->RemoveSupportRod();
      delete l;
    }
    
    void ObjectManager::DeleteTarget(TestPatternFrame* t) {
      registered_frames_.erase(
          std::remove(registered_frames_.begin(), registered_frames_.end(), t),
          registered_frames_.end());
    
      if (hmd_nav_ != nullptr) hmd_nav_->DeletedObject();
      make_invalid_ = true;
      selection_system_->ResetHoveredGrabbed();
      t->RemoveSupportRod();
      delete t;
    }
    
    void ObjectManager::KillThread() {
      intersector_run_ = false;
      intersection_thread_.join();
    }
    
    void ObjectManager::SetMenuManager(MenuManager* manager) {
      menu_ = manager;
      current_wavelength_nm_ = manager->GetLaserMenu()->GetCurrentWaveLength();
    }
    
    void ObjectManager::ChangedWavelength(float wavelength_nm) {
      current_wavelength_nm_ = wavelength_nm;
    
      for (auto l : registered_lenses_) {
        l->ChangedWaveLength(wavelength_nm);
      }
    }
    
    float ObjectManager::GetDistanceToNextLens(Lens* l, float own_z_pos) {
      auto own_z = (l == nullptr) ? own_z_pos : l->GetFrontCenter().z;
      float closest = INFINITY;
      float curr_z = 0;
    
      for (auto rl : registered_lenses_) {
        if (rl == l) continue;
        curr_z = rl->GetFrontCenter().z;
        if (curr_z < own_z && abs(curr_z - own_z) <= closest) {
          closest = abs(curr_z - own_z);
        }
      }
    
      return (closest == INFINITY) ? 0.0f : closest;
    }
    
    Lens* ObjectManager::GetLens(phx::Entity* e) {
      for (auto rl : registered_lenses_) {
        if (rl->GetEntity() == e) return rl;
      }
      return nullptr;
    }
    
    void ObjectManager::IntersectionThreadFunction() {
      auto select_bin = bin_->GetFirstComponent<phx::Selector>();
    
      int current_lens_res = -1;
      int current_frame_res = -1;
    
      std::vector<glm::vec3> lenses;
      std::vector<glm::vec3> targets;
    
      float dist = 0;
      bool updated_since_invalidation = false;
      while (intersector_run_) {
        // Update data
        intersector_input_mutex_.lock();
        lenses = intersector_lenses_pos_;
        targets = intersector_frames_pos_;
        intersector_input_mutex_.unlock();
    
        // Update internal invalidation flag
        intersector_invalidation_mutex_.lock();
        if (intersector_data_invalidated_) updated_since_invalidation = true;
        intersector_invalidation_mutex_.unlock();
    
        current_lens_res = -1;
        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) {
            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) {
            current_frame_res = i;
            break;
          }
        }
    
        intersector_output_mutex_.lock();
        intersector_res_lens_ = current_lens_res;
        intersector_res_target_ = current_frame_res;
        intersector_output_mutex_.unlock();
    
        // Update invalidation flag
        intersector_invalidation_mutex_.lock();
        if (updated_since_invalidation) {
          intersector_data_invalidated_ = false;
          updated_since_invalidation = false;
        }
        intersector_invalidation_mutex_.unlock();
      }
    }
    
    void ObjectManager::UpdateThreadData() {
      intersector_input_mutex_.lock();
    
      intersector_frames_pos_.clear();
      for (auto i = 0u; i < registered_frames_.size(); i++) {
        intersector_frames_pos_.push_back(
            registered_frames_[i]->GetTransform()->GetGlobalTranslation());
      }
    
      intersector_lenses_pos_.clear();
      for (auto i = 0u; i < registered_lenses_.size(); i++) {
        intersector_lenses_pos_.push_back(
            registered_lenses_[i]->GetTransform()->GetGlobalTranslation());
      }
    
      intersector_input_mutex_.unlock();
    
      if (make_invalid_) {
        intersector_invalidation_mutex_.lock();
        intersector_data_invalidated_ = true;
        intersector_invalidation_mutex_.unlock();
        make_invalid_ = false;
      }
    }