From 11ed1540ab771c862ad7d37282c5ce426639fa74 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 5 Feb 2026 00:54:10 -0500 Subject: [PATCH] Managed to get the monkey to load by patching simdjson 3.3.0 to fix a dubious 3 lines of code as mentioned here: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=280590 then have fastgltf _NOT_ download simdjson again. --- basicmesh.glb.gz | Bin 33597 -> 33597 bytes meson.build | 4 +- vk_engine.cpp | 2 +- vk_loader.cpp | 238 +++++++++++++++++++++----------------------- vk_loader.h | 1 + wraps/fastgltf.wrap | 2 +- 6 files changed, 122 insertions(+), 125 deletions(-) diff --git a/basicmesh.glb.gz b/basicmesh.glb.gz index 50829341c32723916f10743d9e087e674d73c7d2..9de0ed5d2c378b824a3596cd70e749567cb1bb84 100644 GIT binary patch delta 18 Zcmdnn# +#include "vendor/stb_image.h" +#include #include "vk_engine.h" #include "vk_initializers.h" @@ -8,134 +8,128 @@ #include #include -#include +#include #include -constexpr bool OverrideColors = true; - std::optional>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath) { - std::println("\nLoading GLTF: {}", filePath.string()); - auto data = fastgltf::GltfDataBuffer::FromPath(filePath); +//> openmesh + std::cout << "\nLoading GLTF: " << filePath << std::endl; - if(data.error() != fastgltf::Error::None) { - std::println("Failed to load glTF: {}={}\n", - typeid(data.error()).name(), - fastgltf::to_underlying(data.error())); - return std::nullopt; - } + fastgltf::GltfDataBuffer data; + data.loadFromFile(filePath); - constexpr auto gltfOptions = fastgltf::Options::LoadExternalBuffers; + constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers + | fastgltf::Options::LoadExternalBuffers; - fastgltf::Asset gltf{}; - fastgltf::Parser parser{}; - - auto load = parser.loadGltfBinary(data.get(), filePath.parent_path(), gltfOptions); - - switch(load.error()) { - case fastgltf::Error::None: - gltf = std::move(load.get()); - break; - case fastgltf::Error::InvalidGLB: - std::println("fastgltf says Error::InvalidGLB {}", filePath.string()); - return std::nullopt; - break; - case fastgltf::Error::UnsupportedVersion: - std::println("fastgltf says Error::UnsupportedVersion {}", filePath.string()); - return std::nullopt; - break; - case fastgltf::Error::InvalidPath: - std::println("fastgltf says Error::UnsupportedVersion {}", - filePath.string()); - return std::nullopt; - break; - default: - std::println("Unknown fastgltf error loading {}", filePath.string()); - break; - } - - std::vector> meshes; - // use the same vectors for all meshes - std::vector indices; - std::vector vertices; - - for(auto& mesh : gltf.meshes) { - MeshAsset newmesh; - newmesh.name = mesh.name; - - indices.clear(); - indices.clear(); - - for(auto&& p : mesh.primitives) { - auto& indexAccessor = gltf.accessors[p.indicesAccessor.value()]; - - GeoSurface newSurface { - .startIndex = (uint32_t)indices.size(), - .count = (uint32_t)indexAccessor.count, - }; - - size_t initial_vtx = vertices.size(); - - // load indices - { - indices.reserve(indices.size() + indexAccessor.count); - fastgltf::iterateAccessor( - gltf, indexAccessor, [&](std::uint32_t idx) { - indices.push_back(idx + initial_vtx); - }); - } - - // load vertex positions - { - fastgltf::Accessor& posAccessor = gltf.accessors[ - p.findAttribute("POSITIONS")->accessorIndex]; - vertices.resize(vertices.size() + posAccessor.count); - - fastgltf::iterateAccessorWithIndex( - gltf, posAccessor, [&](glm::vec3 v, size_t index) - { - vertices[initial_vtx + index] = { - .position = v, - .uv_x = 0, - .normal = {1, 0, 0}, - .uv_y = 0, - .color = glm::vec4{1.0f}, - }; - }); - } - - // load vertex normals - auto normals = p.findAttribute("NORMA:"); - if(normals != p.attributes.end()) { - fastgltf::iterateAccessorWithIndex( - gltf, gltf.accessors[(*normals).accessorIndex], - [&](glm::vec3 v, size_t index) - { - vertices[initial_vtx + index].normal = v; - }); - } - - auto uv = p.findAttribute("TEXCOORD_0"); - if(uv != p.attributes.end()) { - fastgltf::iterateAccessorWithIndex( - gltf, gltf.accessors[(*uv).accessorIndex], - [&](glm::vec2 v, size_t index) { - vertices[initial_vtx + index].uv_x = v.x; - vertices[initial_vtx + index].uv_y = v.y; - }); - } - - if(OverrideColors) { - for(Vertex& vtx : vertices) { - vtx.color = glm::vec4(vtx.normal, 1.0f); - } - } - - newmesh.meshBuffers = engine->uploadMesh(indices, vertices); - meshes.emplace_back(std::make_shared(std::move(newmesh))); + fastgltf::Asset gltf; + fastgltf::Parser parser {}; + auto load = parser.loadBinaryGLTF(&data, filePath.parent_path(), gltfOptions); + if (load) { + gltf = std::move(load.get()); + } else { + std::print("Failed to load glTF: {} \n", fastgltf::to_underlying(load.error())); + return {}; } - } +//< openmesh +//> loadmesh + std::vector> meshes; - return meshes; + // use the same vectors for all meshes so that the memory doesnt reallocate as + // often + std::vector indices; + std::vector vertices; + for (fastgltf::Mesh& mesh : gltf.meshes) { + MeshAsset newmesh; + + newmesh.name = mesh.name; + + // clear the mesh arrays each mesh, we dont want to merge them by error + indices.clear(); + vertices.clear(); + + for (auto&& p : mesh.primitives) { + GeoSurface newSurface; + newSurface.startIndex = (uint32_t)indices.size(); + newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count; + + size_t initial_vtx = vertices.size(); + + // load indexes + { + fastgltf::Accessor& indexaccessor = gltf.accessors[p.indicesAccessor.value()]; + indices.reserve(indices.size() + indexaccessor.count); + + fastgltf::iterateAccessor(gltf, indexaccessor, + [&](std::uint32_t idx) { + indices.push_back(idx + initial_vtx); + }); + } + + // load vertex positions + { + fastgltf::Accessor& posAccessor = gltf.accessors[p.findAttribute("POSITION")->second]; + vertices.resize(vertices.size() + posAccessor.count); + + fastgltf::iterateAccessorWithIndex(gltf, posAccessor, + [&](glm::vec3 v, size_t index) { + Vertex newvtx; + newvtx.position = v; + newvtx.normal = { 1, 0, 0 }; + newvtx.color = glm::vec4 { 1.f }; + newvtx.uv_x = 0; + newvtx.uv_y = 0; + vertices[initial_vtx + index] = newvtx; + }); + } + + // load vertex normals + auto normals = p.findAttribute("NORMAL"); + if (normals != p.attributes.end()) { + + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*normals).second], + [&](glm::vec3 v, size_t index) { + vertices[initial_vtx + index].normal = v; + }); + } + + // load UVs + auto uv = p.findAttribute("TEXCOORD_0"); + if (uv != p.attributes.end()) { + + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*uv).second], + [&](glm::vec2 v, size_t index) { + vertices[initial_vtx + index].uv_x = v.x; + vertices[initial_vtx + index].uv_y = v.y; + }); + } + + // load vertex colors + auto colors = p.findAttribute("COLOR_0"); + if (colors != p.attributes.end()) { + + fastgltf::iterateAccessorWithIndex(gltf, gltf.accessors[(*colors).second], + [&](glm::vec4 v, size_t index) { + vertices[initial_vtx + index].color = v; + }); + } + newmesh.surfaces.push_back(newSurface); + } + + // display the vertex normals + constexpr bool OverrideColors = true; + if (OverrideColors) { + for (Vertex& vtx : vertices) { + vtx.color = glm::vec4(vtx.normal, 1.f); + } + } + newmesh.meshBuffers = engine->uploadMesh(indices, vertices); + + meshes.emplace_back(std::make_shared(std::move(newmesh))); + } + + return meshes; + +//< loadmesh } diff --git a/vk_loader.h b/vk_loader.h index 7e553f1..2750e4f 100644 --- a/vk_loader.h +++ b/vk_loader.h @@ -20,3 +20,4 @@ class VulkanEngine; std::optional>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath); + diff --git a/wraps/fastgltf.wrap b/wraps/fastgltf.wrap index db7da81..06cadec 100644 --- a/wraps/fastgltf.wrap +++ b/wraps/fastgltf.wrap @@ -1,7 +1,7 @@ [wrap-git] directory=fastgltf url=https://github.com/spnda/fastgltf.git -revision=v0.9.0 +revision=v0.6.1 depth=1 method=cmake