summaryrefslogtreecommitdiff
path: root/assetFactory
diff options
context:
space:
mode:
Diffstat (limited to 'assetFactory')
-rw-r--r--assetFactory/assetFactoryConfig.h28
-rw-r--r--assetFactory/assetFactoryConfig_fwd.h8
-rw-r--r--assetFactory/cuboid.cpp29
-rw-r--r--assetFactory/cuboid.h8
-rw-r--r--assetFactory/cylinder.cpp43
-rw-r--r--assetFactory/cylinder.h8
-rw-r--r--assetFactory/faceController.cpp53
-rw-r--r--assetFactory/faceController.h20
-rw-r--r--assetFactory/factoryMesh.cpp27
-rw-r--r--assetFactory/factoryMesh.h14
-rw-r--r--assetFactory/modelFactory.cpp14
-rw-r--r--assetFactory/modelFactory.h12
-rw-r--r--assetFactory/mutation.cpp10
-rw-r--r--assetFactory/mutation.h14
-rw-r--r--assetFactory/object.cpp17
-rw-r--r--assetFactory/object.h15
-rw-r--r--assetFactory/plane.cpp15
-rw-r--r--assetFactory/plane.h8
-rw-r--r--assetFactory/shape.cpp17
-rw-r--r--assetFactory/shape.h25
-rw-r--r--assetFactory/use.cpp11
-rw-r--r--assetFactory/use.h17
22 files changed, 413 insertions, 0 deletions
diff --git a/assetFactory/assetFactoryConfig.h b/assetFactory/assetFactoryConfig.h
new file mode 100644
index 0000000..171b81a
--- /dev/null
+++ b/assetFactory/assetFactoryConfig.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "assetFactoryConfig_fwd.h"
+#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
+#include <OpenMesh/Core/Mesh/Traits.hh>
+#include <glm/geometric.hpp>
+#include <glm/vec3.hpp>
+
+namespace OpenMesh {
+ template<typename Scalar, int DIM> struct glmvec : public VectorT<Scalar, DIM> {
+ using VectorT<Scalar, DIM>::VectorT;
+ glmvec(const VectorT<Scalar, DIM> & v) : VectorT<Scalar, DIM> {v} { }
+ operator glm::vec<DIM, Scalar>() const
+ {
+ glm::vec<DIM, Scalar> out;
+ std::copy(this->begin(), this->end(), &out[0]);
+ return out;
+ }
+ };
+}
+
+struct ModelFactoryTraits : public OpenMesh::DefaultTraits {
+ FaceAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
+ EdgeAttributes(OpenMesh::Attributes::Status);
+ VertexAttributes(OpenMesh::Attributes::Normal | OpenMesh::Attributes::Status);
+ using Point = OpenMesh::glmvec<float, 3>;
+ using Normal = OpenMesh::glmvec<float, 3>;
+};
diff --git a/assetFactory/assetFactoryConfig_fwd.h b/assetFactory/assetFactoryConfig_fwd.h
new file mode 100644
index 0000000..28489ff
--- /dev/null
+++ b/assetFactory/assetFactoryConfig_fwd.h
@@ -0,0 +1,8 @@
+#pragma once
+
+namespace OpenMesh {
+ template<typename> class PolyMesh_ArrayKernelT;
+}
+struct ModelFactoryTraits;
+
+using ModelFactoryMesh = OpenMesh::PolyMesh_ArrayKernelT<ModelFactoryTraits>;
diff --git a/assetFactory/cuboid.cpp b/assetFactory/cuboid.cpp
new file mode 100644
index 0000000..90b2108
--- /dev/null
+++ b/assetFactory/cuboid.cpp
@@ -0,0 +1,29 @@
+#include "cuboid.h"
+#include "assetFactoryConfig.h"
+
+Cuboid::CreatedFaces
+Cuboid::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const
+{
+ static constexpr std::array<glm::vec3, 8> VERTICES {{
+ // bottom
+ {n, n, z},
+ {n, y, z},
+ {y, y, z},
+ {y, n, z},
+ // top
+ {y, n, o},
+ {y, y, o},
+ {n, y, o},
+ {n, n, o},
+ }};
+
+ const auto vhs = addMutatedToMesh(mesh, VERTICES, mutation);
+ return {
+ {"top", mesh.add_face({vhs[4], vhs[5], vhs[6], vhs[7]})},
+ {"bottom", mesh.add_face({vhs[0], vhs[1], vhs[2], vhs[3]})},
+ {"left", mesh.add_face({vhs[0], vhs[7], vhs[6], vhs[1]})},
+ {"right", mesh.add_face({vhs[2], vhs[5], vhs[4], vhs[3]})},
+ {"front", mesh.add_face({vhs[0], vhs[3], vhs[4], vhs[7]})},
+ {"back", mesh.add_face({vhs[2], vhs[1], vhs[6], vhs[5]})},
+ };
+}
diff --git a/assetFactory/cuboid.h b/assetFactory/cuboid.h
new file mode 100644
index 0000000..5a4072a
--- /dev/null
+++ b/assetFactory/cuboid.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "shape.h"
+
+class Cuboid : public Shape {
+public:
+ CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override;
+};
diff --git a/assetFactory/cylinder.cpp b/assetFactory/cylinder.cpp
new file mode 100644
index 0000000..66d456d
--- /dev/null
+++ b/assetFactory/cylinder.cpp
@@ -0,0 +1,43 @@
+#include "cylinder.h"
+#include "assetFactoryConfig.h"
+#include "maths.h"
+
+Cylinder::CreatedFaces
+Cylinder::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) 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});
+ });
+ 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 std::make_pair(std::string {"edge"},
+ mesh.add_face({
+ 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}),
+ }));
+ });
+ surface.emplace("bottom", mesh.add_face(bottom));
+ surface.emplace("top", mesh.add_face(top));
+
+ return surface;
+}
diff --git a/assetFactory/cylinder.h b/assetFactory/cylinder.h
new file mode 100644
index 0000000..65ca5e5
--- /dev/null
+++ b/assetFactory/cylinder.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "shape.h"
+
+class Cylinder : public Shape {
+public:
+ CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override;
+};
diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp
new file mode 100644
index 0000000..bdef74b
--- /dev/null
+++ b/assetFactory/faceController.cpp
@@ -0,0 +1,53 @@
+#include "faceController.h"
+#include "assetFactoryConfig.h"
+#include "maths.h"
+
+void
+FaceController::apply(ModelFactoryMesh & mesh, const std::string & name, Shape::CreatedFaces & faces) const
+{
+ if (!type.empty()) {
+ const auto mutation = getMatrix();
+ const auto controlledFacesRange = faces.equal_range(name);
+ const std::vector controlledFaces(controlledFacesRange.first, controlledFacesRange.second);
+ faces.erase(name);
+ for (const auto & cf : controlledFaces) {
+ // get face vertices
+ const auto faceVertexRange = mesh.fv_range(cf.second);
+ // get points
+ const std::vector baseVertices(faceVertexRange.begin(), faceVertexRange.end());
+ std::vector<glm::vec3> points;
+ std::transform(
+ faceVertexRange.begin(), faceVertexRange.end(), std::back_inserter(points), [&mesh](auto && v) {
+ return mesh.point(v);
+ });
+ const auto vertexCount = points.size();
+ const auto centre
+ = std::accumulate(points.begin(), points.end(), glm::vec3 {}) / static_cast<float>(vertexCount);
+ if (type == "extrude") {
+ Shape::CreatedFaces newFaces;
+ // mutate points
+ std::for_each(points.begin(), points.end(), [&mutation, &centre](auto && p) {
+ p = centre + ((p - centre) % mutation);
+ });
+ // create new vertices
+ std::vector<OpenMesh::VertexHandle> vertices;
+ std::transform(points.begin(), points.end(), std::back_inserter(vertices), [&mesh](auto && p) {
+ return mesh.add_vertex({p.x, p.y, p.z});
+ });
+ // create new faces
+
+ mesh.delete_face(cf.second);
+ for (size_t idx {}; idx < vertexCount; ++idx) {
+ const auto next = (idx + 1) % vertexCount;
+ newFaces.emplace("extrusion",
+ mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}));
+ }
+ newFaces.emplace(name, mesh.add_face(vertices));
+ for (const auto & [name, faceController] : faceControllers) {
+ faceController.apply(mesh, name, newFaces);
+ }
+ faces.merge(std::move(newFaces));
+ }
+ }
+ }
+}
diff --git a/assetFactory/faceController.h b/assetFactory/faceController.h
new file mode 100644
index 0000000..64c33f3
--- /dev/null
+++ b/assetFactory/faceController.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "assetFactoryConfig_fwd.h"
+#include "mutation.h"
+#include "shape.h"
+#include <map>
+#include <string>
+
+class FaceController : public Mutation {
+public:
+ using FaceControllers = std::map<std::string, FaceController>;
+
+ void apply(ModelFactoryMesh & mesh, const std::string & name, Shape::CreatedFaces & faces) const;
+
+ std::string id;
+ std::string colour;
+ std::string type;
+ bool smooth {false};
+ FaceControllers faceControllers;
+};
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
new file mode 100644
index 0000000..1b89d14
--- /dev/null
+++ b/assetFactory/factoryMesh.cpp
@@ -0,0 +1,27 @@
+#include "factoryMesh.h"
+#include "assetFactoryConfig.h"
+#include "collections.hpp"
+#include "gfx/models/vertex.hpp"
+#include <glm/ext/matrix_transform.hpp>
+
+Mesh::Ptr
+FactoryMesh::createMesh() const
+{
+ constexpr glm::vec2 NullUV {};
+
+ ModelFactoryMesh mesh;
+ for (const auto & use : uses) {
+ use->createMesh(mesh, glm::identity<Mutation::Matrix>());
+ }
+ mesh.garbage_collection();
+
+ mesh.triangulate();
+ mesh.update_face_normals();
+ std::vector<Vertex> vertices;
+ for (const auto & face : mesh.faces()) {
+ for (const auto & vertex : mesh.fv_range(face)) {
+ vertices.emplace_back(mesh.point(vertex), NullUV, mesh.property(mesh.face_normals_pph(), face));
+ }
+ }
+ return std::make_shared<Mesh>(vertices, vectorOfN(vertices.size()));
+}
diff --git a/assetFactory/factoryMesh.h b/assetFactory/factoryMesh.h
new file mode 100644
index 0000000..f850893
--- /dev/null
+++ b/assetFactory/factoryMesh.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "gfx/models/mesh.h"
+#include "stdTypeDefs.hpp"
+#include "use.h"
+
+class FactoryMesh : public StdTypeDefs<FactoryMesh> {
+public:
+ Mesh::Ptr createMesh() const;
+
+ std::string id;
+ glm::vec3 size;
+ Use::Collection uses;
+};
diff --git a/assetFactory/modelFactory.cpp b/assetFactory/modelFactory.cpp
new file mode 100644
index 0000000..3a89157
--- /dev/null
+++ b/assetFactory/modelFactory.cpp
@@ -0,0 +1,14 @@
+#include "modelFactory.h"
+#include "assetFactoryConfig.h"
+#include "cuboid.h"
+#include "cylinder.h"
+#include "plane.h"
+
+ModelFactory::ModelFactory() :
+ shapes {
+ {"plane", std::make_shared<Plane>()},
+ {"cuboid", std::make_shared<Cuboid>()},
+ {"cylinder", std::make_shared<Cylinder>()},
+ }
+{
+}
diff --git a/assetFactory/modelFactory.h b/assetFactory/modelFactory.h
new file mode 100644
index 0000000..f2b1b48
--- /dev/null
+++ b/assetFactory/modelFactory.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "shape.h"
+
+class ModelFactory {
+public:
+ using Shapes = std::map<std::string, Shape::CPtr, std::less<>>;
+
+ ModelFactory();
+
+ Shapes shapes;
+};
diff --git a/assetFactory/mutation.cpp b/assetFactory/mutation.cpp
new file mode 100644
index 0000000..21d2a24
--- /dev/null
+++ b/assetFactory/mutation.cpp
@@ -0,0 +1,10 @@
+#include "mutation.h"
+#include <glm/gtx/transform.hpp>
+#include <maths.h>
+
+Mutation::Matrix
+Mutation::getMatrix() const
+{
+ return glm::translate(glm::identity<Matrix>(), position) * rotate_ypr(rotation)
+ * glm::scale(glm::identity<Matrix>(), scale);
+}
diff --git a/assetFactory/mutation.h b/assetFactory/mutation.h
new file mode 100644
index 0000000..440fab0
--- /dev/null
+++ b/assetFactory/mutation.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <glm/mat4x4.hpp>
+#include <glm/vec3.hpp>
+
+struct Mutation {
+ using Matrix = glm::mat4;
+
+ Matrix getMatrix() const;
+
+ glm::vec3 position {};
+ glm::vec3 rotation {};
+ glm::vec3 scale {1};
+};
diff --git a/assetFactory/object.cpp b/assetFactory/object.cpp
new file mode 100644
index 0000000..8b70676
--- /dev/null
+++ b/assetFactory/object.cpp
@@ -0,0 +1,17 @@
+#include "object.h"
+#include <algorithm>
+
+Object::Object(std::string i) : id {std::move(i)} { }
+
+Object::CreatedFaces
+Object::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const
+{
+ CreatedFaces faces;
+ for (const auto & use : uses) {
+ auto useFaces = use->createMesh(mesh, mutation);
+ 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));
+ });
+ }
+ return faces;
+}
diff --git a/assetFactory/object.h b/assetFactory/object.h
new file mode 100644
index 0000000..f48b78a
--- /dev/null
+++ b/assetFactory/object.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "shape.h"
+#include "stdTypeDefs.hpp"
+#include "use.h"
+
+class Object : public StdTypeDefs<Object>, public Shape {
+public:
+ Object(std::string i);
+
+ CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const;
+
+ Use::Collection uses;
+ std::string id;
+};
diff --git a/assetFactory/plane.cpp b/assetFactory/plane.cpp
new file mode 100644
index 0000000..1e522ad
--- /dev/null
+++ b/assetFactory/plane.cpp
@@ -0,0 +1,15 @@
+#include "plane.h"
+#include "assetFactoryConfig.h"
+
+Plane::CreatedFaces
+Plane::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const
+{
+ static constexpr std::array<glm::vec3, 4> VERTICES {{
+ {n, n, z},
+ {y, n, z},
+ {y, y, z},
+ {n, y, z},
+ }};
+
+ return {{"plane", mesh.add_face(addMutatedToMesh(mesh, VERTICES, mutation))}};
+}
diff --git a/assetFactory/plane.h b/assetFactory/plane.h
new file mode 100644
index 0000000..5e93ee4
--- /dev/null
+++ b/assetFactory/plane.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "shape.h"
+
+class Plane : public Shape {
+public:
+ CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const override;
+};
diff --git a/assetFactory/shape.cpp b/assetFactory/shape.cpp
new file mode 100644
index 0000000..0994898
--- /dev/null
+++ b/assetFactory/shape.cpp
@@ -0,0 +1,17 @@
+#include "shape.h"
+#include "assetFactoryConfig.h"
+#include "gfx/models/vertex.hpp"
+#include "maths.h"
+#include "shape.h"
+
+std::vector<OpenMesh::VertexHandle>
+Shape::addMutatedToMesh(
+ ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices, const Mutation::Matrix & mutation)
+{
+ 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;
+ return mesh.add_vertex({p.x, p.y, p.z});
+ });
+ return vhs;
+}
diff --git a/assetFactory/shape.h b/assetFactory/shape.h
new file mode 100644
index 0000000..9510538
--- /dev/null
+++ b/assetFactory/shape.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "assetFactoryConfig_fwd.h"
+#include "mutation.h"
+#include "stdTypeDefs.hpp"
+#include <OpenMesh/Core/Mesh/Handles.hh>
+#include <map>
+#include <span>
+#include <string>
+
+class Vertex;
+
+class Shape : public StdTypeDefs<Shape> {
+public:
+ using CreatedFaces = std::multimap<std::string, OpenMesh::FaceHandle>;
+
+ static constexpr float z {}, y {.5}, n {-y}, o {1};
+
+ virtual ~Shape() = default;
+
+ virtual CreatedFaces createMesh(ModelFactoryMesh &, const Mutation::Matrix & mutation) const = 0;
+
+ static std::vector<OpenMesh::VertexHandle> addMutatedToMesh(
+ ModelFactoryMesh & mesh, const std::span<const glm::vec3> vertices, const Mutation::Matrix & mutation);
+};
diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp
new file mode 100644
index 0000000..d191329
--- /dev/null
+++ b/assetFactory/use.cpp
@@ -0,0 +1,11 @@
+#include "use.h"
+
+Shape::CreatedFaces
+Use::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const
+{
+ auto faces = type->createMesh(mesh, mutation * getMatrix());
+ for (const auto & [name, faceController] : faceControllers) {
+ faceController.apply(mesh, name, faces);
+ }
+ return faces;
+}
diff --git a/assetFactory/use.h b/assetFactory/use.h
new file mode 100644
index 0000000..4bfce97
--- /dev/null
+++ b/assetFactory/use.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "assetFactoryConfig_fwd.h"
+#include "faceController.h"
+#include "shape.h"
+#include "stdTypeDefs.hpp"
+
+class Use : public StdTypeDefs<Use>, public Mutation {
+public:
+ using FaceControllers = std::map<std::string, FaceController>;
+
+ Shape::CreatedFaces createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation) const;
+
+ Shape::CPtr type;
+ std::string colour;
+ FaceControllers faceControllers;
+};