VEX Engine
Retro looking game engine made in vulkan mostly because i wanted to understand it better.
Loading...
Searching...
No Matches
BasicComponents.hpp
Go to the documentation of this file.
1
6
7#pragma once
8#ifndef GLM_ENABLE_EXPERIMENTAL
9 #define GLM_ENABLE_EXPERIMENTAL 1
10#endif
11#include <glm/glm.hpp>
12#include <glm/gtc/matrix_transform.hpp>
13#include <glm/gtc/quaternion.hpp>
14#include <glm/gtx/quaternion.hpp>
15#include <glm/gtx/euler_angles.hpp>
16#include <glm/gtx/matrix_decompose.hpp>
17#include <vector>
18#include <string>
19#include <map>
21
22#include "components/Mesh.hpp"
23#include "components/ErrorUtils.hpp"
24#include "components/ColorTypes.hpp"
25#include "components/AssetTypes.hpp"
26
27
28#include "components/ErrorUtils.hpp"
29
30namespace vex{
31
34 #ifdef DEBUG
35 public:
36 glm::vec3 position = {0.0f, 0.0f, 0.0f};
37 glm::vec3 rotation = {0.0f, 0.0f, 0.0f};
38 glm::vec3 scale = {1.0f, 1.0f, 1.0f};
39 glm::quat m_rotationQuat = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
41 vex::Registry* m_registry = nullptr;
42 glm::mat4 cachedMatrix = glm::mat4(1.0f);
43 bool dirty = true;
44 #else
45 private:
46 glm::vec3 position = {0.0f, 0.0f, 0.0f};
47 glm::quat m_rotationQuat = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
48 glm::vec3 scale = {1.0f, 1.0f, 1.0f};
50 bool lastTransformed = true;
51 vex::Registry* m_registry = nullptr;
52 bool physicsAffected = false;
53 glm::mat4 cachedMatrix = glm::mat4(1.0f);
54 bool dirty = true;
55 public:
56 #endif
59 : m_registry(other.m_registry), // Initialize the reference from the other's reference
60 position(other.position),
61 m_rotationQuat(other.m_rotationQuat), // Copy the quaternion
62 scale(other.scale),
63 parent(other.parent)
64 {}
65
68 if (this != &other) {
69 position = other.position;
70 m_rotationQuat = other.m_rotationQuat; // Assign the quaternion
71 scale = other.scale;
72 parent = other.parent;
73 }
74 return *this;
75 }
76
79 : m_registry(&registry) {}
80
83 : m_registry(&registry), position(pos), parent(p) {}
84
86 TransformComponent(vex::Registry& registry, glm::vec3 pos, glm::vec3 rot, vex::Entity p = vex::NULL_ENTITY)
87 : m_registry(&registry), position(pos), m_rotationQuat(glm::normalize(glm::quat(glm::radians(rot)))), parent(p) {}
88
90 TransformComponent(vex::Registry& registry, glm::vec3 pos, glm::vec3 rot, glm::vec3 s, vex::Entity p = vex::NULL_ENTITY)
91 : m_registry(&registry), position(pos), m_rotationQuat(glm::normalize(glm::quat(glm::radians(rot)))), scale(s), parent(p) {}
92
95 : m_registry(&registry), parent(p) {}
96
98 TransformComponent() = default;
99
100 bool isDirty(){
101 bool result = false;
102
103 if (!isReady()) [[unlikely]] {
104 log("TransformComponent is not ready, registry is not valid");
105 return false;
106 }
107
108 if (parent != vex::NULL_ENTITY && m_registry->has<TransformComponent>(parent)) {
109 result = m_registry->get<TransformComponent>(parent).isDirty();
110 }
111 return (dirty || result);
112 }
113
114 void setRegistry(vex::Registry& reg) {
115 dirty = true;
116 m_registry = &reg;
117 }
118
119 bool isReady() const {
120 return m_registry != nullptr;
121 }
122
123 #ifdef DEBUG
124 void convertRot(){
125 setLocalRotation(rotation);
126 //rotation = glm::degrees(glm::eulerAngles(m_rotationQuat));
127 }
128 #endif
129
131 void setParent(vex::Entity newParent) {
132 parent = newParent;
133 }
134
137 return parent;
138 }
139
141 glm::vec3 getLocalPosition() const {
142 return position;
143 }
144
146 glm::vec3 getLocalRotation() const {
147 return glm::degrees(glm::eulerAngles(m_rotationQuat));
148 }
149
151 glm::vec3 getLocalScale() const {
152 return scale;
153 }
154
156 void setLocalPosition(glm::vec3 newPosition) {
157 dirty = true;
158 position = newPosition;
159 }
160
162 void setLocalRotation(glm::vec3 newRotation) {
163 dirty = true;
164 m_rotationQuat = glm::normalize(glm::quat(glm::radians(newRotation)));
165 }
166
168 void setLocalScale(glm::vec3 newScale) {
169 dirty = true;
170 scale = newScale;
171 }
172
173 // --- WORLD QUATERNION METHODS FOR PHYSICS SYSTEMS ---
174
176 glm::quat getWorldQuaternion() const {
177 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
178 return m_registry->get<TransformComponent>(parent).getWorldQuaternion() * m_rotationQuat;
179 }
180 return m_rotationQuat;
181 }
182
185 void setWorldQuaternion(glm::quat targetWorldQuat) {
186 dirty = true;
187 if (parent != vex::NULL_ENTITY && m_registry->has<TransformComponent>(parent)) {
188 glm::quat parentWorldQuat = m_registry->get<TransformComponent>(parent).getWorldQuaternion();
189 glm::quat parentInverse = glm::inverse(parentWorldQuat);
190 m_rotationQuat = parentInverse * targetWorldQuat;
191 } else {
192 m_rotationQuat = targetWorldQuat;
193 }
194 m_rotationQuat = glm::normalize(m_rotationQuat);
195 }
196
199 void setWorldQuaternionPhys(glm::quat targetWorldQuat) {
200 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
201 glm::quat parentWorldQuat = m_registry->get<TransformComponent>(parent).getWorldQuaternion();
202 glm::quat parentInverse = glm::inverse(parentWorldQuat);
203 m_rotationQuat = parentInverse * targetWorldQuat;
204 } else {
205 m_rotationQuat = targetWorldQuat;
206 }
207 m_rotationQuat = glm::normalize(m_rotationQuat);
208 dirty = true;
209 }
210
212 glm::quat getLocalQuaternion() const {
213 return m_rotationQuat;
214 }
215
217 void setLocalQuaternion(glm::quat newRotation) {
218 dirty = true;
219 m_rotationQuat = glm::normalize(newRotation);
220 }
221
223 void addLocalQuaternion(glm::quat deltaRotation) {
224 dirty = true;
225 m_rotationQuat = glm::normalize(m_rotationQuat * deltaRotation);
226 }
227
228 // --------------------------------------------------
229
230 glm::mat4 recalculateMatrix(){
231 glm::mat4 local = glm::mat4(1.0f);
232 local = glm::translate(local, position);
233 local *= glm::mat4_cast(m_rotationQuat);
234 local = glm::scale(local, scale);
235
236 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
237 cachedMatrix = m_registry->get<TransformComponent>(parent).recalculateMatrix() * local;
238 }else{
239 cachedMatrix = local;
240 }
241
242 return cachedMatrix;
243 }
244
247 glm::mat4 matrix(bool forceRecalculate = false) {
248 if(isDirty() || forceRecalculate){
249 dirty = false;
250 return recalculateMatrix();
251 }
252 return cachedMatrix;
253 }
254
257 glm::vec3 getWorldPosition() {
258 return glm::vec3(matrix()[3]);
259 }
260
263 glm::vec3 getWorldRotation() {
264 return glm::degrees(glm::eulerAngles(getWorldQuaternion()));
265 }
266
269 glm::vec3 getWorldScale() {
270 glm::vec3 worldScale = scale;
271 vex::Entity current = parent;
272 while (current != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(current)) {
273 worldScale *= m_registry->get<TransformComponent>(current).scale;
274 current = m_registry->get<TransformComponent>(current).parent;
275 }
276 return worldScale;
277}
278
281 void setWorldPosition(glm::vec3 newPosition) {
282 dirty = true;
283 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
284 glm::mat4 parentWorldMatrix = m_registry->get<TransformComponent>(parent).matrix();
285 glm::mat4 inverseParentMatrix = glm::inverse(parentWorldMatrix);
286 glm::vec4 newLocalPos4 = inverseParentMatrix * glm::vec4(newPosition, 1.0f);
287 position = glm::vec3(newLocalPos4);
288 } else {
289 position = newPosition;
290 }
291 }
292
295 void setWorldPositionPhys(glm::vec3 newPosition) {
296 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
297 glm::mat4 parentWorldMatrix = m_registry->get<TransformComponent>(parent).matrix();
298 glm::mat4 inverseParentMatrix = glm::inverse(parentWorldMatrix);
299 glm::vec4 newLocalPos4 = inverseParentMatrix * glm::vec4(newPosition, 1.0f);
300 position = glm::vec3(newLocalPos4);
301 } else {
302 position = newPosition;
303 }
304 dirty = true;
305 }
306
309 void setWorldRotation(glm::vec3 newRotation) {
310 glm::quat targetWorldQuat = glm::quat(glm::radians(newRotation));
311 setWorldQuaternion(targetWorldQuat);
312 }
313
316 void setWorldScale(glm::vec3 newScale) {
317 dirty = true;
318 if (parent != vex::NULL_ENTITY && m_registry && m_registry->has<TransformComponent>(parent)) {
319 glm::vec3 parentWorldScale = m_registry->get<TransformComponent>(parent).getWorldScale();
320 scale = newScale / parentWorldScale;
321 } else {
322 scale = newScale;
323 }
324 }
325
328 void addLocalPosition(glm::vec3 newPosition) {
329 dirty = true;
330 position += newPosition;
331 }
332
335 void addLocalRotation(glm::vec3 newRotation) {
336 dirty = true;
337 glm::quat deltaQuat = glm::quat(glm::radians(newRotation));
338 m_rotationQuat = m_rotationQuat * deltaQuat;
339 m_rotationQuat = glm::normalize(m_rotationQuat);
340 }
341
344 void addLocalScale(glm::vec3 newScale) {
345 dirty = true;
346 scale += newScale;
347 }
348
351 void addPitch(float deltaPitch) {
352 dirty = true;
353 glm::quat deltaQuat = glm::angleAxis(glm::radians(deltaPitch), glm::vec3(1.0f, 0.0f, 0.0f));
354 m_rotationQuat = m_rotationQuat * deltaQuat;
355 m_rotationQuat = glm::normalize(m_rotationQuat);
356 }
357
360 void addYaw(float deltaYaw) {
361 dirty = true;
362 glm::quat deltaQuat = glm::angleAxis(glm::radians(deltaYaw), glm::vec3(0.0f, 1.0f, 0.0f));
363 m_rotationQuat = deltaQuat * m_rotationQuat;
364 m_rotationQuat = glm::normalize(m_rotationQuat);
365 }
366
369 void addRoll(float deltaRoll) {
370 dirty = true;
371 glm::quat deltaQuat = glm::angleAxis(glm::radians(deltaRoll), glm::vec3(0.0f, 0.0f, 1.0f));
372 m_rotationQuat = m_rotationQuat * deltaQuat;
373 m_rotationQuat = glm::normalize(m_rotationQuat);
374 }
375
376
377 glm::vec3 getForwardVector() {
378 return glm::normalize(-glm::vec3(matrix()[2]));
379 }
380
383 glm::vec3 getRightVector() {
384 return glm::normalize(glm::vec3(matrix()[0]));
385 }
386
389 glm::vec3 getUpVector() {
390 return glm::normalize(glm::vec3(matrix()[1]));
391 }
392
393 #if DEBUG
395 void enableLastTransformed() {
396 dirty = true;
397 }
398 #endif
399
400};
401
402#if defined(OPAQUE)
403 #undef OPAQUE
404#endif
405#if defined(TRANSPARENT)
406 #undef TRANSPARENT
407#endif
408
410enum class RenderType {
411 OPAQUE,
412 TRANSPARENT,
413 MASKED,
414 CUSTOM
415};
416
419 // Render Data
420 MeshData meshData;
421 uint32_t id = UINT32_MAX;
422 std::vector<std::string> textureNames;
423 RenderType renderType = RenderType::OPAQUE;
424 vex::rgba color = glm::vec4(1.f);
425
426 std::map<int, texture_asset_path> textureOverrides;
427
428 // Simple bounding data
429 glm::vec3 localCenter = glm::vec3(0.0f);
430 float localRadius = 1.0f;
431
432 glm::vec3 worldCenter = glm::vec3(0.0f);
433 float worldRadius = 1.0f;
434
437 return fresh;
438 }
439
442 fresh = false;
443 }
444
447 fresh = true;
448 }
449
450 private:
451 bool fresh = true;
452};
453
456 vex::rgb color = glm::vec3(1.f);
457 float intensity = 1.f;
458 float radius = 5.f;
459};
460
463 vex::rgb color = glm::vec3(1.f);
464 float density = 0.5f;
465 float start = 0.0f;
466 float end = 100.0f;
467};
468
471 std::string name;
472};
473
476 float fov = 45.0f;
477 float nearPlane = 0.1f;
478 float farPlane = 100.0f;
479 uint32_t id = UINT32_MAX; // For editor use
480};
481}
Main header for the Entity Component System (ECS) framework.
This file defines MeshData struct and all other structs needed for it.
Central registry for managing entities and their components in the ECS system.
Definition Registry.hpp:29
bool has(Entity entity)
Checks if an entity has a component of type T.
Definition Registry.hpp:137
T & get(Entity entity)
Retrieves a component from an entity.
Definition Registry.hpp:118
RenderType
Enum class for different types of rendering. It internally switches used pipeline.
uint32_t Entity
Type alias representing a unique entity identifier in the ECS system.
Definition Types.hpp:11
void VEX_EXPORT log(const char *fmt,...)
Logs a formatted message.
constexpr Entity NULL_ENTITY
Special entity value indicating an invalid or null entity.
Definition Types.hpp:15
Struct that contains camera properties. Used by build in CameraObject, but needed for any custom one ...
Struct containing fog properties.
Struct containing light properties.
Struct containing raw meshData, mesh id, texture paths and material properties. It just template and ...
void forceRefresh()
(used internally by the engine, DO NOT CALL) forces the component to be refreshed.
void setRendered()
(used internally by the engine, DO NOT CALL) sets the component as rendered.
bool getIsFresh()
(used internally by the engine, DO NOT CALL) returns true if the component is fresh.
Mesh data structure for loading and managing mesh data.
Definition Mesh.hpp:41
Struct that simply contains name of the entity. It is used to identify entity and needs to be unique.
Struct containing transform data and methods.
glm::vec3 getUpVector()
Method to get normalized up vector.
void addLocalRotation(glm::vec3 newRotation)
Method to add local rotation (Euler angles in degrees).
void setParent(vex::Entity newParent)
Set the parent entity.
void setWorldRotation(glm::vec3 newRotation)
Method to set world rotation, needed when object is parented as rotation parameter stores local rotat...
TransformComponent()=default
Default constructor is deleted since registry is required.
void addRoll(float deltaRoll)
Method to add to the local roll (rotation around Z-axis).
void setLocalPosition(glm::vec3 newPosition)
Set the local position.
glm::quat getLocalQuaternion() const
Get the local rotation as a quaternion directly.
void setWorldQuaternionPhys(glm::quat targetWorldQuat)
Method to set world rotation using a quaternion (for physics systems).
glm::vec3 getLocalScale() const
Get the local scale.
vex::Entity getParent() const
Get the parent entity.
void setWorldPositionPhys(glm::vec3 newPosition)
Method to set world position by physics component.
void addPitch(float deltaPitch)
Method to add to the local pitch (rotation around X-axis).
glm::vec3 getWorldScale()
Method to get world scale, needed when object is parented as scale parameter stores local scale.
TransformComponent & operator=(const TransformComponent &other)
Copy Assignment Operator. Copies all data members and maintains the reference to the same registry.
void addLocalScale(glm::vec3 newScale)
Method to add local scale.
glm::vec3 getLocalPosition() const
Get the local position.
glm::mat4 matrix(bool forceRecalculate=false)
Method used by renderer to calculate the transformation matrix.
void setLocalRotation(glm::vec3 newRotation)
Set the local rotation (using Euler angles in degrees).
void setLocalScale(glm::vec3 newScale)
Set the local scale.
void addYaw(float deltaYaw)
Method to add to the local yaw (rotation around Y-axis).
TransformComponent(vex::Registry &registry, vex::Entity p)
Constructor 5: Registry, Parent only (useful for empty child objects).
TransformComponent(vex::Registry &registry, glm::vec3 pos, vex::Entity p=vex::NULL_ENTITY)
Constructor 2: Registry, Position, (optional Parent).
glm::quat getWorldQuaternion() const
Method to get the world rotation as a quaternion.
void setWorldScale(glm::vec3 newScale)
Method to set world scale, needed when object is parented as rotation parameter stores local rotation...
void setWorldQuaternion(glm::quat targetWorldQuat)
Method to set world rotation using a quaternion (for physics systems).
TransformComponent(vex::Registry &registry, glm::vec3 pos, glm::vec3 rot, vex::Entity p=vex::NULL_ENTITY)
Constructor 3: Registry, Position, Rotation (Euler degrees), (optional Parent).
glm::vec3 getWorldPosition()
Method to get world position, needed when object is parented as position parameter stores local posit...
TransformComponent(vex::Registry &registry, glm::vec3 pos, glm::vec3 rot, glm::vec3 s, vex::Entity p=vex::NULL_ENTITY)
Constructor 4: Registry, Position, Rotation (Euler degrees), Scale, (optional Parent).
TransformComponent(vex::Registry &registry)
Constructor 1: Registry only.
void setLocalQuaternion(glm::quat newRotation)
Set the local rotation using a quaternion directly.
void addLocalQuaternion(glm::quat deltaRotation)
Multiply a delta quaternion into the current local rotation.
glm::vec3 getWorldRotation()
Method to get world rotation, needed when object is parented as rotation parameter stores local rotat...
TransformComponent(const TransformComponent &other)
Copy Constructor. Copies all data members and maintains the reference to the same registry.
glm::vec3 getLocalRotation() const
Get the local rotation (as Euler angles in degrees).
glm::vec3 getRightVector()
Method to get normalized right vector.
void addLocalPosition(glm::vec3 newPosition)
Method to add local position.
void setWorldPosition(glm::vec3 newPosition)
Method to set world position, needed when object is parented as position parameter stores local posit...
Represents an RGB color value. Used mainly for fancy rendering in editor.
Definition ColorTypes.hpp:7
Represents an RGBA color value. Used mainly for fancy rendering in editor.