summaryrefslogtreecommitdiff
path: root/assetFactory
diff options
context:
space:
mode:
Diffstat (limited to 'assetFactory')
-rw-r--r--assetFactory/cuboid.cpp16
-rw-r--r--assetFactory/cuboid.h2
-rw-r--r--assetFactory/cylinder.cpp75
-rw-r--r--assetFactory/cylinder.h2
-rw-r--r--assetFactory/factoryMesh.cpp2
-rw-r--r--assetFactory/modelFactoryMesh.cpp8
-rw-r--r--assetFactory/modelFactoryMesh.h9
-rw-r--r--assetFactory/mutation.cpp19
-rw-r--r--assetFactory/mutation.h4
-rw-r--r--assetFactory/object.cpp4
-rw-r--r--assetFactory/object.h2
-rw-r--r--assetFactory/plane.cpp4
-rw-r--r--assetFactory/plane.h2
-rw-r--r--assetFactory/shape.cpp6
-rw-r--r--assetFactory/shape.h8
-rw-r--r--assetFactory/use.cpp26
-rw-r--r--assetFactory/use.h2
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;