From 88d5b474f3ab1c021612b0730f1b8d327a7a32db Mon Sep 17 00:00:00 2001
From: Dan Goodliffe <dan@randomdan.homeip.net>
Date: Thu, 16 Feb 2023 23:56:10 +0000
Subject: Add support for smooth faces

---
 assetFactory/cylinder.cpp       | 3 +++
 assetFactory/faceController.cpp | 8 ++++++++
 assetFactory/factoryMesh.cpp    | 6 +++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

(limited to 'assetFactory')

diff --git a/assetFactory/cylinder.cpp b/assetFactory/cylinder.cpp
index 83cf035..d51dc37 100644
--- a/assetFactory/cylinder.cpp
+++ b/assetFactory/cylinder.cpp
@@ -36,6 +36,9 @@ Cylinder::createMesh(ModelFactoryMesh & mesh, const Mutation::Matrix & mutation)
 								mesh.add_vertex({xyz1t.x, xyz1t.y, xyz1t.z}),
 						}));
 			});
+	for (const auto & [name, face] : surface) {
+		mesh.property(mesh.smoothFaceProperty, face) = true;
+	}
 	surface.emplace("bottom", mesh.add_face(bottom));
 	surface.emplace("top", mesh.add_face(top));
 
diff --git a/assetFactory/faceController.cpp b/assetFactory/faceController.cpp
index c04a656..7ec7820 100644
--- a/assetFactory/faceController.cpp
+++ b/assetFactory/faceController.cpp
@@ -23,6 +23,9 @@ FaceController::apply(ModelFactoryMesh & mesh, const std::string & name, Shape::
 			const auto vertexCount = points.size();
 			const auto centre
 					= std::accumulate(points.begin(), points.end(), glm::vec3 {}) / static_cast<float>(vertexCount);
+			if (smooth) {
+				mesh.property(mesh.smoothFaceProperty, cf.second) = true;
+			}
 			if (type == "extrude") {
 				Shape::CreatedFaces newFaces;
 				// mutate points
@@ -43,6 +46,11 @@ FaceController::apply(ModelFactoryMesh & mesh, const std::string & name, Shape::
 							mesh.add_face({baseVertices[idx], baseVertices[next], vertices[next], vertices[idx]}));
 				}
 				newFaces.emplace(name, mesh.add_face(vertices));
+				if (smooth) {
+					for (const auto & [name, face] : newFaces) {
+						mesh.property(mesh.smoothFaceProperty, face) = true;
+					}
+				}
 				for (const auto & [name, faceController] : faceControllers) {
 					faceController.apply(mesh, name, newFaces);
 				}
diff --git a/assetFactory/factoryMesh.cpp b/assetFactory/factoryMesh.cpp
index 9d30ac9..baa031d 100644
--- a/assetFactory/factoryMesh.cpp
+++ b/assetFactory/factoryMesh.cpp
@@ -17,10 +17,14 @@ FactoryMesh::createMesh() const
 
 	mesh.triangulate();
 	mesh.update_face_normals();
+	mesh.update_vertex_normals();
 	std::vector<Vertex> vertices;
 	for (const auto & face : mesh.faces()) {
+		const auto smooth = mesh.property(mesh.smoothFaceProperty, face);
 		for (const auto & vertex : mesh.fv_range(face)) {
-			vertices.emplace_back(mesh.point(vertex), NullUV, mesh.property(mesh.face_normals_pph(), face));
+			vertices.emplace_back(mesh.point(vertex), NullUV,
+					smooth ? mesh.property(mesh.vertex_normals_pph(), vertex)
+						   : mesh.property(mesh.face_normals_pph(), face));
 		}
 	}
 	return std::make_shared<Mesh>(vertices, vectorOfN(vertices.size()));
-- 
cgit v1.2.3