Elevate Engine 1
Loading...
Searching...
No Matches
Mesh.cpp
Go to the documentation of this file.
1#include "Mesh.h"
2
3#include <stddef.h>
4#include <cmath>
9
10namespace Elevate
11{
12 Mesh::Mesh(const MeshData& data)
13 : m_data(data)
14 {
15 // Creating the Layout and the VertexBuffer
16 m_VertexBuffer.reset(VertexBuffer::Create(&data.Vertices[0], (uint32_t)data.Vertices.size() * sizeof(Vertex)));
17 // Creating the layout sent to the shader and the layout of the buffer
18 m_VertexBuffer->SetLayout({ // The layout is based on the Vertex struct (see Vertex.h)
19 { ShaderDataType::Float3, "a_Position" },
20 { ShaderDataType::Float3, "a_Normal" },
21 { ShaderDataType::Float2, "a_TexCord" },
22 { ShaderDataType::Float3, "a_Tangent" },
23 { ShaderDataType::Float3, "a_Bitangent" }
24 });
25
26 //Creating the IndexBuffer (containing indices)
27 m_IndexBuffer.reset(IndexBuffer::Create(&data.Indices[0], (uint32_t)data.Indices.size()));
28
29 m_VertexArray.reset(VertexArray::Create());
30 m_VertexArray->AddVertexBuffer(m_VertexBuffer);
31 m_VertexArray->SetIndexBuffer(m_IndexBuffer);
32
33 m_VertexArray->Unbind();
34
35 if (m_data.Textures.empty())
36 {
38 }
39 }
40
41 Mesh::Mesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices, const std::vector<std::shared_ptr<Texture>>& textures)
42 : Mesh(MeshData(vertices, indices, textures)) { }
43
45 {
46 return new Mesh(data);
47 }
48
49 Mesh* Mesh::Create(std::vector<Vertex>& vertices, std::vector<uint32_t>& indices, std::vector<std::shared_ptr<Texture>>& textures)
50 {
51 return new Mesh(vertices, indices, textures);
52 }
53
55 {
56 const float halfSize = size * 0.5f;
57
58 std::vector<Vertex> vertices;
59 std::vector<uint32_t> indices;
60
61 auto addFace = [&](glm::vec3 normal, glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, glm::vec3 v3) {
62 uint32_t startIndex = (uint32_t) vertices.size();
63
64 Vertex a{ v0, normal, {0.0f, 0.0f} };
65 Vertex b{ v1, normal, {1.0f, 0.0f} };
66 Vertex c{ v2, normal, {1.0f, 1.0f} };
67 Vertex d{ v3, normal, {0.0f, 1.0f} };
68
69 vertices.push_back(a);
70 vertices.push_back(b);
71 vertices.push_back(c);
72 vertices.push_back(d);
73
74 indices.push_back(startIndex);
75 indices.push_back(startIndex + 1);
76 indices.push_back(startIndex + 2);
77 indices.push_back(startIndex);
78 indices.push_back(startIndex + 2);
79 indices.push_back(startIndex + 3);
80 };
81
82 // Front (+Z)
83 addFace({ 0, 0, 1 },
84 { -halfSize, -halfSize, halfSize },
85 { halfSize, -halfSize, halfSize },
86 { halfSize, halfSize, halfSize },
87 { -halfSize, halfSize, halfSize });
88
89 // Back (-Z)
90 addFace({ 0, 0, -1 },
91 { halfSize, -halfSize, -halfSize },
92 { -halfSize, -halfSize, -halfSize },
93 { -halfSize, halfSize, -halfSize },
94 { halfSize, halfSize, -halfSize });
95
96 // Right (+X)
97 addFace({ 1, 0, 0 },
98 { halfSize, -halfSize, halfSize },
99 { halfSize, -halfSize, -halfSize },
100 { halfSize, halfSize, -halfSize },
101 { halfSize, halfSize, halfSize });
102
103 // Left (-X)
104 addFace({ -1, 0, 0 },
105 { -halfSize, -halfSize, -halfSize },
106 { -halfSize, -halfSize, halfSize },
107 { -halfSize, halfSize, halfSize },
108 { -halfSize, halfSize, -halfSize });
109
110 // Top (+Y)
111 addFace({ 0, 1, 0 },
112 { -halfSize, halfSize, halfSize },
113 { halfSize, halfSize, halfSize },
114 { halfSize, halfSize, -halfSize },
115 { -halfSize, halfSize, -halfSize });
116
117 // Bottom (-Y)
118 addFace({ 0, -1, 0 },
119 { -halfSize, -halfSize, -halfSize },
120 { halfSize, -halfSize, -halfSize },
121 { halfSize, -halfSize, halfSize },
122 { -halfSize, -halfSize, halfSize });
123
124 return Mesh(vertices, indices, {});
125 }
126
127 Mesh Mesh::GenerateUVSphere(float radius, int latitudes, int longitudes)
128 {
129 if (longitudes < 3) longitudes = 3;
130 if (latitudes < 2) latitudes = 2;
131
132 const float pi = std::acos(-1.0f);
133 std::vector<Vertex> vertices;
134 std::vector<uint32_t> indices;
135
136 float latStep = pi / latitudes;
137 float longStep = 2 * pi / longitudes;
138
139 for (int lat = 0; lat <= latitudes; ++lat)
140 {
141 float phi = (pi / 2) - (lat * latStep); // From 90* down (starting from north pole basicly)
142 const float xy = radius * cosf(phi);
143 const float z = radius * sinf(phi);
144
145 for (int lon = 0; lon <= longitudes; ++lon)
146 {
147 float theta = lon * longStep;
148
149 Vertex v;
150 v.Position = {
151 xy * cosf(theta),
152 xy * sinf(theta),
153 z
154 };
155 v.TexCoords = {
156 (float) lon / longitudes,
157 (float) lat / latitudes
158 };
159 v.Normal = glm::normalize(v.Position);
160 vertices.push_back(v);
161 }
162 }
163
164 for (int lat = 0; lat < latitudes; ++lat)
165 {
166 for (int lon = 0; lon < longitudes; ++lon)
167 {
168 const uint32_t curr = lat * (longitudes + 1) + lon;
169 const uint32_t next = curr + longitudes + 1;
170
171 indices.insert(indices.end(), {
172 curr, next, curr + 1,
173 next, next + 1, curr + 1
174 });
175 }
176 }
177
178 return Mesh(vertices, indices, {});
179 }
180
181 Mesh Mesh::GenerateCubephere(float radius, int subdivision)
182 {
183 return Mesh();
184 }
185
187 {
188 return GeneratePlane(size, 1);
189 }
190
191 Mesh Mesh::GeneratePlane(float size, int resolution) {
192 std::vector<Vertex> vertices;
193 std::vector<uint32_t> indices;
194
195 float step = size / resolution;
196 float offset = size * 0.5f;
197
198 for (int i = 0; i <= resolution; i++) {
199 for (int j = 0; j <= resolution; j++) {
200 Vertex v;
201 v.Position = { j * step - offset, 0.0f, i * step - offset };
202 v.Normal = { 0.0f, 1.0f, 0.0f };
203 v.TexCoords = { (float)j / resolution, (float)i / resolution };
204 vertices.push_back(v);
205 }
206 }
207
208 for (int i = 0; i < resolution; i++) {
209 for (int j = 0; j < resolution; j++) {
210 int row1 = i * (resolution + 1);
211 int row2 = (i + 1) * (resolution + 1);
212
213 uint32_t v0 = row1 + j;
214 uint32_t v1 = row1 + j + 1;
215 uint32_t v2 = row2 + j;
216 uint32_t v3 = row2 + j + 1;
217
218 indices.push_back(v0);
219 indices.push_back(v2);
220 indices.push_back(v1);
221
222 indices.push_back(v1);
223 indices.push_back(v2);
224 indices.push_back(v3);
225 }
226 }
227
228 return Mesh(vertices, indices, {});
229 }
230
231 Mesh Mesh::CombineMeshes(std::vector<Mesh>& meshes)
232 {
233 size_t indexOffset = 0;
234
235 std::vector<Vertex> vertices;
236 std::vector<uint32_t> indices;
237 std::vector<std::shared_ptr<Texture>> textures;
238
239 for (const Mesh& mesh : meshes)
240 {
241 vertices.insert(
242 vertices.end(),
243 mesh.m_data.Vertices.begin(),
244 mesh.m_data.Vertices.end()
245 );
246
247 for (uint32_t index : mesh.m_data.Indices)
248 {
249 indices.push_back(index + (uint32_t)indexOffset);
250 }
251 indexOffset += mesh.m_data.Vertices.size();
252
253 for (std::shared_ptr<Texture> tex : mesh.m_data.Textures)
254 {
255 if (!tex) continue; // TODO FIND IF AND WHY A TEXTURE COULD BE NULL
256
257 bool found = false;
258 for (std::shared_ptr<Texture> insertedTex : textures)
259 {
260 if (insertedTex->GetNativeHandle() == tex->GetNativeHandle())
261 {
262 found = true;
263 break;
264 }
265 }
266
267 if (!found)
268 {
269 textures.push_back(tex);
270 }
271 }
272 }
273
274 return Mesh(vertices, indices, textures);
275 }
276}
static IndexBuffer * Create(const void *vertices, uint32_t count)
Definition Buffer.cpp:23
static Mesh CombineMeshes(std::vector< Mesh > &meshes)
Definition Mesh.cpp:231
static Mesh GeneratePlane(float size, int resolution)
Definition Mesh.cpp:191
static Mesh * Create(const MeshData &data)
Definition Mesh.cpp:44
static Mesh GenerateCubephere(float radius, int subdivision)
Definition Mesh.cpp:181
Mesh()=default
static Mesh GenerateUVSphere(float radius, int latitudes, int longitudes)
Definition Mesh.cpp:127
static Mesh GenerateQuad(float size=1.0f)
Definition Mesh.cpp:186
static Mesh GenerateCube(float size=1.0f)
Definition Mesh.cpp:54
static TexturePtr GetDefaultTexture()
static VertexArray * Create()
static VertexBuffer * Create(const void *vertices, const uint32_t size)
Definition Buffer.cpp:11
std::vector< uint32_t > Indices
Definition Mesh.h:19
std::vector< Vertex > Vertices
Definition Mesh.h:18
std::vector< TexturePtr > Textures
Definition Mesh.h:20
glm::vec3 Normal
Definition Vertex.h:10
glm::vec3 Position
Definition Vertex.h:9
glm::vec2 TexCoords
Definition Vertex.h:11