From 0476088a93fd4740ddda2db14e732808e69bd8bb Mon Sep 17 00:00:00 2001
From: Jens Koenen <koenen@vr.rwth-aachen.de>
Date: Wed, 18 Jan 2023 16:17:47 +0100
Subject: [PATCH] Updated assimp and fixed last orientation issues

---
 ext/assimp                            |  2 +-
 res/dpr/utility/indirect_capture.vert |  2 +-
 res/dpr/utility/math_library.glsl     |  2 +-
 res/dpr/utility/shadow.vert           |  2 +-
 src/headset/emulated_headset.cpp      |  4 +-
 src/scene.cpp                         | 34 +++++++-----
 src/scene.hpp                         | 22 +++++---
 src/utility/command_parser.cpp        | 74 +++++++++++++++++++++++++++
 src/utility/command_parser.hpp        |  6 +++
 src/vr_application.cpp                |  8 +--
 10 files changed, 128 insertions(+), 28 deletions(-)

diff --git a/ext/assimp b/ext/assimp
index 199aa5dd..67eae8ee 160000
--- a/ext/assimp
+++ b/ext/assimp
@@ -1 +1 @@
-Subproject commit 199aa5dd663402d4d3461876c9846c45b616699d
+Subproject commit 67eae8ee5afa149b11267de8ec87de1538fa80b6
diff --git a/res/dpr/utility/indirect_capture.vert b/res/dpr/utility/indirect_capture.vert
index 7e51ce02..58a5cda7 100644
--- a/res/dpr/utility/indirect_capture.vert
+++ b/res/dpr/utility/indirect_capture.vert
@@ -44,5 +44,5 @@ void main()
     outUV = inUV;
 
     mat4 shadow_matrix = lights[light_index].shadow_matrix[0];
-    gl_Position = convert_right_handed(shadow_matrix * vec4(outPos, 1.0));
+    gl_Position = shadow_matrix * vec4(outPos, 1.0);
 }
diff --git a/res/dpr/utility/math_library.glsl b/res/dpr/utility/math_library.glsl
index 41845c5a..d671504d 100644
--- a/res/dpr/utility/math_library.glsl
+++ b/res/dpr/utility/math_library.glsl
@@ -48,7 +48,7 @@ vec3 decode_normal(vec2 vector)
 // to the right handed NDC-space (x: right, y: down, z: into the screen) that is used by Vulkan.
 vec4 convert_right_handed(vec4 vector)
 {
-    return vec4(vector.x, 1.0 - vector.y, vector.zw);
+    return vec4(vector.x, -vector.y, vector.zw);
 }
 
 #endif
\ No newline at end of file
diff --git a/res/dpr/utility/shadow.vert b/res/dpr/utility/shadow.vert
index 00ae3694..0c72dcec 100644
--- a/res/dpr/utility/shadow.vert
+++ b/res/dpr/utility/shadow.vert
@@ -34,5 +34,5 @@ void main()
     mat4 shadow_matrix = lights[light_index].shadow_matrix[frustum_index];
     mat4 model_matrix = mesh.localToWorldSpace;
 
-    gl_Position = convert_right_handed(shadow_matrix * model_matrix * vec4(inPos, 1.0));
+    gl_Position = shadow_matrix * model_matrix * vec4(inPos, 1.0);
 }
diff --git a/src/headset/emulated_headset.cpp b/src/headset/emulated_headset.cpp
index ccfbb336..30925cbf 100644
--- a/src/headset/emulated_headset.cpp
+++ b/src/headset/emulated_headset.cpp
@@ -48,7 +48,7 @@ bool EmulatedHeadset::on_interface()
         this->compute_matrices(EYE_RIGHT);
     }
 
-    ImGui::DragFloat("Movement Speed", &camera.movement_speed, 1.0f, 0.0f, 1000.0);
+    ImGui::DragFloat("Movement Speed", &camera.movement_speed, 1.0f, 0.0f, 1000.0f);
 
     return true;
 }
@@ -64,7 +64,7 @@ bool EmulatedHeadset::on_update(lava::delta delta_time)
     this->submitted = false;
 
     this->controller_matrices[0] = glm::inverse(this->view_matrix) * glm::translate(glm::mat4(1.0f), glm::vec3(-0.3f, -0.2f, -0.4f));
-    this->controller_matrices[1] = glm::inverse(this->view_matrix) * glm::translate(glm::mat4(1.0f), glm::vec3( 0.3f, -0.2f, -0.4f));
+    this->controller_matrices[1] = glm::inverse(this->view_matrix) * glm::translate(glm::mat4(1.0f), glm::vec3(0.3f, -0.2f, -0.4f));
 
     return true;
 }
