From 3ef83422479f422e8ecffbb02597b3a033549a16 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Wed, 15 Apr 2020 02:03:56 +0200 Subject: [PATCH] Implementing basic scene tree --- src/Engine/Graphics/CMakeLists.txt | 18 ++- src/Engine/Graphics/ForwardPlusRenderPath.cpp | 24 ++++ src/Engine/Graphics/ForwardPlusRenderPath.h | 16 +++ src/Engine/Graphics/GraphicsResources.h | 3 +- src/Engine/Graphics/Mesh.cpp | 1 + src/Engine/Graphics/Mesh.h | 15 +++ src/Engine/Graphics/RenderPath.cpp | 9 +- src/Engine/Graphics/RenderPath.h | 8 +- src/Engine/Graphics/SceneRenderPath.cpp | 25 +--- src/Engine/Graphics/SceneRenderPath.h | 10 +- src/Engine/Graphics/SceneView.cpp | 8 +- src/Engine/Graphics/SceneView.h | 2 +- src/Engine/Graphics/View.cpp | 10 +- src/Engine/Graphics/View.h | 6 +- .../Graphics/Vulkan/VulkanGraphicsResources.h | 3 +- src/Engine/Graphics/Vulkan/VulkanViewport.cpp | 12 ++ src/Engine/Graphics/Window.cpp | 47 ++++++++ src/Engine/Graphics/Window.h | 23 ++++ src/Engine/Math/CMakeLists.txt | 4 +- src/Engine/Math/Math.h | 4 +- src/Engine/Math/Transform.cpp | 84 ++++++++++++++ src/Engine/Math/Transform.h | 36 ++++++ src/Engine/Math/Vector.h | 100 +++++++++++++++- src/Engine/Scene/Actor/Actor.cpp | 69 +++++++++++ src/Engine/Scene/Actor/Actor.h | 40 +++++++ src/Engine/Scene/Actor/CMakeLists.txt | 4 + src/Engine/Scene/CMakeLists.txt | 7 ++ src/Engine/Scene/Components/CMakeLists.txt | 6 + src/Engine/Scene/Components/Component.cpp | 108 ++++++++++++++++++ src/Engine/Scene/Components/Component.h | 48 ++++++++ .../Scene/Components/PrimitiveComponent.cpp | 0 .../Scene/Components/PrimitiveComponent.h | 12 ++ src/Engine/Scene/Scene.cpp | 0 src/Engine/Scene/Scene.h | 14 +++ 34 files changed, 722 insertions(+), 54 deletions(-) create mode 100644 src/Engine/Graphics/ForwardPlusRenderPath.cpp create mode 100644 src/Engine/Graphics/ForwardPlusRenderPath.h create mode 100644 src/Engine/Graphics/Mesh.cpp create mode 100644 src/Engine/Graphics/Mesh.h create mode 100644 src/Engine/Graphics/Window.cpp create mode 100644 src/Engine/Graphics/Window.h create mode 100644 src/Engine/Math/Transform.cpp create mode 100644 src/Engine/Math/Transform.h create mode 100644 src/Engine/Scene/Actor/Actor.cpp create mode 100644 src/Engine/Scene/Actor/Actor.h create mode 100644 src/Engine/Scene/Actor/CMakeLists.txt create mode 100644 src/Engine/Scene/CMakeLists.txt create mode 100644 src/Engine/Scene/Components/CMakeLists.txt create mode 100644 src/Engine/Scene/Components/Component.cpp create mode 100644 src/Engine/Scene/Components/Component.h create mode 100644 src/Engine/Scene/Components/PrimitiveComponent.cpp create mode 100644 src/Engine/Scene/Components/PrimitiveComponent.h create mode 100644 src/Engine/Scene/Scene.cpp create mode 100644 src/Engine/Scene/Scene.h diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index cf84bea..edfd04d 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -1,21 +1,27 @@ target_sources(SeeleEngine PRIVATE + ForwardPlusRenderPath.h + ForwardPlusRenderPath.cpp + GraphicsResources.h + GraphicsResources.cpp + GraphicsEnums.h Graphics.h Graphics.cpp + Mesh.h + Mesh.cpp RenderCore.h RenderCore.cpp RenderPath.h RenderPath.cpp + SceneView.h + SceneView.cpp SceneRenderPath.h SceneRenderPath.cpp View.h View.cpp - SceneView.h - SceneView.cpp + Window.cpp + Window.h WindowManager.h - WindowManager.cpp - GraphicsResources.h - GraphicsResources.cpp - GraphicsEnums.h) + WindowManager.cpp) add_subdirectory(Vulkan/) \ No newline at end of file diff --git a/src/Engine/Graphics/ForwardPlusRenderPath.cpp b/src/Engine/Graphics/ForwardPlusRenderPath.cpp new file mode 100644 index 0000000..020dc1a --- /dev/null +++ b/src/Engine/Graphics/ForwardPlusRenderPath.cpp @@ -0,0 +1,24 @@ +#include "ForwardPlusRenderPath.h" + +using namespace Seele; + +Seele::ForwardPlusRenderPath::ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport viewport) + : SceneRenderPath(graphics, viewport) +{ + +} + +Seele::ForwardPlusRenderPath::~ForwardPlusRenderPath() +{} + +void Seele::ForwardPlusRenderPath::beginFrame() +{ +} + +void Seele::ForwardPlusRenderPath::render() +{ +} + +void Seele::ForwardPlusRenderPath::endFrame() +{ +} diff --git a/src/Engine/Graphics/ForwardPlusRenderPath.h b/src/Engine/Graphics/ForwardPlusRenderPath.h new file mode 100644 index 0000000..7499ca7 --- /dev/null +++ b/src/Engine/Graphics/ForwardPlusRenderPath.h @@ -0,0 +1,16 @@ +#pragma once +#include "SceneRenderPath.h" + +namespace Seele +{ +class ForwardPlusRenderPath : public SceneRenderPath +{ +public: + ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target); + virtual ~ForwardPlusRenderPath(); + virtual void beginFrame() override; + virtual void render() override; + virtual void endFrame() override; +private: +}; +} \ No newline at end of file diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 8114fcc..aef4e2c 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -283,7 +283,8 @@ class Viewport public: Viewport(PWindow owner, const ViewportCreateInfo &createInfo); virtual ~Viewport(); - + virtual void resize(uint32 newX, uint32 newY) = 0; + virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0; protected: uint32 sizeX; uint32 sizeY; diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp new file mode 100644 index 0000000..f99d1ac --- /dev/null +++ b/src/Engine/Graphics/Mesh.cpp @@ -0,0 +1 @@ +#include "Mesh.h" \ No newline at end of file diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h new file mode 100644 index 0000000..fd0917a --- /dev/null +++ b/src/Engine/Graphics/Mesh.h @@ -0,0 +1,15 @@ +#pragma once +#include "GraphicsResources.h" + +namespace Seele +{ +class Mesh +{ +public: + Mesh(Gfx::PVertexBuffer vertexBuffer, Gfx::PIndexBuffer indexBuffer); + ~Mesh(); +private: + Gfx::VertexBuffer vertexBuffer; + Gfx::IndexBuffer indexBuffer; +}; +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPath.cpp b/src/Engine/Graphics/RenderPath.cpp index 6cac146..5bfb80d 100644 --- a/src/Engine/Graphics/RenderPath.cpp +++ b/src/Engine/Graphics/RenderPath.cpp @@ -1,10 +1,17 @@ #include "RenderPath.h" -Seele::RenderPath::RenderPath(Gfx::PGraphics graphics) +Seele::RenderPath::RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target) : graphics(graphics) + , target(target) { } Seele::RenderPath::~RenderPath() { } + +void Seele::RenderPath::applyArea(Rect newArea) +{ + target->resize(newArea.size.x, newArea.size.y); + target->move(newArea.offset.x, newArea.offset.y); +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPath.h b/src/Engine/Graphics/RenderPath.h index 10b2899..87b9ff8 100644 --- a/src/Engine/Graphics/RenderPath.h +++ b/src/Engine/Graphics/RenderPath.h @@ -6,17 +6,15 @@ namespace Seele class RenderPath { public: - RenderPath(Gfx::PGraphics graphics); + RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target); virtual ~RenderPath(); - virtual void applyArea(Rect area) = 0; - virtual void init() = 0; + virtual void applyArea(Rect area); virtual void beginFrame() = 0; virtual void render() = 0; virtual void endFrame() = 0; - protected: Gfx::PGraphics graphics; - Rect area; + Gfx::PViewport target; }; DEFINE_REF(RenderPath); } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/SceneRenderPath.cpp b/src/Engine/Graphics/SceneRenderPath.cpp index 3c4f660..154dbf6 100644 --- a/src/Engine/Graphics/SceneRenderPath.cpp +++ b/src/Engine/Graphics/SceneRenderPath.cpp @@ -1,31 +1,10 @@ #include "SceneRenderPath.h" -Seele::SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics) - : RenderPath(graphics) +Seele::SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target) + : RenderPath(graphics, target) { } Seele::SceneRenderPath::~SceneRenderPath() { } - -void Seele::SceneRenderPath::applyArea(Rect newArea) -{ - area = newArea; -} - -void Seele::SceneRenderPath::init() -{ -} - -void Seele::SceneRenderPath::beginFrame() -{ -} - -void Seele::SceneRenderPath::render() -{ -} - -void Seele::SceneRenderPath::endFrame() -{ -} diff --git a/src/Engine/Graphics/SceneRenderPath.h b/src/Engine/Graphics/SceneRenderPath.h index 4aa0211..9b0c790 100644 --- a/src/Engine/Graphics/SceneRenderPath.h +++ b/src/Engine/Graphics/SceneRenderPath.h @@ -6,12 +6,10 @@ namespace Seele class SceneRenderPath : public RenderPath { public: - SceneRenderPath(Gfx::PGraphics graphics); + SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target); virtual ~SceneRenderPath(); - virtual void applyArea(Rect area) override; - virtual void init() override; - virtual void beginFrame() override; - virtual void render() override; - virtual void endFrame() override; + virtual void beginFrame() = 0; + virtual void render() = 0; + virtual void endFrame() = 0; }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/SceneView.cpp b/src/Engine/Graphics/SceneView.cpp index 7d8d71e..441e3d4 100644 --- a/src/Engine/Graphics/SceneView.cpp +++ b/src/Engine/Graphics/SceneView.cpp @@ -1,10 +1,10 @@ #include "SceneView.h" -#include "SceneRenderPath.h" +#include "ForwardPlusRenderPath.h" -Seele::SceneView::SceneView(Gfx::PGraphics graphics) - : View(graphics) +Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo& createInfo) + : View(graphics, owner, createInfo) { - renderer = new SceneRenderPath(graphics); + renderer = new ForwardPlusRenderPath(graphics, viewport); } Seele::SceneView::~SceneView() diff --git a/src/Engine/Graphics/SceneView.h b/src/Engine/Graphics/SceneView.h index 3fb7b68..59aaf41 100644 --- a/src/Engine/Graphics/SceneView.h +++ b/src/Engine/Graphics/SceneView.h @@ -5,7 +5,7 @@ namespace Seele class SceneView : public View { public: - SceneView(Gfx::PGraphics graphics); + SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo& createInfo); ~SceneView(); }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/View.cpp b/src/Engine/Graphics/View.cpp index 93b3ae1..8ee559c 100644 --- a/src/Engine/Graphics/View.cpp +++ b/src/Engine/Graphics/View.cpp @@ -1,8 +1,11 @@ #include "View.h" +#include "Window.h" -Seele::View::View(Gfx::PGraphics graphics) +Seele::View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& viewportInfo) : graphics(graphics) + , owner(owner) { + viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo); } Seele::View::~View() @@ -14,6 +17,11 @@ void Seele::View::beginFrame() renderer->beginFrame(); } +void Seele::View::render() +{ + renderer->render(); +} + void Seele::View::endFrame() { renderer->endFrame(); diff --git a/src/Engine/Graphics/View.h b/src/Engine/Graphics/View.h index 70d5c2e..c5429fb 100644 --- a/src/Engine/Graphics/View.h +++ b/src/Engine/Graphics/View.h @@ -2,18 +2,22 @@ #include "RenderPath.h" namespace Seele { +DECLARE_REF(Window); // A view is a part of the window, which can be anything from a viewport to an editor class View { public: - View(Gfx::PGraphics graphics); + View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo); virtual ~View(); void beginFrame(); + void render(); void endFrame(); void applyArea(Rect area); protected: Gfx::PGraphics graphics; + Gfx::PViewport viewport; + PWindow owner; PRenderPath renderer; }; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 6a9b71f..ad09d29 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -332,7 +332,8 @@ class Viewport : public Gfx::Viewport public: Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); virtual ~Viewport(); - + virtual void resize(uint32 newX, uint32 newY); + virtual void move(uint32 newOffsetX, uint32 newOffsetY); protected: private: PGraphics graphics; diff --git a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp index 227979b..45f3655 100644 --- a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp @@ -241,3 +241,15 @@ Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo & Viewport::~Viewport() { } + +void Viewport::resize(uint32 newX, uint32 newY) +{ + sizeX = newX; + sizeY = newY; +} + +void Viewport::move(uint32 newOffsetX, uint32 newOffsetY) +{ + offsetX = newOffsetX; + offsetY = newOffsetY; +} \ No newline at end of file diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp new file mode 100644 index 0000000..35eccb9 --- /dev/null +++ b/src/Engine/Graphics/Window.cpp @@ -0,0 +1,47 @@ +#include "Window.h" + +Seele::Window::Window(Gfx::PWindow handle) + : gfxHandle(handle) +{ +} + +Seele::Window::~Window() +{ + +} + +void Seele::Window::addView(PView view) +{ + viewports.add(view); +} + +void Seele::Window::beginFrame() +{ + gfxHandle->beginFrame(); + for(auto view : viewports) + { + view->beginFrame(); + } +} + +void Seele::Window::render() +{ + for(auto view : viewports) + { + view->render(); + } +} + +void Seele::Window::endFrame() +{ + gfxHandle->endFrame(); + for(auto view : viewports) + { + view->endFrame(); + } +} + +Gfx::PWindow Seele::Window::getGfxHandle() +{ + return gfxHandle; +} \ No newline at end of file diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h new file mode 100644 index 0000000..90d5d52 --- /dev/null +++ b/src/Engine/Graphics/Window.h @@ -0,0 +1,23 @@ +#pragma once +#include "GraphicsResources.h" +#include "View.h" + +namespace Seele +{ +// The logical window, with the graphics proxy +class Window +{ +public: + Window(Gfx::PWindow handle); + ~Window(); + void addView(PView view); + void beginFrame(); + void render(); + void endFrame(); + Gfx::PWindow getGfxHandle(); +private: + Array viewports; + Gfx::PWindow gfxHandle; +}; +DEFINE_REF(Window); +} \ No newline at end of file diff --git a/src/Engine/Math/CMakeLists.txt b/src/Engine/Math/CMakeLists.txt index e840f15..55dc26a 100644 --- a/src/Engine/Math/CMakeLists.txt +++ b/src/Engine/Math/CMakeLists.txt @@ -2,4 +2,6 @@ target_sources(SeeleEngine PRIVATE Math.h Matrix.h - Vector.h) \ No newline at end of file + Vector.h + Transform.h + Transform.cpp) \ No newline at end of file diff --git a/src/Engine/Math/Math.h b/src/Engine/Math/Math.h index 11173fa..ae743b2 100644 --- a/src/Engine/Math/Math.h +++ b/src/Engine/Math/Math.h @@ -26,7 +26,7 @@ struct Rect }; struct Rect3D { - Vector3 size; - Vector3 offset; + Vector size; + Vector offset; }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Transform.cpp b/src/Engine/Math/Transform.cpp new file mode 100644 index 0000000..a6fc343 --- /dev/null +++ b/src/Engine/Math/Transform.cpp @@ -0,0 +1,84 @@ +#include "Transform.h" + +using namespace Seele; + +Transform::Transform() + : position(Vector4(0, 0, 0, 0)), rotation(Quaternion(0, 0, 0, 0)), scale(Vector4(1, 1, 1, 0)) +{ +} + +Transform::Transform(Vector position) + : position(Vector4(position, 0)), rotation(Quaternion(0, 0, 0, 0)), scale(Vector4(1, 1, 1, 0)) +{ +} +Transform::Transform(Vector position, Quaternion rotation) + : position(Vector4(position, 0)), rotation(rotation), scale(Vector4(1, 1, 1, 0)) +{ +} +Transform::Transform(Vector position, Quaternion rotation, Vector scale) + : position(Vector4(position, 0)), rotation(rotation), scale(Vector4(scale, 0)) +{ +} +Transform::Transform(Quaternion rotation, Vector scale) + : position(Vector4(0, 0, 0, 0)), rotation(rotation), scale(Vector4(scale, 0)) +{ +} +Transform::~Transform() +{ +} +Vector Transform::inverseTransformPosition(const Vector& v) const +{ + return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale); +} + +Vector Transform::getSafeScaleReciprocal(const Vector4& inScale, float tolerance) +{ + Vector safeReciprocalScale; + if (abs(inScale.x) <= tolerance) + { + safeReciprocalScale.x = 0.f; + } + else + { + safeReciprocalScale.x = 1 / inScale.x; + } + if (abs(inScale.y) <= tolerance) + { + safeReciprocalScale.y = 0.f; + } + else + { + safeReciprocalScale.y = 1 / inScale.y; + } + if (abs(inScale.z) <= tolerance) + { + safeReciprocalScale.z = 0.f; + } + else + { + safeReciprocalScale.z = 1 / inScale.z; + } + return safeReciprocalScale; +} + +inline Vector Transform::getPosition() const +{ + return Vector(position); +} + +inline Quaternion Transform::getRotation() const +{ + return rotation; +} + +inline Vector Transform::getScale() const +{ + return Vector(scale); +} + +inline void Transform::multiply(Transform* outTransform, const Transform* a, const Transform* b) +{ + outTransform->rotation = b->rotation * a->rotation; + outTransform->position = b->position * (b->scale * a->position) + b->position; + outTransform->scale = b->scale * a->scale; +} diff --git a/src/Engine/Math/Transform.h b/src/Engine/Math/Transform.h new file mode 100644 index 0000000..7b9fb8f --- /dev/null +++ b/src/Engine/Math/Transform.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vector.h" + +namespace Seele +{ +class Transform +{ +public: + Transform(); + Transform(Vector position); + Transform(Vector position, Quaternion rotation); + Transform(Vector position, Quaternion rotation, Vector scale); + Transform(Quaternion rotation, Vector scale); + ~Transform(); + Vector inverseTransformPosition(const Vector &v) const; + static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.00001f); + + inline Vector getPosition() const; + inline Quaternion getRotation() const; + inline Vector getScale() const; + + inline static void multiply(Transform* outTransform, const Transform* a, const Transform* b); + + Transform& operator*(const Transform& other) const + { + Transform outTransform; + multiply(&outTransform, this, &other); + return outTransform; + } + +private: + Vector4 position; + Quaternion rotation; + Vector4 scale; +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Math/Vector.h b/src/Engine/Math/Vector.h index cc1b9a2..a4d5a02 100644 --- a/src/Engine/Math/Vector.h +++ b/src/Engine/Math/Vector.h @@ -2,10 +2,11 @@ #include #include #include +#include namespace Seele { typedef glm::vec2 Vector2; -typedef glm::vec3 Vector3; +typedef glm::vec3 Vector; typedef glm::vec4 Vector4; typedef glm::uvec2 UVector2; @@ -15,4 +16,101 @@ typedef glm::uvec4 UVector4; typedef glm::ivec2 IVector2; typedef glm::ivec3 IVector3; typedef glm::ivec4 IVector4; + +typedef glm::quat Quaternion; + +static inline float square(float x) +{ + return x * x; +} + +static inline Vector unrotateVector(Quaternion quaternion, Vector v) +{ + const Vector q(-quaternion.x, -quaternion.y, -quaternion.z); + const Vector t = 2.f * glm::cross(q, v); + const Vector result = v + (quaternion.w * t) + glm::cross(q, t); + return result; +} + +static inline bool equalsQuaternion(const Quaternion& right, const Quaternion& left, float tolerance) +{ + return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance) + || (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance); +} + +static inline float clampRotatorAxis(float angle) +{ + angle = fmod(angle, 360.f); + if (angle < 0.f) + { + angle += 360.f; + } + return angle; +} +static inline float normalizeRotatorAxis(float angle) +{ + angle = clampRotatorAxis(angle); + + if (angle > 180.f) + { + angle -= 360.f; + } + return angle; +} + +static inline Quaternion toQuaternion(const Vector& other) +{ + Quaternion result; + const float DEG_TO_RAD = glm::pi() / (180.f); + const float RADS_DIVIDED_BY_2 = DEG_TO_RAD / 2.f; + + const float PitchNoWinding = fmod(other.x, 360.0f); + const float YawNoWinding = fmod(other.y, 360.0f); + const float RollNoWinding = fmod(other.z, 360.0f); + + const float SP = sin(PitchNoWinding * RADS_DIVIDED_BY_2); + const float SY = sin(YawNoWinding * RADS_DIVIDED_BY_2); + const float SR = sin(RollNoWinding * RADS_DIVIDED_BY_2); + + const float CP = cos(PitchNoWinding * RADS_DIVIDED_BY_2); + const float CY = cos(YawNoWinding * RADS_DIVIDED_BY_2); + const float CR = cos(RollNoWinding * RADS_DIVIDED_BY_2); + + result.x = CR * SP * SY - SR * CP * CY; + result.y = -CR * SP * CY - SR * CP * SY; + result.z = CR * CP * SY - SR * SP * CY; + result.w = CR * CP * CY + SR * SP * SY; + return result; +} + +static inline Vector toRotator(const Quaternion& other) +{ + const float singularityTest = other.z * other.x - other.w * other.y; + const float yawY = 2.f * (other.w * other.z + other.x * other.y); + const float yawX = (1.f - 2.f * (square(other.y) + square(other.z))); + + const float SINGULARITY_THRESHOLD = 0.4999995f; + const float RAD_TO_DEG = (180.f) / glm::pi(); + Vector rotatorFromQuat; + + if (singularityTest < -SINGULARITY_THRESHOLD) + { + rotatorFromQuat.x = -90.f; + rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; + rotatorFromQuat.z = normalizeRotatorAxis(-rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG)); + } + else if (singularityTest > SINGULARITY_THRESHOLD) + { + rotatorFromQuat.x = 90.f; + rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; + rotatorFromQuat.z = normalizeRotatorAxis(rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG)); + } + else + { + rotatorFromQuat.x = asin(2.f * (singularityTest)) * RAD_TO_DEG; + rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG; + rotatorFromQuat.z = atan2(-2.f * (other.w * other.x + other.y * other.z), (1.f - 2.f * (square(other.x) + square(other.y)))) * RAD_TO_DEG; + } + return rotatorFromQuat; +} } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Actor/Actor.cpp b/src/Engine/Scene/Actor/Actor.cpp new file mode 100644 index 0000000..c979773 --- /dev/null +++ b/src/Engine/Scene/Actor/Actor.cpp @@ -0,0 +1,69 @@ +#include "Actor.h" +#include "Component.h" + +using namespace Seele; + +Actor::Actor() +{ + +} +Actor::~Actor() +{ + +} +void Actor::setParent(PActor newParent) +{ + parent = newParent; +} +void Actor::addChild(PActor child) +{ + children.add(child); +} +void Actor::detachChild(PActor child) +{ + children.remove(children.find(child), false); +} +void Actor::setWorldLocation(Vector location) +{ + rootComponent->setWorldLocation(location); +} +void Actor::setWorldRotation(Vector4 rotation) +{ + rootComponent->setWorldRotation(rotation); +} +void Actor::setWorldScale(Vector scale) +{ + rootComponent->setWorldScale(scale); +} +void Actor::setRelativeLocation(Vector location) +{ + rootComponent->setRelativeLocation(location); +} +void Actor::setRelativeRotation(Vector4 rotation) +{ + rootComponent->setRelativeRotation(rotation); +} +void Actor::setRelativeScale(Vector scale) +{ + rootComponent->setRelativeScale(scale); +} +void Actor::addWorldTranslation(Vector translation) +{ + rootComponent->addWorldTranslation(translation); +} +void Actor::addWorldRotation(Vector4 rotation) +{ + rootComponent->addWorldRotation(rotation); +} +void Actor::addWorldScale(Vector scale) +{ + rootComponent->addWorldScale(scale); +} +PComponent Actor::getRootComponent() +{ + return rootComponent; +} +void Actor::setRootComponent(PComponent newRoot) +{ + rootComponent = newRoot; +} diff --git a/src/Engine/Scene/Actor/Actor.h b/src/Engine/Scene/Actor/Actor.h new file mode 100644 index 0000000..8586e37 --- /dev/null +++ b/src/Engine/Scene/Actor/Actor.h @@ -0,0 +1,40 @@ +#pragma once +#include "MinimalEngine.h" +#include "Transform.h" + +namespace Seele +{ +DECLARE_REF(Actor); +DECLARE_REF(Component); +class Actor +{ +public: + Actor(); + virtual ~Actor(); + void setParent(PActor parent); + PActor getParent(); + void addChild(PActor child); + void detachChild(PActor child); + Array getChildren(); + void setWorldLocation(Vector location); + void setWorldRotation(Vector4 rotation); + void setWorldScale(Vector scale); + + void setRelativeLocation(Vector location); + void setRelativeRotation(Vector4 rotation); + void setRelativeScale(Vector scale); + + void addWorldTranslation(Vector translation); + void addWorldRotation(Vector4 rotation); + void addWorldScale(Vector scale); + + PComponent getRootComponent(); + void setRootComponent(PComponent newRoot); +private: + PActor parent; + Array children; + PComponent rootComponent; + Transform transform; +}; +DEFINE_REF(Actor); +} \ No newline at end of file diff --git a/src/Engine/Scene/Actor/CMakeLists.txt b/src/Engine/Scene/Actor/CMakeLists.txt new file mode 100644 index 0000000..3aa282d --- /dev/null +++ b/src/Engine/Scene/Actor/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(SeeleEngine + PRIVATE + Actor.cpp + Actor.h) \ No newline at end of file diff --git a/src/Engine/Scene/CMakeLists.txt b/src/Engine/Scene/CMakeLists.txt new file mode 100644 index 0000000..a592c30 --- /dev/null +++ b/src/Engine/Scene/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(SeeleEngine + PRIVATE + Scene.cpp + Scene.h) + +add_subdirectory(Actor/) +add_subdirectory(Components/) \ No newline at end of file diff --git a/src/Engine/Scene/Components/CMakeLists.txt b/src/Engine/Scene/Components/CMakeLists.txt new file mode 100644 index 0000000..ba4188d --- /dev/null +++ b/src/Engine/Scene/Components/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(SeeleEngine + PRIVATE + Component.h + Component.cpp + PrimitiveComponent.cpp + PrimitiveComponent.h) \ No newline at end of file diff --git a/src/Engine/Scene/Components/Component.cpp b/src/Engine/Scene/Components/Component.cpp new file mode 100644 index 0000000..734738d --- /dev/null +++ b/src/Engine/Scene/Components/Component.cpp @@ -0,0 +1,108 @@ +#include "Component.h" + +using namespace Seele; + +Component::Component() +{ +} +Component::~Component() +{ +} +PComponent Component::getParent() +{ + +} +PActor Component::getOwner() +{ + +} +void Component::setWorldLocation(Vector location) +{ +} +void Component::setWorldRotation(Vector rotation) +{ +} +void Component::setWorldRotation(Quaternion rotation) +{ +} +void Component::setWorldScale(Vector scale) +{ +} +void Component::setRelativeLocation(Vector location) +{ +} +void Component::setRelativeRotation(Vector rotation) +{ +} +void Component::setRelativeRotation(Quaternion rotation) +{ +} +void Component::setRelativeScale(Vector scale) +{ +} +void Component::addWorldTranslation(Vector translation) +{ +} +void Component::addWorldRotation(Vector rotation) +{ +} +void Component::addWorldRotation(Quaternion rotation) +{ +} +void Component::addWorldScale(Vector scale) +{ +} +Transform Component::getTransform() const +{ + return transform; +} + +void Component::internalSetTransform(Vector newLocation, Quaternion newRotation) +{ + if(parent != nullptr) + { + Transform parentTransform = parent->getTransform(); + newLocation = parentTransform.inverseTransformPosition(newLocation); + newRotation = glm::inverse(parentTransform.getRotation()) * newRotation; + } + + const Vector newRelRotation = toRotator(newRotation); + if(newLocation != relativeLocation || newRelRotation != relativeLocation) + { + relativeLocation = newLocation; + relativeRotation = newRelRotation; + updateComponentTransform(newRelRotation); + } +} + +void Component::propagateTransformUpdate() +{ + for(auto child : children) + { + if(child != nullptr) + { + child->updateComponentTransform(child->relativeRotation); + } + } +} + +void Component::updateComponentTransform(Quaternion relativeRotationQuat) +{ + if(parent != nullptr && !parent->bComponentTransformClean) + { + parent->updateComponentTransform(parent->relativeRotation); + + if(bComponentTransformClean) + { + return; + } + } + bComponentTransformClean = true; + Transform newTransform; + const Transform relTransform(relativeLocation, relativeRotationQuat, relativeScale); + if(parent != nullptr) + { + newTransform = parent->getTransform() * relTransform; + } + +} diff --git a/src/Engine/Scene/Components/Component.h b/src/Engine/Scene/Components/Component.h new file mode 100644 index 0000000..930da3e --- /dev/null +++ b/src/Engine/Scene/Components/Component.h @@ -0,0 +1,48 @@ +#pragma once +#include "MinimalEngine.h" +#include "Transform.h" + +namespace Seele +{ +DECLARE_REF(Actor); +class Component +{ +public: + Component(); + virtual ~Component(); + PComponent getParent(); + void setParent(PComponent parent); + PActor getOwner(); + void setOwner(PActor owner); + + void setWorldLocation(Vector location); + void setWorldRotation(Vector rotation); + void setWorldRotation(Quaternion rotation); + void setWorldScale(Vector scale); + + void setRelativeLocation(Vector location); + void setRelativeRotation(Vector rotation); + void setRelativeRotation(Quaternion rotation); + void setRelativeScale(Vector scale); + + void addWorldTranslation(Vector translation); + void addWorldRotation(Vector rotation); + void addWorldRotation(Quaternion rotation); + void addWorldScale(Vector scale); + + Transform getTransform() const; +private: + void internalSetTransform(Vector newLocation, Quaternion newRotation); + void propagateTransformUpdate(); + void updateComponentTransform(Quaternion relativeRotationQuat); + uint8 bComponentTransformClean:1; + Vector relativeLocation; + Vector relativeRotation; + Vector relativeScale; + Transform transform; + PActor owner; + PComponent parent; + Array children; +}; +DEFINE_REF(Component) +} \ No newline at end of file diff --git a/src/Engine/Scene/Components/PrimitiveComponent.cpp b/src/Engine/Scene/Components/PrimitiveComponent.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Scene/Components/PrimitiveComponent.h b/src/Engine/Scene/Components/PrimitiveComponent.h new file mode 100644 index 0000000..a4b1004 --- /dev/null +++ b/src/Engine/Scene/Components/PrimitiveComponent.h @@ -0,0 +1,12 @@ +#pragma once +#include "Component.h" + +namespace Seele +{ +class PrimitiveComponent : public Component +{ +public: +private: + +}; +} \ No newline at end of file diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h new file mode 100644 index 0000000..ba43cd1 --- /dev/null +++ b/src/Engine/Scene/Scene.h @@ -0,0 +1,14 @@ +#include "MinimalEngine.h" +#include "Actor/Actor.h" + +namespace Seele +{ +class Scene +{ +public: + Scene(); + ~Scene(); +private: + Array rootActors; +}; +} \ No newline at end of file