Select Git revision
Dockerfile.itac
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;
}
}