From 61f60cbbae999c00e7681b4f1562904c081644f9 Mon Sep 17 00:00:00 2001 From: Trevor Hollmann <thollmann@uni-koblenz.de> Date: Sat, 17 Jul 2021 21:59:35 +0200 Subject: [PATCH] [#79] Add URIs to Scene struct. --- .../include/vkcv/asset/asset_loader.hpp | 4 ++ .../src/vkcv/asset/asset_loader.cpp | 63 ++++++++++++++++--- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp index cd609c99..ad35d772 100644 --- a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp +++ b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp @@ -80,6 +80,7 @@ typedef struct { * if the image has just RGB or is grayscale. */ typedef struct { + int uri; // index into the URIs array of the Scene int sampler; // index into the sampler array of the Scene uint8_t channels; // number of channels uint16_t w, h; // width and height of the texture @@ -183,10 +184,12 @@ typedef struct { enum PrimitiveMode mode; // draw as points, lines or triangle? size_t numIndices, numVertices; struct { + int uri; // index into the URIs array of Scene enum IndexType type; // data type of the indices std::vector<uint8_t> data; // binary data of the index buffer } indexBuffer; struct { + int uri; // index into the URIs array of Scene std::vector<uint8_t> data; // binary data of the vertex buffer std::vector<VertexAttribute> attributes; // description of one } vertexBuffer; @@ -217,6 +220,7 @@ typedef struct { std::vector<Material> materials; std::vector<Texture> textures; std::vector<Sampler> samplers; + std::vector<std::string> uris; } Scene; /** diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index b1d0bdd4..e78b4e62 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -92,14 +92,19 @@ int createTextures(const std::vector<fx::gltf::Texture>& tex_src, const std::vector<fx::gltf::Image>& img_src, const std::vector<fx::gltf::Buffer>& buf_src, const std::vector<fx::gltf::BufferView>& bV_src, - const std::string& dir, std::vector<Texture>& dst) + const std::string& dir, std::vector<std::string> &uris, + std::vector<Texture>& dst) { + std::unordered_map<std::string,int> known_uris; + for (int i = 0; i < uris.size(); i++) known_uris[uris[i]] = i; + dst.clear(); dst.reserve(tex_src.size()); for (const auto& tex : tex_src) { std::string uri = dir + "/" + img_src[tex.source].uri; int w, h, c; uint8_t* data; + int uri_index = -1; if (!uri.empty()) { data = stbi_load(uri.c_str(), &w, &h, &c, 4); if (!data) { @@ -107,8 +112,15 @@ int createTextures(const std::vector<fx::gltf::Texture>& tex_src, uri.c_str()); return ASSET_ERROR; } + if (known_uris.count(uri)) { + uri_index = known_uris[uri]; + } else { + uri_index = uris.size(); + uris.push_back(uri); + } } else { - //TODO this is untested. Find gltf file without uri to test it! + // TODO What to do in this case with Texture.uri? + // TODO this is untested. Find gltf file without uri to test it! const fx::gltf::BufferView bufferView = bV_src[img_src[tex.source].bufferView]; data = stbi_load_from_memory( &buf_src[bufferView.buffer].data[bufferView.byteOffset], @@ -133,7 +145,9 @@ int createTextures(const std::vector<fx::gltf::Texture>& tex_src, } free(data); + if (uri_index < 0) vkcv_log(LogLevel::WARNING, "Texture is missing a URI."); dst.push_back({ + uri_index, tex.sampler, static_cast<uint8_t>(c), static_cast<uint16_t>(w), static_cast<uint16_t>(h), @@ -383,11 +397,15 @@ int createVertexGroups(fx::gltf::Mesh const& objectMesh, fx::gltf::Document &sceneObjects, std::vector<VertexGroup> &vertexGroups, std::vector<int> &vertexGroupsIndices, + std::vector<std::string> &uris, int &groupCount, bool probe) { const size_t numVertexGroups = objectMesh.primitives.size(); vertexGroups.reserve(numVertexGroups); + std::unordered_map<std::string,int> known_uris; + for (int i = 0; i < uris.size(); i++) known_uris[uris[i]] = i; + for (const auto & objectPrimitive : objectMesh.primitives) { std::vector<VertexAttribute> vertexAttributes; vertexAttributes.reserve(objectPrimitive.attributes.size()); @@ -416,9 +434,16 @@ int createVertexGroups(fx::gltf::Mesh const& objectMesh, IndexType indexType; std::vector<uint8_t> indexBufferData = {}; const fx::gltf::Accessor& indexAccessor = sceneObjects.accessors[objectPrimitive.indices]; + int indexBufferURI; if (objectPrimitive.indices >= 0 && !probe) { // if there is no index buffer, -1 is returned from fx-gltf const fx::gltf::BufferView& indexBufferView = sceneObjects.bufferViews[indexAccessor.bufferView]; const fx::gltf::Buffer& indexBuffer = sceneObjects.buffers[indexBufferView.buffer]; + if (known_uris.count(indexBuffer.uri)) { + indexBufferURI = known_uris[indexBuffer.uri]; + } else { + indexBufferURI = uris.size(); + uris.push_back(indexBuffer.uri); + } indexBufferData.resize(indexBufferView.byteLength); { @@ -438,6 +463,13 @@ int createVertexGroups(fx::gltf::Mesh const& objectMesh, const fx::gltf::BufferView& vertexBufferView = sceneObjects.bufferViews[posAccessor.bufferView]; const fx::gltf::Buffer& vertexBuffer = sceneObjects.buffers[vertexBufferView.buffer]; + int vertexBufferURI; + if (known_uris.count(vertexBuffer.uri)) { + vertexBufferURI = known_uris[vertexBuffer.uri]; + } else { + vertexBufferURI = uris.size(); + uris.push_back(vertexBuffer.uri); + } // only copy relevant part of vertex data uint32_t relevantBufferOffset = std::numeric_limits<uint32_t>::max(); @@ -470,8 +502,8 @@ int createVertexGroups(fx::gltf::Mesh const& objectMesh, static_cast<PrimitiveMode>(objectPrimitive.mode), sceneObjects.accessors[objectPrimitive.indices].count, posAccessor.count, - {indexType, indexBufferData}, - {vertexBufferData, vertexAttributes}, + {indexBufferURI, indexType, indexBufferData}, + {vertexBufferURI, vertexBufferData, vertexAttributes}, {posAccessor.min[0], posAccessor.min[1], posAccessor.min[2]}, {posAccessor.max[0], posAccessor.max[1], posAccessor.max[2]}, static_cast<uint8_t>(objectPrimitive.material) @@ -573,13 +605,16 @@ int loadScene(const std::filesystem::path &path, Scene &scene){ std::vector<Sampler> samplers; std::vector<Mesh> meshes; std::vector<VertexGroup> vertexGroups; + std::vector<std::string> uris; int groupCount = 0; for (size_t i = 0; i < sceneObjects.meshes.size(); i++){ std::vector<int> vertexGroupsIndices; fx::gltf::Mesh const &objectMesh = sceneObjects.meshes[i]; - if (createVertexGroups(objectMesh, sceneObjects, vertexGroups, vertexGroupsIndices, groupCount, false) != ASSET_SUCCESS) { + if (createVertexGroups(objectMesh, sceneObjects, vertexGroups, + vertexGroupsIndices, uris, groupCount, + false) != ASSET_SUCCESS) { vkcv_log(LogLevel::ERROR, "Failed to get Vertex Groups!"); return ASSET_ERROR; } @@ -603,7 +638,7 @@ int loadScene(const std::filesystem::path &path, Scene &scene){ } } - if (createTextures(sceneObjects.textures, sceneObjects.images,sceneObjects.buffers,sceneObjects.bufferViews, dir, textures) != ASSET_SUCCESS) { + if (createTextures(sceneObjects.textures, sceneObjects.images,sceneObjects.buffers,sceneObjects.bufferViews, dir, uris, textures) != ASSET_SUCCESS) { size_t missing = sceneObjects.textures.size() - textures.size(); vkcv_log(LogLevel::ERROR, "Failed to get %lu textures from glTF source '%s'", missing, path.c_str()); @@ -685,6 +720,7 @@ int probeScene(const std::filesystem::path& path, Scene& scene) { std::vector<Sampler> samplers; std::vector<Mesh> meshes; std::vector<VertexGroup> vertexGroups; + std::vector<std::string> uris; int groupCount = 0; std::set<std::string> names; @@ -692,7 +728,9 @@ int probeScene(const std::filesystem::path& path, Scene& scene) { std::vector<int> vertexGroupsIndices; fx::gltf::Mesh const& objectMesh = sceneObjects.meshes[i]; - if (createVertexGroups(objectMesh, sceneObjects, vertexGroups, vertexGroupsIndices, groupCount, true) != ASSET_SUCCESS) { + if (createVertexGroups(objectMesh, sceneObjects, vertexGroups, + vertexGroupsIndices, uris, groupCount, + true) != ASSET_SUCCESS) { vkcv_log(LogLevel::ERROR, "Failed to get Vertex Groups!"); return ASSET_ERROR; } @@ -722,7 +760,7 @@ int probeScene(const std::filesystem::path& path, Scene& scene) { } } - /*if (createTextures(sceneObjects.textures, sceneObjects.images, sceneObjects.buffers, sceneObjects.bufferViews, dir, textures) != ASSET_SUCCESS) { + /*if (createTextures(sceneObjects.textures, sceneObjects.images, sceneObjects.buffers, sceneObjects.bufferViews, dir, uris, textures) != ASSET_SUCCESS) { size_t missing = sceneObjects.textures.size() - textures.size(); vkcv_log(LogLevel::ERROR, "Failed to get %lu textures from glTF source '%s'", missing, path.c_str()); @@ -786,6 +824,7 @@ int loadMesh(const std::filesystem::path &path, const std::string &name, Scene & std::vector<Sampler> samplers; std::vector<Mesh> meshes; std::vector<VertexGroup> vertexGroups; + std::vector<std::string> uris; int groupCount = 0; int meshIndex = -1; @@ -794,7 +833,11 @@ int loadMesh(const std::filesystem::path &path, const std::string &name, Scene & std::vector<int> vertexGroupsIndices; fx::gltf::Mesh const& objectMesh = sceneObjects.meshes[i]; - if (createVertexGroups(objectMesh, sceneObjects, vertexGroups, vertexGroupsIndices, groupCount, false) != ASSET_SUCCESS) { + if (createVertexGroups(objectMesh, sceneObjects, + vertexGroups, + vertexGroupsIndices, uris, + groupCount, false) + != ASSET_SUCCESS) { vkcv_log(LogLevel::ERROR, "Failed to get Vertex Groups!"); return ASSET_ERROR; } @@ -824,7 +867,7 @@ int loadMesh(const std::filesystem::path &path, const std::string &name, Scene & ); } - if (createTextures(sceneObjects.textures, sceneObjects.images, sceneObjects.buffers, sceneObjects.bufferViews, dir, textures) != ASSET_SUCCESS) { + if (createTextures(sceneObjects.textures, sceneObjects.images, sceneObjects.buffers, sceneObjects.bufferViews, dir, uris, textures) != ASSET_SUCCESS) { size_t missing = sceneObjects.textures.size() - textures.size(); vkcv_log(LogLevel::ERROR, "Failed to get %lu textures from glTF source '%s'", missing, path.c_str()); -- GitLab