Chira Engine
A customizable MIT-licensed game engine.
MeshDataBuilder.cpp
1 #include "MeshDataBuilder.h"
2 
3 #include <algorithm>
4 
5 using namespace chira;
6 
7 MeshDataBuilder::MeshDataBuilder() : MeshData() {
8  this->drawMode = MeshDrawMode::DYNAMIC;
9 }
10 
11 void MeshDataBuilder::addVertex(Vertex vertex, bool addDuplicate) { // NOLINT(misc-no-recursion)
12  if (addDuplicate) {
13  this->vertices.push_back(vertex);
14  this->indices.push_back(this->currentIndex);
15  this->currentIndex += 1;
16  return;
17  }
18  if (auto position = std::find(this->vertices.begin(), this->vertices.end(), vertex); position != this->vertices.end()) {
19  this->indices.push_back(static_cast<Index>(position - this->vertices.begin()));
20  } else {
21  this->addVertex(vertex, true);
22  }
23 }
24 
25 void MeshDataBuilder::addTriangle(Vertex v1, Vertex v2, Vertex v3, bool addDuplicate) {
26  this->addVertex(v1, addDuplicate);
27  this->addVertex(v2, addDuplicate);
28  this->addVertex(v3, addDuplicate);
29 }
30 
31 void MeshDataBuilder::addSquare(Vertex v1, Vertex v2, Vertex v3, Vertex v4, bool addDuplicate) {
32  this->addTriangle(v1, v2, v3, addDuplicate);
33  this->addTriangle(v3, v4, v1, addDuplicate);
34 }
35 
36 void MeshDataBuilder::addSquare(Vertex center, glm::vec2 size, SignedAxis normal, float offset, bool addDuplicate) {
37  const float s1 = size.x / 2;
38  const float s2 = size.y / 2;
39  const glm::vec3 mid{center.position.x, center.position.y, center.position.z};
40  const glm::vec3 col{center.color.r, center.color.g, center.color.b};
41 
42  switch (normal) {
43  using enum SignedAxis;
44  case YP:
45  this->addSquare(
46  {{mid.x - s1, mid.y + offset, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
47  {{mid.x + s1, mid.y + offset, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
48  {{mid.x + s1, mid.y + offset, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
49  {{mid.x - s1, mid.y + offset, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
50  addDuplicate
51  );
52  break;
53  case YN:
54  this->addSquare(
55  {{mid.x - s1, mid.y - offset, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
56  {{mid.x + s1, mid.y - offset, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
57  {{mid.x + s1, mid.y - offset, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
58  {{mid.x - s1, mid.y - offset, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
59  addDuplicate
60  );
61  break;
62  case ZP:
63  this->addSquare(
64  {{mid.x - s1, mid.y + s2, mid.z + offset}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
65  {{mid.x - s1, mid.y - s2, mid.z + offset}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
66  {{mid.x + s1, mid.y - s2, mid.z + offset}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
67  {{mid.x + s1, mid.y + s2, mid.z + offset}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
68  addDuplicate
69  );
70  break;
71  case ZN:
72  this->addSquare(
73  {{mid.x + s1, mid.y + s2, mid.z - offset}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
74  {{mid.x + s1, mid.y - s2, mid.z - offset}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
75  {{mid.x - s1, mid.y - s2, mid.z - offset}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
76  {{mid.x - s1, mid.y + s2, mid.z - offset}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
77  addDuplicate
78  );
79  break;
80  case XP:
81  this->addSquare(
82  {{mid.x + offset, mid.y + s1, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
83  {{mid.x + offset, mid.y - s1, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
84  {{mid.x + offset, mid.y - s1, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
85  {{mid.x + offset, mid.y + s1, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
86  addDuplicate
87  );
88  break;
89  case XN:
90  this->addSquare(
91  {{mid.x - offset, mid.y - s1, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
92  {{mid.x - offset, mid.y - s1, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
93  {{mid.x - offset, mid.y + s1, mid.z + s2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
94  {{mid.x - offset, mid.y + s1, mid.z - s2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
95  addDuplicate
96  );
97  break;
98  }
99 }
100 
101 void MeshDataBuilder::addCube(Vertex center, glm::vec3 size, bool visibleOutside, bool addDuplicate) {
102  const float x2 = size.x / 2;
103  const float y2 = size.y / 2;
104  const float z2 = size.z / 2;
105  const glm::vec3 mid{center.position.x, center.position.y, center.position.z};
106  const glm::vec3 col{center.color.r, center.color.g, center.color.b};
107 
108  if (visibleOutside) {
109  this->addSquare(
110  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
111  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
112  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
113  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
114  addDuplicate
115  );
116  this->addSquare(
117  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
118  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
119  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
120  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
121  addDuplicate
122  );
123  this->addSquare(
124  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
125  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
126  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
127  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
128  addDuplicate
129  );
130  this->addSquare(
131  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
132  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
133  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
134  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
135  addDuplicate
136  );
137  this->addSquare(
138  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
139  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
140  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
141  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
142  addDuplicate
143  );
144  this->addSquare(
145  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
146  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
147  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
148  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
149  addDuplicate
150  );
151  } else {
152  this->addSquare(
153  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
154  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
155  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
156  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
157  addDuplicate
158  );
159  this->addSquare(
160  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
161  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
162  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
163  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
164  addDuplicate
165  );
166  this->addSquare(
167  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
168  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
169  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
170  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
171  addDuplicate
172  );
173  this->addSquare(
174  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
175  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
176  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
177  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
178  addDuplicate
179  );
180  this->addSquare(
181  {{mid.x + x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
182  {{mid.x + x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
183  {{mid.x + x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
184  {{mid.x + x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
185  addDuplicate
186  );
187  this->addSquare(
188  {{mid.x - x2, mid.y + y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 0}},
189  {{mid.x - x2, mid.y + y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 0}},
190  {{mid.x - x2, mid.y - y2, mid.z + z2}, {0, 0, 0}, {col.x, col.y, col.z}, {1, 1}},
191  {{mid.x - x2, mid.y - y2, mid.z - z2}, {0, 0, 0}, {col.x, col.y, col.z}, {0, 1}},
192  addDuplicate
193  );
194  }
195 }
196 
197 void MeshDataBuilder::update() {
198  if (!this->initialized)
199  this->setupForRendering();
200  this->updateMeshData();
201 }
202 
204  this->clearMeshData();
205 }
void addSquare(Vertex v1, Vertex v2, Vertex v3, Vertex v4, bool addDuplicate=false)
Vertex v4 forms a face with vertex v1 and v3.
void clear()
Does not call update().
void addVertex(Vertex vertex, bool addDuplicate=false)
Pass true to addDuplicate if you don't want to scan the entire vertex vector to calculate the index.
void updateMeshData()
Updates the vertex buffers with the current mesh data.
Definition: MeshData.cpp:15
void setupForRendering()
Establishes the vertex buffers and copies the current mesh data into them.
Definition: MeshData.cpp:10
void clearMeshData()
Does not call updateMeshData().
Definition: MeshData.cpp:62