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