From b25bc3cc32c5a9057c66ad282fa1cdfe0ed6094a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 10 Apr 2023 18:45:13 +0100 Subject: First cut loading assets using assimp This is far from perfect, specifically the created texture atlas is not compatibile with wrapping texture UVs --- assetFactory/assetFactory.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'assetFactory/assetFactory.h') diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h index 52692c4..7843d44 100644 --- a/assetFactory/assetFactory.h +++ b/assetFactory/assetFactory.h @@ -1,6 +1,7 @@ #pragma once #include "asset.h" +#include "assimp.h" #include "persistence.h" #include "shape.h" #include "textureFragment.h" @@ -12,6 +13,7 @@ class AssetFactory : public Persistence::Persistable { public: using Shapes = std::map>; using Assets = std::map>; + using AssImps = std::map>; using TextureFragments = std::map>; using Colour = glm::vec3; using ColourAlpha = glm::vec4; @@ -26,6 +28,7 @@ public: Shapes shapes; Assets assets; + AssImps assimps; Colours colours; TextureFragments textureFragments; -- cgit v1.2.3 From 1b97b7b4cb126c8b60ac1acbd7e72274f0ddf21f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 13 Apr 2023 02:20:50 +0100 Subject: Use texture atlas for asset factory --- assetFactory/asset.h | 4 ++-- assetFactory/assetFactory.cpp | 26 ++++++++------------------ assetFactory/assetFactory.h | 4 ++-- assetFactory/assimp.cpp | 8 ++++---- assetFactory/factoryMesh.cpp | 3 ++- assetFactory/modelFactoryMesh.cpp | 1 + assetFactory/modelFactoryMesh.h | 2 ++ assetFactory/style.cpp | 9 ++++++++- 8 files changed, 29 insertions(+), 28 deletions(-) (limited to 'assetFactory/assetFactory.h') diff --git a/assetFactory/asset.h b/assetFactory/asset.h index 30f40cd..dba4974 100644 --- a/assetFactory/asset.h +++ b/assetFactory/asset.h @@ -4,11 +4,11 @@ #include "persistence.h" #include -class Texture; +class TextureAtlas; class Asset : public Persistence::Persistable, public StdTypeDefs { public: - using TexturePtr = std::shared_ptr; + using TexturePtr = std::shared_ptr; std::string id; std::string name; diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp index 917edfe..46b4642 100644 --- a/assetFactory/assetFactory.cpp +++ b/assetFactory/assetFactory.cpp @@ -80,17 +80,11 @@ AssetFactory::parseColour(std::string_view in) const throw std::runtime_error("No such asset factory colour"); } -AssetFactory::TextureFragmentCoords -AssetFactory::getTextureCoords(std::string_view id) const +GLuint +AssetFactory::getMaterialIndex(std::string_view id) const { createTexutre(); - const auto & fragmentUV = textureFragmentPositions.at(id); - return { - fragmentUV.xy(), - fragmentUV.zy(), - fragmentUV.zw(), - fragmentUV.xw(), - }; + return textureFragmentPositions.at(id); } Asset::TexturePtr @@ -103,7 +97,7 @@ AssetFactory::getTexture() const void AssetFactory::createTexutre() const { - if (!textureFragments.empty() && (!texture || textureFragmentPositions.empty())) { + if (!textureFragments.empty() && !texture) { // * layout images std::vector imageSizes; std::transform( @@ -112,18 +106,14 @@ AssetFactory::createTexutre() const }); const auto [layout, outSize] = TexturePacker {imageSizes}.pack(); // * create texture - texture = std::make_shared(outSize.x, outSize.y, TextureOptions {.wrap = GL_CLAMP_TO_EDGE}); + texture = std::make_shared(outSize.x, outSize.y, layout.size()); std::transform(textureFragments.begin(), textureFragments.end(), std::inserter(textureFragmentPositions, textureFragmentPositions.end()), - [position = layout.begin(), size = imageSizes.begin(), outSize = glm::vec2 {outSize}]( - const auto & tf) mutable { - const auto positionFraction = glm::vec4 {*position, *position + *size} / outSize.xyxy(); - glTexSubImage2D(GL_TEXTURE_2D, 0, static_cast(position->x), static_cast(position->y), - static_cast(size->x), static_cast(size->y), GL_RGBA, GL_UNSIGNED_BYTE, - tf.second->image->data.data()); + [position = layout.begin(), size = imageSizes.begin(), this](const auto & tf) mutable { + const auto m = texture->add(*position, *size, tf.second->image->data.data()); position++; size++; - return decltype(textureFragmentPositions)::value_type {tf.first, positionFraction}; + return decltype(textureFragmentPositions)::value_type {tf.first, m}; }); } } diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h index 7843d44..9e5d205 100644 --- a/assetFactory/assetFactory.h +++ b/assetFactory/assetFactory.h @@ -23,7 +23,7 @@ public: AssetFactory(); [[nodiscard]] static std::shared_ptr loadXML(const std::filesystem::path &); [[nodiscard]] ColourAlpha parseColour(std::string_view) const; - [[nodiscard]] TextureFragmentCoords getTextureCoords(std::string_view) const; + [[nodiscard]] GLuint getMaterialIndex(std::string_view) const; [[nodiscard]] Asset::TexturePtr getTexture() const; Shapes shapes; @@ -42,5 +42,5 @@ private: void createTexutre() const; mutable Asset::TexturePtr texture; - mutable std::map> textureFragmentPositions; + mutable std::map> textureFragmentPositions; }; diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp index 0c6cb86..dd82105 100644 --- a/assetFactory/assimp.cpp +++ b/assetFactory/assimp.cpp @@ -64,11 +64,11 @@ public: }; const auto & m = *scene->mMaterials[amesh->mMaterialIndex]; - AssetFactory::TextureFragmentCoords tfc; + GLuint material {}; if (auto mf = Persistence::ParseBase::getShared("assetFactory")) { aiString path; m.Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path); - tfc = mf->getTextureCoords(path.C_Str()); + material = mf->getMaterialIndex(path.C_Str()); } for (const auto & f : AIRANGE(amesh, Faces)) { @@ -79,8 +79,8 @@ public: if (amesh->HasTextureCoords(0)) { for (auto idx = f.mIndices; const auto fheh : mesh.fh_range(fh)) { const auto ouv = !amesh->mTextureCoords[0][*idx++]; - const auto uv = glm::mix(tfc[0], tfc[2], ouv); - mesh.set_texcoord2D(fheh, uv); + mesh.set_texcoord2D(fheh, ouv); + mesh.property(mesh.materialFaceProperty, fh) = material; } } } diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp index 4922936..f7bc7c8 100644 --- a/assetFactory/factoryMesh.cpp +++ b/assetFactory/factoryMesh.cpp @@ -18,6 +18,7 @@ FactoryMesh::createMesh() const for (const auto & face : mesh.faces()) { const auto & smooth = mesh.property(mesh.smoothFaceProperty, face); const auto & colour = mesh.color(face); + const auto & material = mesh.property(mesh.materialFaceProperty, face); std::vector faceIndices; for (const auto & heh : mesh.fh_range(face)) { @@ -26,7 +27,7 @@ FactoryMesh::createMesh() const const auto & point = mesh.point(vertex); const auto & normal = smooth ? mesh.property(mesh.vertex_normals_pph(), vertex) : mesh.property(mesh.face_normals_pph(), face); - Vertex outVertex {point, textureUV, normal, colour}; + Vertex outVertex {point, textureUV, normal, colour, material}; if (const auto existingItr = std::find(vertices.rbegin(), vertices.rend(), outVertex); existingItr != vertices.rend()) { faceIndices.push_back(static_cast(std::distance(existingItr, vertices.rend()) - 1)); diff --git a/assetFactory/modelFactoryMesh.cpp b/assetFactory/modelFactoryMesh.cpp index e640502..3d4b5f3 100644 --- a/assetFactory/modelFactoryMesh.cpp +++ b/assetFactory/modelFactoryMesh.cpp @@ -3,6 +3,7 @@ ModelFactoryMesh::ModelFactoryMesh() { add_property(smoothFaceProperty); + add_property(materialFaceProperty); add_property(nameFaceProperty); add_property(nameAdjFaceProperty); } diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h index 8ac2edd..4eac7ee 100644 --- a/assetFactory/modelFactoryMesh.h +++ b/assetFactory/modelFactoryMesh.h @@ -1,6 +1,7 @@ #pragma once #include "modelFactoryMesh_fwd.h" +#include #include #include #include @@ -47,6 +48,7 @@ struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT smoothFaceProperty; + OpenMesh::FPropHandleT materialFaceProperty; OpenMesh::FPropHandleT nameFaceProperty; OpenMesh::HPropHandleT nameAdjFaceProperty; diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp index 12346a6..ea67fc2 100644 --- a/assetFactory/style.cpp +++ b/assetFactory/style.cpp @@ -30,7 +30,14 @@ Style::applyStyle( else { mesh.set_color(face, {}); if (auto mf = Persistence::ParseBase::getShared("assetFactory")) { - auto coords = mf->getTextureCoords(texture); + const auto material = mf->getMaterialIndex(texture); + mesh.property(mesh.materialFaceProperty, face) = material; + static constexpr std::array coords {{ + {0.f, 0.f}, + {1.f, 0.f}, + {1.f, 1.f}, + {0.f, 1.f}, + }}; auto coord = coords.begin(); // Wild assumption that face is a quad and the texture should apply linearly for (const auto & heh : mesh.fh_range(face)) { -- cgit v1.2.3 From 47cd9d863fb09acb82d2428f881d61242f8ab437 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Apr 2023 17:33:02 +0100 Subject: Load all assets in red dir with asset factory --- application/main.cpp | 9 ++++++++- assetFactory/assetFactory.cpp | 13 +++++++++++++ assetFactory/assetFactory.h | 1 + test/test-assetFactory.cpp | 7 +++++++ 4 files changed, 29 insertions(+), 1 deletion(-) (limited to 'assetFactory/assetFactory.h') diff --git a/application/main.cpp b/application/main.cpp index 1f91dab..aea3d2e 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -11,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -43,6 +46,7 @@ public: world.create(geoData); { + const auto assets = AssetFactory::loadAll("res"); auto rl = world.create(); const glm::vec3 j {-1120, -1100, 3}, k {-1100, -1000, 15}, l {-1000, -800, 20}, m {-900, -600, 30}, n {-600, -500, 32}, o {-500, -800, 30}, p {-600, -900, 25}, q {-1025, -1175, 10}, @@ -66,13 +70,16 @@ public: rl->addLinksBetween(t, u); rl->addLinksBetween(u, m); const std::shared_ptr train = world.create(l3); - auto b47 = std::make_shared("brush47"); + auto b47 = std::dynamic_pointer_cast(assets.at("brush-47")); for (int N = 0; N < 6; N++) { train->create(b47); } train->orders.removeAll(); train->orders.create(&train->orders, l3->ends[1], l3->length, rl->findNodeAt({-1100, -450, 15})); train->currentActivity = train->orders.current()->createActivity(); + + auto foliage = std::dynamic_pointer_cast(assets.at("Tree-01-1")); + world.create(foliage, Location {{-1100, -1100, 0}}); } auto t_start = std::chrono::high_resolution_clock::now(); diff --git a/assetFactory/assetFactory.cpp b/assetFactory/assetFactory.cpp index 05f0634..af0cd54 100644 --- a/assetFactory/assetFactory.cpp +++ b/assetFactory/assetFactory.cpp @@ -11,6 +11,7 @@ #include "resource.h" #include "saxParse-persistence.h" #include "texturePacker.h" +#include AssetFactory::AssetFactory() : shapes { @@ -29,6 +30,18 @@ AssetFactory::loadXML(const std::filesystem::path & filename) return Persistence::SAXParsePersistence {}.loadState>(file); } +AssetFactory::Assets +AssetFactory::loadAll(const std::filesystem::path & root) +{ + return std::accumulate(std::filesystem::recursive_directory_iterator {root}, + std::filesystem::recursive_directory_iterator {}, Assets {}, [](auto && out, auto && path) { + if (path.path().extension() == ".xml") { + out.merge(loadXML(path)->assets); + } + return std::move(out); + }); +} + AssetFactory::Colours AssetFactory::parseX11RGB(const char * path) { diff --git a/assetFactory/assetFactory.h b/assetFactory/assetFactory.h index 9e5d205..e449ce2 100644 --- a/assetFactory/assetFactory.h +++ b/assetFactory/assetFactory.h @@ -22,6 +22,7 @@ public: AssetFactory(); [[nodiscard]] static std::shared_ptr loadXML(const std::filesystem::path &); + [[nodiscard]] static Assets loadAll(const std::filesystem::path &); [[nodiscard]] ColourAlpha parseColour(std::string_view) const; [[nodiscard]] GLuint getMaterialIndex(std::string_view) const; [[nodiscard]] Asset::TexturePtr getTexture() const; diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index c425e71..3d79213 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -115,6 +115,13 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5)) } BOOST_AUTO_TEST_SUITE_END(); +BOOST_AUTO_TEST_CASE(loadall) +{ + const auto assets = AssetFactory::loadAll(RESDIR); + BOOST_CHECK(assets.at("brush-47")); + BOOST_CHECK(assets.at("Tree-01-1")); +} + template using InOut = std::tuple; BOOST_DATA_TEST_CASE(normalizeColourName, boost::unit_test::data::make>({ -- cgit v1.2.3