We got GameObjects / Components and shit

This commit is contained in:
2026-01-10 06:09:50 +01:00
parent 10b00b0525
commit 0bfc5e0705
35 changed files with 1546 additions and 331 deletions
+44
View File
@@ -0,0 +1,44 @@
#include <destrum/ObjectModel/Component.h>
#include <stdexcept>
#include <destrum/ObjectModel/GameObject.h>
// #include "imgui.h"
Component::Component(GameObject& pParent, const std::string& name): Object(name), m_ParentGameObjectPtr(&pParent) {
// if (m_ParentGameObjectPtr == nullptr) {
// //TODO: Change pParent ot be a reference
// throw std::runtime_error("Component made with no GameObject??");
// }
}
Transform& Component::GetTransform() const {
return m_ParentGameObjectPtr->GetTransform();
}
void Component::Destroy() {
// const bool isBeingDestroyed = GetIsBeingDestroyed();
Object::Destroy();
}
void Component::Start() {
}
void Component::SetEnabled(bool enabled) {
m_IsEnabled = enabled;
}
void Component::LateUpdate() {
}
void Component::FixedUpdate() {
}
void Component::ImGuiInspector() {
}
void Component::ImGuiRender() {
}
void Component::Render(const RenderContext& ctx) {
}
+96
View File
@@ -0,0 +1,96 @@
#include <destrum/ObjectModel/GameObject.h>
#include <string>
#include <iostream>
#include "spdlog/spdlog.h"
// #include "Managers/ResourceManager.h"
GameObject::~GameObject() {
spdlog::debug("GameObject destroyed: {}", GetName());
}
void GameObject::SetActiveDirty() {
m_ActiveDirty = true;
for (const Transform* child : m_TransformPtr.GetChildren()) {
child->GetOwner()->SetActiveDirty();
}
}
void GameObject::UpdateActiveState() {
const auto* parentPtr = m_TransformPtr.GetParent();
if(parentPtr == nullptr) {
m_ActiveInHierarchy = m_Active;
} else {
m_ActiveInHierarchy = m_Active && parentPtr->GetOwner()->IsActiveInHierarchy();
}
m_ActiveDirty = false;
}
bool GameObject::IsActiveInHierarchy() {
if (m_ActiveDirty) {
UpdateActiveState();
}
return m_ActiveInHierarchy;
}
GameObject::GameObject(const std::string& name): Object(name) {
}
void GameObject::Update() {
for (const auto& component: m_Components) {
if (!component->HasStarted) {
component->Start();
component->HasStarted = true;
}
component->Update();
}
}
void GameObject::LateUpdate() {
for (const auto& component: m_Components) {
component->LateUpdate();
}
}
void GameObject::FixedUpdate() {
for (const auto& component: m_Components) {
component->FixedUpdate();
}
}
void GameObject::Render(const RenderContext& ctx) const {
for (const auto& component: m_Components) {
component->Render(ctx);
}
}
// void GameObject::ImGuiRender() {
// for (const auto& component: m_Components) {
// component->ImGuiRender();
// }
// }
void GameObject::Destroy() {
Object::Destroy();
m_TransformPtr.SetParent(nullptr);
for (const auto& component: m_Components) {
component->Destroy();
}
for (const auto child : m_TransformPtr.GetChildren()) {
child->GetOwner()->Destroy();
}
}
void GameObject::CleanupComponents() {
std::erase_if(m_Components, [](const std::unique_ptr<Component>& component) {
return component->IsBeingDestroyed();
});
}
+22
View File
@@ -0,0 +1,22 @@
#include <destrum/ObjectModel/Object.h>
#include <cassert>
#include <iostream>
#include "spdlog/spdlog.h"
Object::~Object() {
if (!m_BeingDestroyed) {
assert(false && "Objects destructor called before destroy");
}
spdlog::debug("Object Destroyed: {}", m_Name);
}
void Object::Destroy() {
std::cout << "Marked Object for destruction: " << m_Name << std::endl;
spdlog::debug("Object Destroyed: {}", m_Name);
m_BeingDestroyed = true;
}
Object::Object(std::string name): m_Name(std::move(name)) {
}
+253
View File
@@ -0,0 +1,253 @@
#include <destrum/ObjectModel/Transform.h>
#include <destrum/ObjectModel/GameObject.h>
Transform::Transform(GameObject* owner): m_Owner(owner) {
}
Transform::~Transform() {
SetParent(nullptr);
for (auto it = m_Children.begin(); it != m_Children.end();) {
Transform* child = *it;
it = m_Children.erase(it);
child->SetParent(nullptr);
}
}
const glm::vec3& Transform::GetWorldPosition() {
if (m_PositionDirty) {
UpdateWorldPosition();
}
return m_WorldPosition;
}
const glm::quat& Transform::GetWorldRotation() {
if (m_RotationDirty) {
UpdateWorldRotation();
}
return m_WorldRotation;
}
const glm::vec3& Transform::GetWorldScale() {
if (m_ScaleDirty) {
UpdateWorldScale();
}
return m_WorldScale;
}
const glm::mat4& Transform::GetWorldMatrix() {
if (m_MatrixDirty) {
UpdateWorldMatrix();
}
return m_WorldMatrix;
}
void Transform::SetWorldPosition(const glm::vec3& position) {
if (m_Parent == nullptr) {
SetLocalPosition(position);
} else {
SetLocalPosition(position - m_Parent->GetWorldPosition());
}
}
void Transform::SetWorldPosition(float x, float y, float z) {
SetWorldPosition(glm::vec3(x, y, z));
}
void Transform::SetWorldRotation(const glm::quat& rotation) {
if(m_Parent == nullptr) {
SetLocalRotation(rotation);
} else {
SetLocalRotation(glm::inverse(m_Parent->GetWorldRotation()) * rotation);
}
}
void Transform::SetWorldRotation(const glm::vec3& rotation) {
SetWorldRotation(glm::quat(glm::radians(rotation)));
}
void Transform::SetWorldRotation(float x, float y, float z) {
SetWorldRotation(glm::vec3{x, y, z});
}
void Transform::SetWorldScale(double x, double y, double z) {
SetWorldScale(glm::vec3{x, y, z});
}
void Transform::SetWorldScale(const glm::vec3& scale) {
if (m_Parent == nullptr) {
SetLocalScale(scale);
} else {
SetLocalScale(scale - m_Parent->GetWorldScale());
}
}
void Transform::Move(const glm::vec3& move) {
SetLocalPosition(m_LocalPosition + move);
}
void Transform::Move(double x, double y, double z) {
this->Move(glm::vec3(x, y, z));
}
void Transform::SetLocalPosition(const glm::vec3& position) {
m_LocalPosition = position;
SetPositionDirty();
}
void Transform::SetLocalPosition(float x, float y, float z) {
SetLocalPosition(glm::vec3{x, y, z});
}
void Transform::SetLocalRotation(float x, float y, float z) {
SetLocalRotation(glm::vec3{x, y, z});
}
void Transform::SetLocalRotation(const glm::vec3& rotation) {
SetLocalRotation(glm::quat(glm::radians(rotation)));
}
void Transform::SetLocalRotation(const glm::quat& rotation) {
m_LocalRotation = rotation;
SetRotationDirty();
}
void Transform::SetLocalScale(float x, float y, float z) {
SetLocalScale({x, y, z});
}
void Transform::SetLocalScale(const glm::vec3& scale) {
m_LocalScale = scale;
SetScaleDirty();
}
void Transform::RemoveChild(Transform* transform) {
std::erase(m_Children, transform);
}
void Transform::AddChild(Transform* transform) {
// if (transform == this or transform == nullptr) {
// return;
// }
//
// if (transform->m_Parent) {
// transform->m_Parent->RemoveChild(transform);
// }
//
// transform->SetParent(this);
m_Children.push_back(transform);
//
// transform->SetPositionDirty();
}
void Transform::SetParent(Transform* parent, bool useWorldPosition) {
if (parent == m_Parent or parent == this or IsChild(parent)) {
return;
}
if (parent == nullptr) {
SetLocalPosition(GetWorldPosition());
} else {
if (useWorldPosition) {
SetLocalPosition(GetWorldPosition() - parent->GetWorldPosition());
}
SetPositionDirty();
}
if (m_Parent) {
m_Parent->RemoveChild(this);
}
m_Parent = parent;
if (m_Parent) {
m_Parent->AddChild(this);
}
}
bool Transform::IsChild(Transform* child) const {
return std::ranges::find(m_Children, child) != m_Children.end();
}
const std::vector<Transform*>& Transform::GetChildren() const {
// std::vector<Transform*> validChildren;
// for (auto* child : m_Children) {
// if (child && !child->GetOwner()->IsBeingDestroyed()) {
// validChildren.push_back(child);
// }
// }
// return validChildren;
return m_Children;
}
GameObject *Transform::GetOwner() const {
return m_Owner;
}
void Transform::SetPositionDirty() {
m_PositionDirty = true;
m_MatrixDirty = true;
for (const auto child: m_Children) {
child->SetPositionDirty();
}
}
void Transform::SetRotationDirty() {
m_RotationDirty = true;
m_MatrixDirty = true;
for(Transform* childPtr : m_Children) {
if(not childPtr->m_RotationDirty) {
childPtr->SetRotationDirty();
}
}
}
void Transform::SetScaleDirty() {
m_ScaleDirty = true;
m_MatrixDirty = true;
for(Transform* childPtr : m_Children) {
if(not childPtr->m_ScaleDirty) {
childPtr->SetScaleDirty();
}
}
}
void Transform::UpdateWorldPosition() {
if (m_Parent) {
m_WorldPosition = m_Parent->GetWorldPosition() + m_LocalPosition;
} else {
m_WorldPosition = m_LocalPosition;
}
m_PositionDirty = false;
}
void Transform::UpdateWorldRotation() {
if (m_Parent == nullptr) {
m_WorldRotation = m_LocalRotation;
} else {
m_WorldRotation = m_LocalRotation * m_Parent->GetWorldRotation();
}
m_RotationDirty = false;
}
void Transform::UpdateWorldScale() {
if(m_Parent == nullptr) {
m_WorldScale = m_LocalScale;
} else {
m_WorldScale = m_LocalScale * m_Parent->GetWorldScale();
}
m_ScaleDirty = false;
}
void Transform::UpdateWorldMatrix() {
const glm::mat4 trans = glm::translate(glm::mat4(1.0f), GetWorldPosition());
const glm::mat4 rot = glm::mat4_cast(GetWorldRotation());
const glm::mat4 scale = glm::scale(glm::mat4(1.0f), GetWorldScale());
m_WorldMatrix = trans * rot * scale;
m_MatrixDirty = false;
}