Skip to content
Snippets Groups Projects
Select Git revision
  • 0acd419026604758d4738356f433d5c27a1c3896
  • main default protected
  • v1
  • old_script_archive
4 results

training.py

Blame
  • lens.cpp 13.18 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 "lens.hpp"
    #include <optix.h>
    #include "object_manager.hpp"
    #include "optix_context_manager.hpp"
    
    #include "phx/rendering/components/transform.hpp"
    #include "selection_mark_handler.hpp"
    #include "selector.hpp"
    
    #include "phx/rendering/components/material_handle.hpp"
    #include "phx/resources/resource_pointer.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/string_cast.hpp"
    SUPPRESS_WARNINGS_END
    
    Lens::Lens(phx::Engine* engine, phx::Scene* scene, OptixContextManager* manager,
               LensSideType type1, LensSideType type2, optix::float3 frontCenter,
               float lensradius, float thickness, float radius, float radius2) {
      manager_ = manager;
      scene_ = scene;
    
      CreateGlassMaterialInstance();
      geometry_ = manager->GetContext()->createGeometryInstance(
          manager->GetLensGeometry(), &glass_material_, &glass_material_ + 1);
    
      geometry_["center"]->setFloat(0, 0, 0);
      geometry_["radius"]->setFloat(radius);
      geometry_["radius2"]->setFloat(radius2);
      geometry_["orientation"]->setFloat(optix::make_float3(0.f, 0.f, -1.f));
      geometry_["lensRadius"]->setFloat(lensradius);
    
      geometry_["side1Type"]->setInt(type1);
      geometry_["side2Type"]->setInt(type2);
      type_1_ = type1;
      type_2_ = type2;
    
      float cylinderLength = GetCylinderLength(thickness);
      geometry_["halfCylinderLength"]->setFloat(cylinderLength / 2);
    
      transform_ = manager->GetContext()->createTransform();
      transform_->setMatrix(false, &glm::mat4()[0][0], &glm::mat4()[0][0]);
      // Add the lens to the scene
    
      geometry_group_ = manager->GetContext()->createGeometryGroup();
      geometry_group_->addChild(geometry_);
      acceleration_structure_ = manager->GetContext()->createAcceleration("Trbvh");
      acceleration_structure_->setProperty("refit", "1");
    
      geometry_group_->setAcceleration(acceleration_structure_);
    
      transform_->setChild<optix::GeometryGroup>(geometry_group_);
      manager->GetTopObject()->addChild(transform_);
    
      // Attach handles
      entity_ = scene->CreateEntity();
      auto center =
          frontCenter - optix::make_float3(0.f, 0.f, -1.f) * thickness / 2;
      entity_->AddComponent<phx::Transform>()->Translate(
          glm::vec3(center.x, center.y, center.z));
      selector_ = entity_->AddComponent<phx::Selector>(nullptr, true);
    
      support_rod_ = new SupportRod(scene, selector_, false);
    
      auto obj_m = engine->GetSystem<ObjectManager>();
    
      // Set Moving
      selector_->SetMove([this, obj_m](phx::Transform* t, glm::mat4 r) {
        auto pos = glm::vec3((t->GetGlobalMatrix() * r)[3]);
        auto pos_proj =
            glm::dot(pos - obj_m->GetCenterAxisPos(), glm::vec3(0, 0, 1)) *
                glm::vec3(0, 0, 1) +
            obj_m->GetCenterAxisPos();
    
        // close enough? Then snap!
        if (glm::length(pos - pos_proj) <= obj_m->GetSnapDistance()) pos = pos_proj;
    
        entity_->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(pos);
        glm::mat4 trans =
            entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix();
        transform_->setMatrix(true, &(trans[0][0]), &(inverse(trans)[0][0]));
    
        support_rod_->Moved();
        acceleration_structure_->markDirty();
        manager_->TopAccelerationMarkDirty();
      });
      selector_->SetExternalUpdate([this]() {
        glm::mat4 trans =
            entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix();
        transform_->setMatrix(true, &(trans[0][0]), &(inverse(trans)[0][0]));
    
        support_rod_->Moved();
        acceleration_structure_->markDirty();
        manager_->TopAccelerationMarkDirty();
      });
    
      // Store if grabbed
      selector_->SetGrab([this](phx::Transform*, glm::mat4) { grabbed_ = true; });
      selector_->SetRelease([this]() { grabbed_ = false; });
    
      RecalculateBoundingBox();
      acceleration_structure_->markDirty();
      manager_->TopAccelerationMarkDirty();
    }
    
    Lens::~Lens() {
      manager_->GetTopObject()->removeChild(transform_);
      glass_material_->destroy();
      geometry_->destroy();
      geometry_group_->destroy();
      transform_->destroy();
      acceleration_structure_->destroy();
      scene_->RemoveEntity(entity_);
      delete support_rod_;
      manager_->TopAccelerationMarkDirty();
    }
    
    void Lens::NextLensSideType1() {
      auto s1 = geometry_["side1Type"]->getInt();
      auto s2 = geometry_["side2Type"]->getInt();
    
      s1 = (((s1 + 1) + 1) % 3) - 1;
    
      SetLensSideTypes(static_cast<LensSideType>(s1),
                       static_cast<LensSideType>(s2));
    }
    
    void Lens::PreviousLensSideType1() {
      auto s1 = geometry_["side1Type"]->getInt();
      auto s2 = geometry_["side2Type"]->getInt();
    
      s1 = (((s1 - 1 + 3) + 1) % 3) - 1;
    
      SetLensSideTypes(static_cast<LensSideType>(s1),
                       static_cast<LensSideType>(s2));
    }
    
    void Lens::NextLensSideType2() {
      auto s1 = geometry_["side1Type"]->getInt();
      auto s2 = geometry_["side2Type"]->getInt();
    
      s2 = (((s2 + 1) + 1) % 3) - 1;
    
      SetLensSideTypes(static_cast<LensSideType>(s1),
                       static_cast<LensSideType>(s2));
    }
    
    void Lens::PreviousLensSideType2() {
      auto s1 = geometry_["side1Type"]->getInt();
      auto s2 = geometry_["side2Type"]->getInt();
    
      s2 = (((s2 - 1 + 3) + 1) % 3) - 1;
    
      SetLensSideTypes(static_cast<LensSideType>(s1),
                       static_cast<LensSideType>(s2));
    }
    
    void Lens::NextGlassType() {
      glass_type_ = static_cast<GlassType>((glass_type_ + 1) % 5);
      ChangedWaveLength(current_wavelength_nm_);
    }
    
    void Lens::PreviousGlassType() {
      glass_type_ = static_cast<GlassType>((glass_type_ - 1 + 5) % 5);
      ChangedWaveLength(current_wavelength_nm_);
    }
    
    std::string Lens::GetLensTypeName1() {
      return GetTypeString(
          static_cast<LensSideType>(geometry_["side1Type"]->getInt()));
    }
    
    std::string Lens::GetLensTypeName2() {
      return GetTypeString(
          static_cast<LensSideType>(geometry_["side2Type"]->getInt()));
    }
    
    std::string Lens::GetGlassTypeName() {
      switch (glass_type_) {
        case BK7:
          return "BK7";
        case SF5:
          return "SF5";
        case SF11:
          return "SF11";
        case FUSED_SILICA:
          return "Fus.Sil.";
        case SK16:
          return "SK16";
        case F2:
          return "F2";
      }
      return "Unknown";
    }
    
    void Lens::Translate(glm::vec3 pos) {
      GetEntity()->GetFirstComponent<phx::Transform>()->SetGlobalTranslation(pos);
      selector_->ExternalUpdate();
    }
    
    void Lens::SetSelected(bool s) { support_rod_->SetMarked(s); }
    
    void Lens::ChangedWaveLength(float wavelength_nm) {
      double wl2 = glm::pow(wavelength_nm / 1000.0, 2);
      float index = (float)sqrt(1 +
                                (glass_definitions[glass_type_][0].x * wl2) /
                                    (wl2 - glass_definitions[glass_type_][1].x) +
                                (glass_definitions[glass_type_][0].y * wl2) /
                                    (wl2 - glass_definitions[glass_type_][1].y) +
                                (glass_definitions[glass_type_][0].z * wl2) /
                                    (wl2 - glass_definitions[glass_type_][1].z));
    
      glass_material_["refraction_index"]->setFloat(index);
      current_wavelength_nm_ = wavelength_nm;
    }
    
    std::array<glm::vec3, 2u> Lens::ComputeAABBFromCylinder(glm::vec3 orientation,
                                                            float halfLength1,
                                                            float halfLength2,
                                                            float radius) {
      auto res = std::array<glm::vec3, 2u>();
    
      glm::vec3 sideVector =
          normalize(cross(orientation, glm::vec3(0.0f, 1.0f, 0.0f)));
      glm::vec3 newUp = normalize(cross(sideVector, orientation));
      sideVector = sideVector * radius;
      newUp = newUp * radius;
      glm::vec3 depthVector = normalize(orientation);
    
      res[0] = glm::vec3(INFINITY);
      res[1] = glm::vec3(-INFINITY);
      glm::vec3 testVector = glm::vec3(0.0f);
    
      testVector = depthVector * halfLength1 + sideVector + newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = depthVector * halfLength1 + sideVector - newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = depthVector * halfLength1 - sideVector + newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = depthVector * halfLength1 - sideVector - newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
    
      testVector = -depthVector * halfLength2 + sideVector + newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = -depthVector * halfLength2 + sideVector - newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = -depthVector * halfLength2 - sideVector + newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
      testVector = -depthVector * halfLength2 - sideVector - newUp;
      res[1] = glm::max(res[1], testVector);
      res[0] = glm::min(res[0], testVector);
    
      return res;
    }
    
    glm::vec3 Lens::GetFrontCenter() {
      return entity_->GetFirstComponent<phx::Transform>()->GetGlobalTranslation() +
             glm::mat3(
                 entity_->GetFirstComponent<phx::Transform>()->GetGlobalMatrix()) *
                 glm::vec3(0.f, 0.f, -1.f) * GetThickness() / 2.0f;
    }
    
    float Lens::GetCylinderLength(float thickness) {
      float lr = geometry_["lensRadius"]->getFloat();
      float r1 = geometry_["radius"]->getFloat();
      float r2 = geometry_["radius2"]->getFloat();
    
      // thickness of the halfspheres
      float halfThickness1 = r1 - sqrtf(-lr * lr + r1 * r1);
      if (type_1_ == CONCAVE) halfThickness1 *= -1;
      if (type_1_ == PLANE) halfThickness1 = 0;
    
      float halfThickness2 = r2 - sqrtf(-lr * lr + r2 * r2);
      if (type_2_ == CONCAVE) halfThickness2 *= -1;
      if (type_2_ == PLANE) halfThickness2 = 0;
    
      return thickness - halfThickness1 - halfThickness2;
    }
    
    float Lens::GetThickness(float cylinder_length) {
      float lr = geometry_["lensRadius"]->getFloat();
      float r1 = geometry_["radius"]->getFloat();
      float r2 = geometry_["radius2"]->getFloat();
    
      // thickness of the halfspheres
      float halfThickness1 = r1 - sqrtf(-lr * lr + r1 * r1);
      if (type_1_ == CONCAVE) halfThickness1 *= -1;
      if (type_1_ == PLANE) halfThickness1 = 0;
    
      float halfThickness2 = r2 - sqrtf(-lr * lr + r2 * r2);
      if (type_2_ == CONCAVE) halfThickness2 *= -1;
      if (type_2_ == PLANE) halfThickness2 = 0;
    
      return cylinder_length + halfThickness1 + halfThickness2;
    }
    
    void Lens::SetLensSideTypes(LensSideType type1, LensSideType type2) {
      float thickness =
          GetThickness(geometry_["halfCylinderLength"]->getFloat() * 2);
    
      geometry_["side1Type"]->setInt(type1);
      geometry_["side2Type"]->setInt(type2);
    
      type_1_ = type1;
      type_2_ = type2;
    
      geometry_["halfCylinderLength"]->setFloat(GetCylinderLength(thickness) / 2);
    }
    
    void Lens::RecalculateBoundingBox() {
      auto o = geometry_["orientation"]->getFloat3();
      float t = geometry_["halfCylinderLength"]->getFloat() * 2;
      float lr = geometry_["lensRadius"]->getFloat();
    
      t = GetThickness(t);
    
      auto bb =
          ComputeAABBFromCylinder(glm::vec3(o.x, o.y, o.z), t / 2.0f, t / 2.0f, lr);
      selector_->SetCollider(bb[0], bb[1]);
      selector_->ExternalUpdate();
    }
    
    std::string Lens::GetTypeString(LensSideType t) {
      switch (t) {
        case CONCAVE:
          return "Concave";
        case CONVEX:
          return "Convex";
        case PLANE:
          return "Plane";
      }
      return "Unknown";
    }
    
    void Lens::CreateGlassMaterialInstance() {
      glass_material_ = manager_->GetContext()->createMaterial();
      glass_material_->setClosestHitProgram(0,
                                            manager_->GetGlassProgramPerspective());
      glass_material_->setClosestHitProgram(1,
                                            manager_->GetGlassProgramIterative());
    
      glass_material_["importance_cutoff"]->setFloat(1e-2f);
      glass_material_["cutoff_color"]->setFloat(0.035f, 0.102f, 0.169f);
      glass_material_["fresnel_exponent"]->setFloat(3.0f);
      glass_material_["fresnel_minimum"]->setFloat(0.1f);
      glass_material_["fresnel_maximum"]->setFloat(1.0f);
      glass_material_["refraction_index"]->setFloat(1.4f);
      glass_material_["refraction_color"]->setFloat(1.0f, 1.0f, 1.0f);
      glass_material_["reflection_color"]->setFloat(1.0f, 1.0f, 1.0f);
      glass_material_["refraction_maxdepth"]->setInt(10);
      glass_material_["reflection_maxdepth"]->setInt(5);
      glass_material_["extinction_constant"]->setFloat(log(0.83f), log(0.83f),
                                                       log(0.83f));
    }