// Transform component
// Handles the position, rotation, and scale of an entity in 3D space
// AffineTransform or "Pose" matrix.
class TransformComponent : public Component {
private:
glm::vec3 position = glm::vec3(0.0f);
glm::quat rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f); // Identity quaternion
glm::vec3 scale = glm::vec3(1.0f);
// Cached transformation matrix
mutable glm::mat4 transformMatrix = glm::mat4(1.0f);
mutable bool transformDirty = true;
public:
void SetPosition(const glm::vec3& pos) {
position = pos;
transformDirty = true;
}
void SetRotation(const glm::quat& rot) {
rotation = rot;
transformDirty = true;
}
void SetScale(const glm::vec3& s) {
scale = s;
transformDirty = true;
}
const glm::vec3& GetPosition() const { return position; }
const glm::quat& GetRotation() const { return rotation; }
const glm::vec3& GetScale() const { return scale; }
glm::mat4 GetTransformMatrix() const {
if (transformDirty) {
// Calculate transformation matrix
glm::mat4 translationMatrix = glm::translate(glm::mat4(1.0f), position);
glm::mat4 rotationMatrix = glm::mat4_cast(rotation);
glm::mat4 scaleMatrix = glm::scale(glm::mat4(1.0f), scale);
transformMatrix = translationMatrix * rotationMatrix * scaleMatrix;
transformDirty = false;
}
return transformMatrix;
}
};
// Mesh component
// Manages the visual representation of an entity by handling its 3D mesh and material
class MeshComponent : public Component {
private:
Mesh* mesh = nullptr;
Material* material = nullptr;
public:
MeshComponent(Mesh* m, Material* mat) : mesh(m), material(mat) {}
void SetMesh(Mesh* m) { mesh = m; }
void SetMaterial(Material* mat) { material = mat; }
Mesh* GetMesh() const { return mesh; }
Material* GetMaterial() const { return material; }
void Render() override {
if (!mesh || !material) return;
// Get transform component
auto transform = GetOwner()->GetComponent<TransformComponent>();
if (!transform) return;
// Render mesh with material and transform
material->Bind();
material->SetUniform("modelMatrix", transform->GetTransformMatrix());
mesh->Render();
}
};
// Camera component
// Defines a viewpoint for rendering the scene by managing view and projection matrices
class CameraComponent : public Component {
private:
float fieldOfView = 45.0f;
float aspectRatio = 16.0f / 9.0f;
float nearPlane = 0.1f;
float farPlane = 1000.0f;
glm::mat4 viewMatrix = glm::mat4(1.0f);
glm::mat4 projectionMatrix = glm::mat4(1.0f);
bool projectionDirty = true;
public:
void SetPerspective(float fov, float aspect, float near, float far) {
fieldOfView = fov;
aspectRatio = aspect;
nearPlane = near;
farPlane = far;
projectionDirty = true;
}
glm::mat4 GetViewMatrix() const {
// Get transform component
auto transform = GetOwner()->GetComponent<TransformComponent>();
if (transform) {
// Calculate view matrix from transform
glm::vec3 position = transform->GetPosition();
glm::quat rotation = transform->GetRotation();
// Forward vector (local -Z)
glm::vec3 forward = rotation * glm::vec3(0.0f, 0.0f, -1.0f);
// Up vector (local +Y)
glm::vec3 up = rotation * glm::vec3(0.0f, 1.0f, 0.0f);
return glm::lookAt(position, position + forward, up);
}
return glm::mat4(1.0f);
}
glm::mat4 GetProjectionMatrix() const {
if (projectionDirty) {
projectionMatrix = glm::perspective(
glm::radians(fieldOfView),
aspectRatio,
nearPlane,
farPlane
);
projectionDirty = false;
}
return projectionMatrix;
}
};