Cogs.Core
MeshGeneratorCylinder.h
1#pragma once
2
3#include "MeshGeneratorCommon.h"
4
5namespace
6{
7 void cylinderFactory(Mesh * m, const ShapeDefinition & definition, int kRefinementLevels, int kMaxSamples)
8 {
9 int n = samplesFromLevel(definition.refinement, kRefinementLevels, kMaxSamples) + 3; // +2 is minimum (one triangle at end), but looks bad.
10
11 //Uses X dimension for radius, Z for height. Ignores Y
12 auto & r = definition.size.x;
13 auto & h = definition.size.z;
14
15 // End-cap duplication of center vertex, one per triangle in the
16 // triangle fan, to reduce texture coordinate twirl-distortion.
17 std::vector<PositionNormalTexVertex> V(2 * n + 4 * (n + 1));
18 for (int i = 0; i < n; i++) {
19 float u = (i + 0.5f) / float(n);
20 V[i] = PositionNormalTexVertex({ glm::vec3(0.f, 0.f, -h), glm::vec3(0.f, 0.f, -1.f), glm::vec2(u, 0.f) });
21 V[n + 4 * (n + 1) + i] = PositionNormalTexVertex({ glm::vec3(0.f, 0.f, h), glm::vec3(0.f, 0.f, 1.f), glm::vec2(u, 1.f) });
22 }
23
24 // Cylinder vertices, duplicated along seam. Two set of vertices
25 // at each end, one with normals for cylinder body, and one with
26 // normals for the caps.
27 for (int i = 0; i <= n; i++) {
28 float u = float(i) / float(n);
29 float cu = r * std::cos(glm::pi<float>() * 2.0f * u);
30 float su = r * std::sin(glm::pi<float>() * 2.0f * u);
31 V[n + 0 * (n + 1) + i] = PositionNormalTexVertex({ glm::vec3(su, cu, -h), glm::vec3(0.f, 0.f, -1.f), glm::vec2(u, 0.f) });
32 V[n + 1 * (n + 1) + i] = PositionNormalTexVertex({ glm::vec3(su, cu, -h), glm::vec3(su, cu, 0.f), glm::vec2(u, 0.f) });
33 V[n + 2 * (n + 1) + i] = PositionNormalTexVertex({ glm::vec3(su, cu, h), glm::vec3(su, cu, 0.f), glm::vec2(u, 1.f) });
34 V[n + 3 * (n + 1) + i] = PositionNormalTexVertex({ glm::vec3(su, cu, h), glm::vec3(0.f, 0.f, 1.f), glm::vec2(u, 1.f) });
35 }
36
37 std::vector<uint32_t> I;
38 I.reserve(3 * 4 * n);
39 for (int i = 0; i < n; i++) { // start cap
40 I.push_back(i);
41 I.push_back(n + i);
42 I.push_back(n + i + 1);
43 }
44
45 for (int i = 0; i < n; i++) { // body
46 I.push_back(n + 1 * (n + 1) + i);
47 I.push_back(n + 2 * (n + 1) + i);
48 I.push_back(n + 1 * (n + 1) + i + 1);
49
50 I.push_back(n + 1 * (n + 1) + i + 1);
51 I.push_back(n + 2 * (n + 1) + i);
52 I.push_back(n + 2 * (n + 1) + i + 1);
53 }
54
55 for (int i = 0; i < n; i++) { // end cap
56 I.push_back(n + 3 * (n + 1) + i + 1);
57 I.push_back(n + 3 * (n + 1) + i);
58 I.push_back(n + 4 * (n + 1) + i);
59 }
60
61 m->setVertexData(V.data(), V.size());
62 m->setIndexData(I.data(), I.size());
63 m->setBounds(computeBoundingBoxFromVertexFormat(V.begin(), V.end()));
64 }
65}
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
Definition: Mesh.h:265
void setIndexData(const uint32_t *data, size_t count)
Convenience method for setting index data from a raw pointer to data and count number of elements.
Definition: Mesh.h:705
void setBounds(Geometry::BoundingBox box)
Set custom bounds for the mesh.
Definition: Mesh.h:298
void setVertexData(Element *elements, size_t count)
Set vertex data.
Definition: Mesh.h:754
Defines creation values for a unique shape.
Definition: ShapeType.h:74