We got GameObjects / Components and shit
This commit is contained in:
@@ -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) {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
@@ -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)) {
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user