diff options
Diffstat (limited to 'assetFactory')
-rw-r--r-- | assetFactory/cuboid.cpp | 16 | ||||
-rw-r--r-- | assetFactory/cuboid.h | 2 | ||||
-rw-r--r-- | assetFactory/cylinder.cpp | 75 | ||||
-rw-r--r-- | assetFactory/cylinder.h | 2 | ||||
-rw-r--r-- | assetFactory/factoryMesh.cpp | 2 | ||||
-rw-r--r-- | assetFactory/modelFactoryMesh.cpp | 8 | ||||
-rw-r--r-- | assetFactory/modelFactoryMesh.h | 9 | ||||
-rw-r--r-- | assetFactory/mutation.cpp | 19 | ||||
-rw-r--r-- | assetFactory/mutation.h | 4 | ||||
-rw-r--r-- | assetFactory/object.cpp | 4 | ||||
-rw-r--r-- | assetFactory/object.h | 2 | ||||
-rw-r--r-- | assetFactory/plane.cpp | 4 | ||||
-rw-r--r-- | assetFactory/plane.h | 2 | ||||
-rw-r--r-- | assetFactory/shape.cpp | 6 | ||||
-rw-r--r-- | assetFactory/shape.h | 8 | ||||
-rw-r--r-- | assetFactory/use.cpp | 26 | ||||
-rw-r--r-- | assetFactory/use.h | 2 |
17 files changed, 120 insertions, 71 deletions
diff --git a/assetFactory/cuboid.cpp b/assetFactory/cuboid.cpp index 24fe4a4..f200258 100644 --- a/assetFactory/cuboid.cpp +++ b/assetFactory/cuboid.cpp @@ -2,7 +2,7 @@ #include "modelFactoryMesh.h" Cuboid::CreatedFaces -Cuboid::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const +Cuboid::createMesh(ModelFactoryMesh & mesh, float) const { static constexpr std::array<glm::vec3, 8> VERTICES {{ // bottom @@ -17,13 +17,13 @@ Cuboid::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) c {n, n, o}, }}; - const auto vhs = addMutatedToMesh(mesh, VERTICES, mutation); + const auto vhs = addToMesh(mesh, VERTICES); return { - mesh.add_namedFace("top", {vhs[4], vhs[5], vhs[6], vhs[7]}), - mesh.add_namedFace("bottom", {vhs[0], vhs[1], vhs[2], vhs[3]}), - mesh.add_namedFace("left", {vhs[0], vhs[7], vhs[6], vhs[1]}), - mesh.add_namedFace("right", {vhs[2], vhs[5], vhs[4], vhs[3]}), - mesh.add_namedFace("front", {vhs[0], vhs[3], vhs[4], vhs[7]}), - mesh.add_namedFace("back", {vhs[2], vhs[1], vhs[6], vhs[5]}), + mesh.add_namedFace("top", vhs[4], vhs[5], vhs[6], vhs[7]), + mesh.add_namedFace("bottom", vhs[0], vhs[1], vhs[2], vhs[3]), + mesh.add_namedFace("left", vhs[0], vhs[7], vhs[6], vhs[1]), + mesh.add_namedFace("right", vhs[2], vhs[5], vhs[4], vhs[3]), + mesh.add_namedFace("front", vhs[0], vhs[3], vhs[4], vhs[7]), + mesh.add_namedFace("back", vhs[2], vhs[1], vhs[6], vhs[5]), }; } diff --git a/assetFactory/cuboid.h b/assetFactory/cuboid.h index 5a4072a..4e375a9 100644 --- a/assetFactory/cuboid.h +++ b/assetFactory/cuboid.h @@ -4,5 +4,5 @@ class Cuboid : public Shape { public: - CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override; + CreatedFaces createMesh(ModelFactoryMesh & mesh, float lodf) const override; }; diff --git a/assetFactory/cylinder.cpp b/assetFactory/cylinder.cpp index cf0dbfb..0803369 100644 --- a/assetFactory/cylinder.cpp +++ b/assetFactory/cylinder.cpp @@ -3,44 +3,51 @@ #include "modelFactoryMesh.h" Cylinder::CreatedFaces -Cylinder::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const +Cylinder::createMesh(ModelFactoryMesh & mesh, float lodf) const { - const glm::vec2 scale {std::accumulate(&mutation[0][0], &mutation[0][3], 0.f), - std::accumulate(&mutation[1][0], &mutation[1][3], 0.f)}; - const unsigned int P = static_cast<unsigned int>(std::round(15.F * std::sqrt(glm::length(scale)))); - std::vector<OpenMesh::VertexHandle> bottom(P), top(P); - std::generate_n(bottom.begin(), P, [a = 0.f, step = two_pi / static_cast<float>(P), &mesh, &mutation]() mutable { - const auto xy = sincosf(a += step) * .5F; - const auto xyz = (xy ^ 0) % mutation; - return mesh.add_vertex({xyz.x, xyz.y, xyz.z}); - }); - std::generate_n(top.begin(), P, [a = 0.f, step = two_pi / static_cast<float>(P), &mesh, &mutation]() mutable { - const auto xy = sincosf(a -= step) * .5F; - const auto xyz = (xy ^ 1) % mutation; - return mesh.add_vertex({xyz.x, xyz.y, xyz.z}); + const auto P = static_cast<unsigned int>(std::round(15.F * std::sqrt(lodf))); + const auto step = two_pi / static_cast<float>(P); + + // Generate 2D circumference points + std::vector<glm::vec2> circumference(P); + std::generate(circumference.begin(), circumference.end(), [a = 0.f, step]() mutable { + return sincosf(a += step) * .5F; }); + CreatedFaces surface; - std::generate_n(std::inserter(surface, surface.end()), P, - [a = 0.f, step = two_pi / static_cast<float>(P), &mesh, &mutation]() mutable { - const auto xy1 = sincosf(a) * .5F; - const auto xy2 = sincosf(a -= step) * .5F; - const auto xyz1b = (xy1 ^ 0) % mutation; - const auto xyz2b = (xy2 ^ 0) % mutation; - const auto xyz1t = (xy1 ^ 1) % mutation; - const auto xyz2t = (xy2 ^ 1) % mutation; - return mesh.add_namedFace("edge", - { - mesh.add_vertex({xyz1b.x, xyz1b.y, xyz1b.z}), - mesh.add_vertex({xyz2b.x, xyz2b.y, xyz2b.z}), - mesh.add_vertex({xyz2t.x, xyz2t.y, xyz2t.z}), - mesh.add_vertex({xyz1t.x, xyz1t.y, xyz1t.z}), - }); - }); - for (const auto & [name, face] : surface) { - mesh.property(mesh.smoothFaceProperty, face) = true; + { + // Generate bottom face vertices + std::vector<OpenMesh::VertexHandle> bottom(P); + std::transform(circumference.begin(), circumference.end(), bottom.begin(), [&mesh](const auto & xy) { + return mesh.add_vertex({xy.x, xy.y, 0.f}); + }); + surface.insert(mesh.add_namedFace("bottom", bottom)); + } + { + // Generate top face vertices + std::vector<OpenMesh::VertexHandle> top(P); + std::transform(circumference.rbegin(), circumference.rend(), top.begin(), [&mesh](const auto & xy) { + return mesh.add_vertex({xy.x, xy.y, 1.f}); + }); + surface.insert(mesh.add_namedFace("top", top)); + } + { + // Generate edge vertices + std::vector<std::pair<OpenMesh::VertexHandle, OpenMesh::VertexHandle>> edge(P + 1); + std::transform(circumference.begin(), circumference.end(), edge.begin(), [&mesh](const auto & xy) { + return std::make_pair(mesh.add_vertex({xy.x, xy.y, 0.f}), mesh.add_vertex({xy.x, xy.y, 1.f})); + }); + // Wrap around + edge.back() = edge.front(); + // Transform adjacent pairs of top/bottom pairs to faces + std::adjacent_find(edge.begin(), edge.end(), [&mesh, &surface](const auto & first, const auto & second) { + const auto fh + = surface.insert(mesh.add_namedFace("edge", first.first, first.second, second.second, second.first)) + ->second; + mesh.property(mesh.smoothFaceProperty, fh) = true; + return false; + }); } - surface.insert(mesh.add_namedFace("bottom", bottom)); - surface.insert(mesh.add_namedFace("top", top)); return surface; } diff --git a/assetFactory/cylinder.h b/assetFactory/cylinder.h index 65ca5e5..1d7b0e0 100644 --- a/assetFactory/cylinder.h +++ b/assetFactory/cylinder.h @@ -4,5 +4,5 @@ class Cylinder : public Shape { public: - CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override; + CreatedFaces createMesh(ModelFactoryMesh & mesh, float lodf) const override; }; diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp index 0cfed85..1665b90 100644 --- a/assetFactory/factoryMesh.cpp +++ b/assetFactory/factoryMesh.cpp @@ -11,7 +11,7 @@ FactoryMesh::createMesh() const ModelFactoryMesh mesh; for (const auto & use : uses) { - use->createMesh(mesh, glm::identity<Mutation::Matrix>()); + use->createMesh(mesh, 1); } mesh.garbage_collection(); diff --git a/assetFactory/modelFactoryMesh.cpp b/assetFactory/modelFactoryMesh.cpp index f9ee6a0..806ac3b 100644 --- a/assetFactory/modelFactoryMesh.cpp +++ b/assetFactory/modelFactoryMesh.cpp @@ -5,11 +5,3 @@ ModelFactoryMesh::ModelFactoryMesh() add_property(smoothFaceProperty); add_property(nameFaceProperty); } - -std::pair<std::string, OpenMesh::FaceHandle> -ModelFactoryMesh::add_namedFace(std::string name, std::vector<OpenMesh::VertexHandle> p) -{ - const auto handle = add_face(std::move(p)); - property(nameFaceProperty, handle) = name; - return std::make_pair(name, handle); -} diff --git a/assetFactory/modelFactoryMesh.h b/assetFactory/modelFactoryMesh.h index 258913b..ea5f011 100644 --- a/assetFactory/modelFactoryMesh.h +++ b/assetFactory/modelFactoryMesh.h @@ -35,5 +35,12 @@ struct ModelFactoryMesh : public OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTra OpenMesh::FPropHandleT<bool> smoothFaceProperty; OpenMesh::FPropHandleT<std::string> nameFaceProperty; - std::pair<std::string, OpenMesh::FaceHandle> add_namedFace(std::string name, std::vector<OpenMesh::VertexHandle> p); + template<typename... Vs> + std::pair<std::string, OpenMesh::FaceHandle> + add_namedFace(std::string name, Vs &&... vs) + { + const auto handle = add_face(std::forward<Vs>(vs)...); + property(nameFaceProperty, handle) = name; + return std::make_pair(name, handle); + } }; diff --git a/assetFactory/mutation.cpp b/assetFactory/mutation.cpp index 21d2a24..9722dc3 100644 --- a/assetFactory/mutation.cpp +++ b/assetFactory/mutation.cpp @@ -1,4 +1,5 @@ #include "mutation.h" +#include <algorithm> #include <glm/gtx/transform.hpp> #include <maths.h> @@ -8,3 +9,21 @@ Mutation::getMatrix() const return glm::translate(glm::identity<Matrix>(), position) * rotate_ypr(rotation) * glm::scale(glm::identity<Matrix>(), scale); } + +Mutation::Matrix +Mutation::getDeformationMatrix() const +{ + return glm::scale(glm::identity<Matrix>(), scale); +} + +Mutation::Matrix +Mutation::getLocationMatrix() const +{ + return glm::translate(glm::identity<Matrix>(), position) * rotate_ypr(rotation); +} + +float +Mutation::relativeLevelOfDetail() const +{ + return std::max({scale.x, scale.y, scale.z}); +} diff --git a/assetFactory/mutation.h b/assetFactory/mutation.h index 440fab0..e620955 100644 --- a/assetFactory/mutation.h +++ b/assetFactory/mutation.h @@ -7,6 +7,10 @@ struct Mutation { using Matrix = glm::mat4; Matrix getMatrix() const; + Matrix getDeformationMatrix() const; + Matrix getLocationMatrix() const; + + float relativeLevelOfDetail() const; glm::vec3 position {}; glm::vec3 rotation {}; diff --git a/assetFactory/object.cpp b/assetFactory/object.cpp index ae5a301..5c86f47 100644 --- a/assetFactory/object.cpp +++ b/assetFactory/object.cpp @@ -4,11 +4,11 @@ Object::Object(std::string i) : id {std::move(i)} { } Object::CreatedFaces -Object::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const +Object::createMesh(ModelFactoryMesh & mesh, float levelOfDetailFactor) const { CreatedFaces faces; for (const auto & use : uses) { - auto useFaces = use->createMesh(mesh, mutation); + auto useFaces = use->createMesh(mesh, levelOfDetailFactor); std::transform(useFaces.begin(), useFaces.end(), std::inserter(faces, faces.end()), [this](auto && face) { return std::make_pair(id + ":" + face.first, std::move(face.second)); }); diff --git a/assetFactory/object.h b/assetFactory/object.h index f3726c7..3f7b640 100644 --- a/assetFactory/object.h +++ b/assetFactory/object.h @@ -10,7 +10,7 @@ public: Object() = default; Object(std::string i); - CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override; + CreatedFaces createMesh(ModelFactoryMesh & mesh, float lodf) const override; Use::Collection uses; std::string id; diff --git a/assetFactory/plane.cpp b/assetFactory/plane.cpp index 563c4e9..c6e1b5a 100644 --- a/assetFactory/plane.cpp +++ b/assetFactory/plane.cpp @@ -2,7 +2,7 @@ #include "modelFactoryMesh.h" Plane::CreatedFaces -Plane::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const +Plane::createMesh(ModelFactoryMesh & mesh, float) const { static constexpr std::array<glm::vec3, 4> VERTICES {{ {n, n, z}, @@ -11,5 +11,5 @@ Plane::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) co {n, y, z}, }}; - return {mesh.add_namedFace("plane", addMutatedToMesh(mesh, VERTICES, mutation))}; + return {mesh.add_namedFace("plane", addToMesh(mesh, VERTICES))}; } diff --git a/assetFactory/plane.h b/assetFactory/plane.h index 5e93ee4..f24e2c1 100644 --- a/assetFactory/plane.h +++ b/assetFactory/plane.h @@ -4,5 +4,5 @@ class Plane : public Shape { public: - CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override; + CreatedFaces createMesh(ModelFactoryMesh & mesh, float lodf) const override; }; diff --git a/assetFactory/shape.cpp b/assetFactory/shape.cpp index f6e55e8..ec6594e 100644 --- a/assetFactory/shape.cpp +++ b/assetFactory/shape.cpp @@ -5,12 +5,10 @@ #include "shape.h" std::vector<OpenMesh::VertexHandle> -Shape::addMutatedToMesh( - ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices, const Mutation::Matrix & mutation) +Shape::addToMesh(ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices) { std::vector<OpenMesh::VertexHandle> vhs; - std::transform(vertices.begin(), vertices.end(), std::back_inserter(vhs), [&mesh, &mutation](const auto & v) { - const auto p = v % mutation; + std::transform(vertices.begin(), vertices.end(), std::back_inserter(vhs), [&mesh](const auto & p) { return mesh.add_vertex({p.x, p.y, p.z}); }); return vhs; diff --git a/assetFactory/shape.h b/assetFactory/shape.h index 5a2b59c..fe517c1 100644 --- a/assetFactory/shape.h +++ b/assetFactory/shape.h @@ -1,9 +1,9 @@ #pragma once #include "modelFactoryMesh_fwd.h" -#include "mutation.h" #include "stdTypeDefs.hpp" #include <OpenMesh/Core/Mesh/Handles.hh> +#include <glm/vec3.hpp> #include <map> #include <span> #include <string> @@ -18,8 +18,8 @@ public: virtual ~Shape() = default; - virtual CreatedFaces createMesh(ModelFactoryMesh &, const Mutation::Matrix & mutation) const = 0; + virtual CreatedFaces createMesh(ModelFactoryMesh &, float levelOfDetailFactor) const = 0; - static std::vector<OpenMesh::VertexHandle> addMutatedToMesh( - ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices, const Mutation::Matrix & mutation); + static std::vector<OpenMesh::VertexHandle> addToMesh( + ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices); }; diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp index 708e310..898b736 100644 --- a/assetFactory/use.cpp +++ b/assetFactory/use.cpp @@ -1,14 +1,36 @@ #include "use.h" #include "assetFactory.h" +#include <glm/ext/matrix_transform.hpp> +#include <glm/matrix.hpp> +#include <maths.h> +#include <set> +#include <stream_support.hpp> Shape::CreatedFaces -Use::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const +Use::createMesh(ModelFactoryMesh & mesh, float levelOfDetailFactor) const { - auto faces = type->createMesh(mesh, mutation * getMatrix()); + auto apply = [&mesh](const auto & faces, const Mutation::Matrix & m) { + std::set<ModelFactoryMesh::VertexHandle> vs; + for (const auto & f : faces) { + const auto fvr = mesh.fv_range(f.second); + for (const auto & v : fvr) { + if (!vs.contains(v)) { + glm::vec3 p = mesh.point(v); + p = p % m; + mesh.set_point(v, ModelFactoryMesh::Point(p.x, p.y, p.z)); + vs.insert(v); + } + } + } + }; + + auto faces = type->createMesh(mesh, levelOfDetailFactor * relativeLevelOfDetail()); applyStyle(mesh, {this}, faces); + apply(faces, getDeformationMatrix()); for (const auto & [name, faceController] : faceControllers) { faceController->apply(mesh, {this}, name, faces); } + apply(faces, getLocationMatrix()); return faces; } diff --git a/assetFactory/use.h b/assetFactory/use.h index 5e4c35f..9dbf382 100644 --- a/assetFactory/use.h +++ b/assetFactory/use.h @@ -11,7 +11,7 @@ class Use : public StdTypeDefs<Use>, public Mutation, public Style, public Persi public: using FaceControllers = std::map<std::string, std::unique_ptr<FaceController>>; - Shape::CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const; + Shape::CreatedFaces createMesh(ModelFactoryMesh & mesh, float lodf) const; Shape::CPtr type; FaceControllers faceControllers; |