diff --git a/src/scene.cpp b/src/scene.cpp
index fd617492..c757da3e 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -20,7 +20,7 @@ bool Scene::create(const SceneConfig& config, lava::device_ptr device, uint32_t
 
     if (!config.scene_file.empty())
     {
-        if (!this->load_scene(config.scene_file, config.scene_unit, config.scene_orientation, device, node_indices))
+        if (!this->load_scene(config.scene_file, config.scene_unit, config.scene_orientation, config.scene_uvs, device, node_indices))
         {
             return false;
         }
@@ -35,7 +35,7 @@ bool Scene::create(const SceneConfig& config, lava::device_ptr device, uint32_t
 
     if (!config.controller_left_file.empty())
     {
-        if (!this->load_controller(config.controller_left_file, config.controller_left_unit, config.controller_left_orientation, device, this->controller_left, node_indices))
+        if (!this->load_controller(config.controller_left_file, config.controller_left_unit, config.controller_left_orientation, config.controller_left_uvs, device, this->controller_left, node_indices))
         {
             return false;
         }
@@ -45,7 +45,7 @@ bool Scene::create(const SceneConfig& config, lava::device_ptr device, uint32_t
 
     if (!config.controller_right_file.empty())
     {
-        if (!this->load_controller(config.controller_right_file, config.controller_right_unit, config.controller_right_orientation, device, this->controller_right, node_indices))
+        if (!this->load_controller(config.controller_right_file, config.controller_right_unit, config.controller_right_orientation, config.controller_right_uvs, device, this->controller_right, node_indices))
         {
             return false;
         }
@@ -859,12 +859,12 @@ bool Scene::create_mesh_buffer(lava::device_ptr device, uint32_t frame_count)
     return true;
 }
 
-bool Scene::load_scene(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, lava::device_ptr device, std::map<std::string, SceneNodeIndex>& node_indices)
+bool Scene::load_scene(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, SceneUVs uvs, lava::device_ptr device, std::map<std::string, SceneNodeIndex>& node_indices)
 {
     uint32_t post_processes = 0;
     float scale = 1.0f;
 
-    if (!Scene::setup_post_processes(orientation, post_processes))
+    if (!Scene::setup_post_processes(orientation, uvs, post_processes))
     {
         return false;
     }
@@ -875,7 +875,7 @@ bool Scene::load_scene(const std::string& file_name, SceneUnit unit, SceneOrient
     }
 
     Assimp::Importer importer;
-
+    
     lava::log()->info("Loading scene file '{}'", file_name.c_str());
     const aiScene* scene = importer.ReadFile(file_name, post_processes);
 
@@ -925,12 +925,12 @@ bool Scene::load_scene(const std::string& file_name, SceneUnit unit, SceneOrient
     return true;
 }
 
-bool Scene::load_controller(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, lava::device_ptr device, SceneNodeIndex& node_index, std::map<std::string, SceneNodeIndex>& node_indices)
+bool Scene::load_controller(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, SceneUVs uvs, lava::device_ptr device, SceneNodeIndex& node_index, std::map<std::string, SceneNodeIndex>& node_indices)
 {
     uint32_t post_processes = 0;
     float scale = 1.0f;
 
-    if (!Scene::setup_post_processes(orientation, post_processes))
+    if (!Scene::setup_post_processes(orientation, uvs, post_processes))
     {
         return false;
     }
@@ -2161,24 +2161,34 @@ void Scene::apply_transforms()
     }
 }
 
-bool Scene::setup_post_processes(SceneOrientation orientation, uint32_t& post_processes)
+bool Scene::setup_post_processes(SceneOrientation orientation, SceneUVs uvs, uint32_t& post_processes)
 {
     post_processes = aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType | aiProcess_GenBoundingBoxes;
-    post_processes |= aiProcess_FlipUVs;
 
     switch (orientation)
     {
     case SCENE_ORIENTATION_RIGHT_HANDED:
-        //post_processes |= aiProcess_ConvertToLeftHanded;
         break;
     case SCENE_ORIENTATION_LEFT_HANDED:
-        post_processes |= aiProcess_ConvertToLeftHanded;
+        post_processes |= aiProcess_ConvertToLeftHanded; //Convert to right-handed
         break;
     default:
         lava::log()->error("Can't setup post processes due to unknown scene orientation!");
         return false;
     }
 
+    switch (uvs)
+    {
+    case SCENE_UVS_UNCHANGED:
+        break;
+    case SCENE_UVS_Y_FLIP:
+        post_processes ^= aiProcess_FlipUVs;
+        break;
+    default:
+        lava::log()->error("Can't setup post processes due to unknown scene uvs!");
+        return false;
+    }
+
     return true;
 }
 
diff --git a/src/scene.hpp b/src/scene.hpp
index a30d2b6c..6c6dd0e2 100644
--- a/src/scene.hpp
+++ b/src/scene.hpp
@@ -31,6 +31,12 @@ enum SceneOrientation
     SCENE_ORIENTATION_LEFT_HANDED
 };
 
+enum SceneUVs
+{
+    SCENE_UVS_UNCHANGED,
+    SCENE_UVS_Y_FLIP
+};
+
 struct SceneConfig
 {
     std::string scene_file;
@@ -45,9 +51,13 @@ struct SceneConfig
     SceneUnit controller_left_unit = SCENE_UNIT_METERS;
     SceneUnit controller_right_unit = SCENE_UNIT_METERS;
 
-    SceneOrientation scene_orientation = SCENE_ORIENTATION_LEFT_HANDED;
-    SceneOrientation controller_left_orientation = SCENE_ORIENTATION_LEFT_HANDED;
-    SceneOrientation controller_right_orientation = SCENE_ORIENTATION_LEFT_HANDED;
+    SceneOrientation scene_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
+    SceneOrientation controller_left_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
+    SceneOrientation controller_right_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
+
+    SceneUVs scene_uvs = SCENE_UVS_UNCHANGED;
+    SceneUVs controller_left_uvs = SCENE_UVS_UNCHANGED;
+    SceneUVs controller_right_uvs = SCENE_UVS_UNCHANGED;
 
     glm::mat4 controller_left_alignment = glm::mat4(1.0f); //NOTE: This additonal transformation can be used to align the left controller model so that it matches with the controller in real world.
     glm::mat4 controller_right_alignment = glm::mat4(1.0f); //NOTE: This additonal transformation can be used to align the left controller model so that it matches with the controller in real world.
@@ -193,8 +203,8 @@ private:
     bool create_light_buffer(lava::device_ptr device, uint32_t frame_count);
     bool create_mesh_buffer(lava::device_ptr device, uint32_t frame_count);
 
-    bool load_scene(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, lava::device_ptr device, std::map<std::string, SceneNodeIndex>& node_indices);
-    bool load_controller(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, lava::device_ptr device, SceneNodeIndex& node_index, std::map<std::string, SceneNodeIndex>& node_indices);
+    bool load_scene(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, SceneUVs uvs, lava::device_ptr device, std::map<std::string, SceneNodeIndex>& node_indices);
+    bool load_controller(const std::string& file_name, SceneUnit unit, SceneOrientation orientation, SceneUVs uvs, lava::device_ptr device, SceneNodeIndex& node_index, std::map<std::string, SceneNodeIndex>& node_indices);
     bool load_sky_sphere(const std::string& file_name, uint32_t ring_count, uint32_t segment_count, lava::device_ptr device);
 
     bool load_nodes(const aiNode* node, float scale, uint32_t base_mesh, SceneNodeIndex parent_index, std::map<std::string, SceneNodeIndex>& node_indices);
@@ -215,7 +225,7 @@ private:
     void reset_transforms();
     void apply_transforms();
 
-    static bool setup_post_processes(SceneOrientation orientation, uint32_t& post_processes);
+    static bool setup_post_processes(SceneOrientation orientation, SceneUVs uvs, uint32_t& post_processes);
     static bool compute_scale(SceneUnit unit, float& scale);
 
 private:
diff --git a/src/utility/command_parser.cpp b/src/utility/command_parser.cpp
index 5d134d37..2f370c85 100644
--- a/src/utility/command_parser.cpp
+++ b/src/utility/command_parser.cpp
@@ -84,6 +84,22 @@ bool CommandParser::parse_command(const argh::parser& cmd_line)
             }
         }
 
+        else if (parameter.first == "scene-orientation")
+        {
+            if (!this->set_scene_orientation(parameter.second))
+            {
+                return false;
+            }
+        }
+
+        else if (parameter.first == "scene-uvs")
+        {
+            if (!this->set_scene_uvs(parameter.second))
+            {
+                return false;
+            }
+        }
+
         else if (parameter.first == "headset")
         {
             if (!this->set_headset(parameter.second))
@@ -290,6 +306,16 @@ SceneUnit CommandParser::get_scene_unit() const
     return this->scene_unit;
 }
 
+SceneOrientation CommandParser::get_scene_orientation() const
+{
+    return this->scene_orientation;
+}
+
+SceneUVs CommandParser::get_scene_uvs() const
+{
+    return this->scene_uvs;
+}
+
 const std::string& CommandParser::get_scene_path() const
 {
     return this->scene_path;
@@ -365,6 +391,10 @@ void CommandParser::show_help()
     std::cout << "                                        If no file is specified, sky stays black." << std::endl;
     std::cout << "   --scene-unit={unit}                  The unit in which the geometry of the scene is defined." << std::endl;
     std::cout << "                                        Options: meters (default), centimeters" << std::endl;
+    std::cout << "   --scene-orientation={orientation}    The coordinate system in which the geometry of the scene is defined." << std::endl;
+    std::cout << "                                        Options: right-handed (default), left-handed" << std::endl;
+    std::cout << "   --scene-uvs={uvs}                    The operation that is applied to the uvs of the scene during loading." << std::endl;
+    std::cout << "                                        Options: y-flip (default), unchanged" << std::endl;
     std::cout << "   --headset={headset}                  The headset that should be used." << std::endl;
     std::cout << "                                        Options: emulated (default), openvr, openxr, remote" << std::endl;
     std::cout << "   --stereo-strategy={strategy}         The stereo strategy that should be used." << std::endl;
@@ -546,5 +576,49 @@ bool CommandParser::set_scene_unit(const std::string& name)
         return false;
     }
 
+    return true;
+}
+
+bool CommandParser::set_scene_orientation(const std::string& name)
+{
+    if (name == "right-handed")
+    {
+        this->scene_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
+    }
+
+    else if (name == "left-handed")
+    {
+        this->scene_orientation = SCENE_ORIENTATION_LEFT_HANDED;
+    }
+
+    else
+    {
+        std::cout << "Invalid option set for parameter 'scene-orientation'. Use option --help to get more information." << std::endl;
+    
+        return false;
+    }
+
+    return true;
+}
+
+bool CommandParser::set_scene_uvs(const std::string& name)
+{
+    if (name == "y-flip")
+    {
+        this->scene_uvs = SCENE_UVS_Y_FLIP;
+    }
+
+    else if (name == "unchanged")
+    {
+        this->scene_uvs = SCENE_UVS_UNCHANGED;
+    }
+
+    else
+    {
+        std::cout << "Invalid option set for parameter 'scene-uvs'. Use option --help to get more information." << std::endl;
+    
+        return false;
+    }
+
     return true;
 }
\ No newline at end of file
diff --git a/src/utility/command_parser.hpp b/src/utility/command_parser.hpp
index 6a6df8a8..c451afa8 100644
--- a/src/utility/command_parser.hpp
+++ b/src/utility/command_parser.hpp
@@ -27,6 +27,8 @@ public:
     EncoderType get_encoder() const;
     EncoderCodec get_codec() const;
     SceneUnit get_scene_unit() const;
+    SceneOrientation get_scene_orientation() const;
+    SceneUVs get_scene_uvs() const;
 
     const std::string& get_scene_path() const;
     std::optional<std::string> get_sky_sphere_path() const;
@@ -55,6 +57,8 @@ private:
     bool set_encoder(const std::string& name);
     bool set_codec(const std::string& name);
     bool set_scene_unit(const std::string& name);
+    bool set_scene_orientation(const std::string& name);
+    bool set_scene_uvs(const std::string& name);
 
 private:
     HeadsetType headset = HEADSET_TYPE_EMULATED;
@@ -63,6 +67,8 @@ private:
     EncoderType encoder = ENCODER_TYPE_VULKAN;
     EncoderCodec codec = ENCODER_CODEC_H264;
     SceneUnit scene_unit = SCENE_UNIT_METERS;
+    SceneOrientation scene_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
+    SceneUVs scene_uvs = SCENE_UVS_Y_FLIP;
 
     std::string scene_path = "";
     std::optional<std::string> sky_sphere_path;
diff --git a/src/vr_application.cpp b/src/vr_application.cpp
index 18c6c864..307c70e8 100644
--- a/src/vr_application.cpp
+++ b/src/vr_application.cpp
@@ -319,8 +319,9 @@ bool VRApplication::on_create()
     SceneConfig config;
     config.scene_file = this->command_parser.get_scene_path();
     config.scene_unit = this->command_parser.get_scene_unit();
-    config.scene_orientation = SCENE_ORIENTATION_RIGHT_HANDED;
-    
+    config.scene_orientation = this->command_parser.get_scene_orientation();
+    config.scene_uvs = this->command_parser.get_scene_uvs();
+
     if (this->command_parser.get_sky_sphere_path().has_value())
     {
         config.sky_sphere_file = this->command_parser.get_sky_sphere_path().value();
@@ -330,8 +331,7 @@ bool VRApplication::on_create()
     {
         config.controller_left_file = std::string(RESOURCE_FOLDER) + "/dpr-controller/ObjModelViveFocus3ControllerLeft.fbx";
         config.controller_left_unit = SCENE_UNIT_CENTIMETERS;
-        config.controller_left_orientation = SCENE_ORIENTATION_LEFT_HANDED;
-
+        
         config.controller_right_file = std::string(RESOURCE_FOLDER) + "/dpr-controller/ObjModelViveFocus3ControllerRight.fbx";
         config.controller_right_unit = SCENE_UNIT_CENTIMETERS;
     }
-- 
GitLab