From be910b5d13551ddcd63f5d5439ccf9e05ff95b00 Mon Sep 17 00:00:00 2001
From: Christian Mattes <christian.mattes@rwth-aachen.de>
Date: Thu, 7 Mar 2019 14:55:50 +0100
Subject: [PATCH] Added VRMesh loading from obj-files

---
 src/lava-vr/VRMesh.cc         | 77 +++++++++++++++++++++++++++++++++++
 src/lava-vr/VRMesh.hh         |  1 +
 src/lava-vr/VRMeshRenderer.cc |  4 +-
 3 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/src/lava-vr/VRMesh.cc b/src/lava-vr/VRMesh.cc
index d376507..310b581 100644
--- a/src/lava-vr/VRMesh.cc
+++ b/src/lava-vr/VRMesh.cc
@@ -3,6 +3,14 @@
 #include <iostream>
 #include <zlib.h>
 
+#include <assimp/Importer.hpp>
+#include <assimp/mesh.h>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/vector3.h>
+
+#include <lodepng/lodepng.h>
+
 namespace lava {
 namespace vr {
 
@@ -122,5 +130,74 @@ VRMesh VRMesh::readFromFile(const std::string &filename) {
     return result;
 }
 
+VRMesh VRMesh::readFromObj(const std::string &objfile,
+                           const std::string &texture) {
+    VRMesh result;
+
+    Assimp::Importer importer;
+
+    const aiScene *importScene =
+        importer.ReadFile(objfile, AI_SCENE_FLAGS_NON_VERBOSE_FORMAT |
+                                       aiProcess_JoinIdenticalVertices);
+
+    if (importScene == NULL) {
+        std::cout << "VRMesh::readFromObj(...): no scene loaded." << std::endl
+                  << "Perhaps invalid filepath given? Filepath is:" << std::endl
+                  << objfile << std::endl;
+        assert(0);
+    }
+
+    if (importScene->HasMeshes()) {
+        aiMesh *theMesh = importScene->mMeshes[0];
+        auto uv = theMesh->mTextureCoords[0];
+
+        for (unsigned int i = 0; i < theMesh->mNumVertices; ++i) {
+            Vertex v;
+            v.position.x = theMesh->mVertices[i].x;
+            v.position.y = theMesh->mVertices[i].y;
+            v.position.z = theMesh->mVertices[i].z;
+            if (uv) {
+                v.texCoord.x = uv[i].x;
+                v.texCoord.y = 1.0 - uv[i].y;
+            }
+            v.layer = 0.0f;
+
+            result.vertices.push_back(v);
+        }
+        for (unsigned int i_f = 0; i_f < theMesh->mNumFaces; ++i_f) {
+            assert(theMesh->mFaces[i_f].mNumIndices == 3 &&
+                   "Only triangles for now please");
+            for (unsigned int i_i = 0; i_i < 3; ++i_i) {
+                uint32_t currentVertexIndex =
+                    (uint32_t)theMesh->mFaces[i_f].mIndices[i_i];
+                result.indices.push_back(currentVertexIndex);
+            }
+        }
+
+        if (!texture.empty()) {
+            result.colorTexture.meta.depth = 1;
+            result.colorTexture.meta.mipLayers = 1;
+            result.colorTexture.meta.bytes_per_pixel = 4;
+            lodepng::decode(result.colorTexture.data,
+                            result.colorTexture.meta.width,
+                            result.colorTexture.meta.height, texture, LCT_RGBA);
+        } else {
+            result.colorTexture.meta.width = 1;
+            result.colorTexture.meta.height = 1;
+            result.colorTexture.meta.depth = 1;
+            result.colorTexture.meta.mipLayers = 1;
+            result.colorTexture.meta.bytes_per_pixel = 4;
+            result.colorTexture.data = {0xff, 0xff, 0xff, 0xff};
+        }
+    } else {
+        std::cout
+            << "Loading VRMesh from .obj-file failed (no mesh could be loaded)."
+            << std::endl;
+        assert(0);
+    }
+
+    return result;
+}
+
 } // namespace vr
 } // namespace lava
diff --git a/src/lava-vr/VRMesh.hh b/src/lava-vr/VRMesh.hh
index 4843f0e..b1a0267 100644
--- a/src/lava-vr/VRMesh.hh
+++ b/src/lava-vr/VRMesh.hh
@@ -50,6 +50,7 @@ struct VRMesh {
 #endif
 
     static VRMesh readFromFile(const std::string &filename);
+    static VRMesh readFromObj(const std::string &objfile, const std::string& texture = "");
 
     struct OffsetHelper {
         size_t width, height, depth, bytes_per_pixel, mip_layers;
diff --git a/src/lava-vr/VRMeshRenderer.cc b/src/lava-vr/VRMeshRenderer.cc
index f4b937e..73f181f 100644
--- a/src/lava-vr/VRMeshRenderer.cc
+++ b/src/lava-vr/VRMeshRenderer.cc
@@ -98,7 +98,9 @@ void VRMeshRenderer::upload(const VRMesh &mesh) {
         auto meta = mesh.colorTexture.meta;
 
         mTexture = lava::texture2DArray(meta.width, meta.height, meta.depth,
-                                        vk::Format::eBc7SrgbBlock)
+                                        meta.bytes_per_pixel == 1
+                                            ? vk::Format::eBc7SrgbBlock
+                                            : vk::Format::eR8G8B8A8Srgb)
                        .setMipLevels(meta.mipLayers)
                        .create(device);
 
-- 
GitLab