Implementing ECS SystemBase and updating slang

This commit is contained in:
Dynamitos
2022-11-15 12:19:11 +01:00
parent 05bc31a2b4
commit f635ee2100
106 changed files with 1083 additions and 1675 deletions
+11 -120
View File
@@ -1,61 +1,19 @@
#include "Actor.h"
#include "Scene/Components/Component.h"
#include "Scene/Scene.h"
using namespace Seele;
Actor::Actor()
Actor::Actor(PScene scene)
: Entity(scene)
{
scene->attachComponent<Component::Transform>(identifier);
}
Actor::~Actor()
{
}
void Actor::launchStart()
{
rootComponent->launchStart();
for(auto child : children)
{
child->launchStart();
}
start();
}
void Actor::launchTick(float deltaTime) const
{
rootComponent->launchTick(deltaTime);
for(auto child : children)
{
child->launchTick(deltaTime);
}
tick(deltaTime);
}
void Actor::launchUpdate()
{
rootComponent->launchUpdate();
for(auto child : children)
{
child->launchUpdate();
}
update();
}
void Actor::notifySceneAttach(PScene scene)
{
owningScene = scene;
rootComponent->notifySceneAttach(scene);
for(auto child : children)
{
child->notifySceneAttach(scene);
}
}
PScene Actor::getScene()
{
return owningScene;
}
void Actor::setParent(PActor newParent)
{
if(parent != nullptr)
@@ -68,86 +26,19 @@ void Actor::addChild(PActor child)
{
children.add(child);
child->setParent(this);
child->notifySceneAttach(owningScene);
}
void Actor::removeChild(PActor child)
{
children.remove(children.find(child), false);
child->setParent(nullptr);
child->notifySceneAttach(nullptr);
}
//void Actor::setAbsoluteLocation(Vector location)
//{
// rootComponent->setWorldLocation(location);
//}
//
//void Actor::setAbsoluteRotation(Quaternion rotation)
//{
// rootComponent->setAbsoluteRotation(rotation);
//}
//void Actor::setAbsoluteRotation(Vector rotation)
//{
// rootComponent->setAbsoluteRotation(rotation);
//}
//void Actor::setWorldScale(Vector scale)
//{
// rootComponent->setWorldScale(scale);
//}
void Actor::setRelativeLocation(Vector location)
const Component::Transform& Actor::getTransform() const
{
rootComponent->setRelativeLocation(location);
}
void Actor::setRelativeRotation(Quaternion rotation)
{
rootComponent->setRelativeRotation(rotation);
}
void Actor::setRelativeRotation(Vector rotation)
{
rootComponent->setRelativeRotation(rotation);
}
void Actor::setRelativeScale(Vector scale)
{
rootComponent->setRelativeScale(scale);
}
//void Actor::addAbsoluteTranslation(Vector translation)
//{
// rootComponent->addAbsoluteTranslation(translation);
//}
//void Actor::addAbsoluteRotation(Quaternion rotation)
//{
// rootComponent->addAbsoluteRotation(rotation);
//}
//void Actor::addAbsoluteRotation(Vector rotation)
//{
// rootComponent->addAbsoluteRotation(rotation);
//}
void Actor::addRelativeLocation(Vector translation)
{
rootComponent->addRelativeLocation(translation);
}
void Actor::addRelativeRotation(Quaternion rotation)
{
rootComponent->addRelativeRotation(rotation);
}
void Actor::addRelativeRotation(Vector rotation)
{
rootComponent->addRelativeRotation(rotation);
}
PComponent Actor::getRootComponent()
{
return rootComponent;
}
void Actor::setRootComponent(PComponent newRoot)
{
if(rootComponent != nullptr)
{
rootComponent->owner = nullptr;
}
rootComponent = newRoot;
rootComponent->owner = this;
return scene->accessComponent<Component::Transform>(identifier);
}
Transform Actor::getTransform() const
{
return rootComponent->getTransform();
}
//Component::Transform& Actor::getTransform()
//{
// return scene->accessComponent<Component::Transform>(identifier);
//}
+9 -38
View File
@@ -1,60 +1,31 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Transform.h"
#include "Entity.h"
#include "Scene/Component/Transform.h"
namespace Seele
{
DECLARE_REF(Actor)
DECLARE_REF(Component)
DECLARE_REF(Scene)
class Actor
// Actors are entities that are part of the scene hierarchy
// In order for that hierarchy to make sense it requires at least a transform component
class Actor : public Entity
{
public:
Actor();
Actor(PScene scene);
virtual ~Actor();
virtual void launchStart();
virtual void start() {}
void launchTick(float deltaTime) const;
virtual void tick(float) const { }//co_return; }
void launchUpdate();
virtual void update() { }//co_return; }
void notifySceneAttach(PScene scene);
PScene getScene();
PActor getParent();
void addChild(PActor child);
void removeChild(PActor child);
Array<PActor> getChildren();
//void setAbsoluteLocation(Vector location);
//void setAbsoluteRotation(Quaternion rotation);
//void setAbsoluteRotation(Vector rotation);
//void setWorldScale(Vector scale);
void setRelativeLocation(Vector location);
void setRelativeRotation(Quaternion rotation);
void setRelativeRotation(Vector rotation);
void setRelativeScale(Vector scale);
//void addAbsoluteTranslation(Vector translation);
//void addAbsoluteRotation(Quaternion rotation);
//void addAbsoluteRotation(Vector rotation);
void addRelativeLocation(Vector translation);
void addRelativeRotation(Quaternion rotation);
void addRelativeRotation(Vector rotation);
PComponent getRootComponent();
void setRootComponent(PComponent newRoot);
// Returns a read-only copy of the actors transform
Transform getTransform() const;
const Component::Transform& getTransform() const;
protected:
//Component::Transform& getTransform();
void setParent(PActor parent);
PScene owningScene;
PActor parent;
Array<PActor> children;
PComponent rootComponent;
};
DEFINE_REF(Actor)
} // namespace Seele
+3 -1
View File
@@ -3,4 +3,6 @@ target_sources(Engine
Actor.cpp
Actor.h
CameraActor.cpp
CameraActor.h)
CameraActor.h
Entity.cpp
Entity.h)
+15 -11
View File
@@ -1,21 +1,25 @@
#include "CameraActor.h"
#include "Scene/Components/Component.h"
#include "Scene/Components/CameraComponent.h"
#include "Scene/Scene.h"
using namespace Seele;
CameraActor::CameraActor()
CameraActor::CameraActor(PScene scene)
: Actor(scene)
{
sceneComponent = new Component();
setRootComponent(sceneComponent);
cameraComponent = new CameraComponent();
cameraComponent->fieldOfView = 70.0f;
cameraComponent->setParent(sceneComponent);
cameraComponent->setOwner(this);
sceneComponent->addChildComponent(cameraComponent);
scene->attachComponent<Component::Camera>(identifier);
scene->accessComponent<Component::Transform>(identifier).setRelativeLocation(Math::Vector(10, 5, 14));
}
CameraActor::~CameraActor()
{
}
Component::Camera& CameraActor::getCameraComponent()
{
return scene->accessComponent<Component::Camera>(identifier);
}
const Component::Camera& CameraActor::getCameraComponent() const
{
return scene->accessComponent<Component::Camera>(identifier);
}
+4 -8
View File
@@ -1,21 +1,17 @@
#pragma once
#include "Actor.h"
#include "Scene/Component/Camera.h"
namespace Seele
{
DECLARE_REF(CameraComponent)
class CameraActor : public Actor
{
public:
CameraActor();
CameraActor(PScene scene);
virtual ~CameraActor();
PCameraComponent getCameraComponent() const
{
return cameraComponent;
}
Component::Camera& getCameraComponent();
const Component::Camera& getCameraComponent() const;
private:
PCameraComponent cameraComponent;
PComponent sceneComponent; // This will be the root, camera will be the child
};
DEFINE_REF(CameraActor)
} // namespace Seele
+15
View File
@@ -0,0 +1,15 @@
#include "Entity.h"
using namespace Seele;
Entity::Entity(PScene scene)
: identifier(scene->createEntity())
, scene(scene)
{
}
Entity::~Entity()
{
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <entt/entt.hpp>
#include "MinimalEngine.h"
#include "Scene/Scene.h"
namespace Seele
{
// An entity describes a part of a scene
// It is just a wrapper the ID of a registry
class Entity
{
public:
Entity(PScene scene);
virtual ~Entity();
template<typename Component, typename... Args>
void attachComponent(Args... args)
{
scene->attachComponent<Component>(identifier, args...);
}
protected:
PScene scene;
entt::entity identifier;
};
DEFINE_REF(Entity)
} // namespace Seele
+2 -1
View File
@@ -5,4 +5,5 @@ target_sources(Engine
Scene.h)
add_subdirectory(Actor/)
add_subdirectory(Components/)
add_subdirectory(Component/)
add_subdirectory(System/)
@@ -0,0 +1,8 @@
target_sources(Engine
PUBLIC
Component.h
Camera.h
Camera.cpp
StaticMesh.h
Transform.h
Transform.cpp)
@@ -1,13 +1,15 @@
#include "CameraComponent.h"
#include "Camera.h"
#include "Scene/Actor/Actor.h"
#include <algorithm>
#include <iostream>
using namespace Seele;
using namespace Seele::Component;
using namespace Seele::Math;
CameraComponent::CameraComponent()
Camera::Camera()
: aspectRatio(0)
, fieldOfView(0)
, fieldOfView(glm::radians(70.f))
, bNeedsViewBuild(true)
, bNeedsProjectionBuild(true)
, viewMatrix(Matrix4())
@@ -15,14 +17,13 @@ CameraComponent::CameraComponent()
{
yaw = 0;
pitch = 0;
setRelativeLocation(Vector(0, 10, -50));
}
CameraComponent::~CameraComponent()
Camera::~Camera()
{
}
void CameraComponent::mouseMove(float deltaYaw, float deltaPitch)
void Camera::mouseMove(float deltaYaw, float deltaPitch)
{
yaw -= deltaYaw / 500.f;
pitch += deltaPitch / 500.f;
@@ -31,29 +32,29 @@ void CameraComponent::mouseMove(float deltaYaw, float deltaPitch)
Vector xyz = glm::cross(cameraDirection, Vector(0, 0, 1));
Quaternion result = Quaternion(glm::dot(cameraDirection, Vector(0, 0, 1)) + 1, xyz.x, xyz.y, xyz.z);
//std::cout << "Result " << Vector(0, 0, 1) * glm::normalize(result) << " cameraDirection: " << cameraDirection << std::endl;
setRelativeRotation(result);
getTransform().setRelativeRotation(result);
bNeedsViewBuild = true;
}
void CameraComponent::mouseScroll(float x)
void Camera::mouseScroll(float x)
{
addRelativeLocation(getTransform().getForward()*x);
getTransform().addRelativeLocation(getTransform().getForward()*x);
bNeedsViewBuild = true;
}
void CameraComponent::moveX(float amount)
void Camera::moveX(float amount)
{
addRelativeLocation(getTransform().getForward()*amount);
getTransform().addRelativeLocation(getTransform().getForward()*amount);
bNeedsViewBuild = true;
}
void CameraComponent::moveY(float amount)
void Camera::moveY(float amount)
{
addRelativeLocation(getTransform().getRight()*amount);
getTransform().addRelativeLocation(getTransform().getRight()*amount);
bNeedsViewBuild = true;
}
void CameraComponent::setViewport(Gfx::PViewport newViewport)
void Camera::setViewport(Gfx::PViewport newViewport)
{
viewport = newViewport;
aspectRatio = viewport->getSizeX() / (float)viewport->getSizeY();
@@ -61,17 +62,17 @@ void CameraComponent::setViewport(Gfx::PViewport newViewport)
bNeedsProjectionBuild = true;
}
void CameraComponent::buildViewMatrix()
void Camera::buildViewMatrix()
{
Vector eyePos = getAbsoluteTransform().getPosition();
Vector lookAt = eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)));
Vector eyePos = getTransform().getPosition();//getAbsoluteTransform().getPosition();
Vector lookAt = Vector(0, 0, 0);//eyePos + glm::normalize(Vector(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)));
//std::cout << "Eye: " << eyePos << " lookAt: " << lookAt << std::endl;
viewMatrix = glm::lookAt(eyePos, lookAt, Vector(0, 1, 0));
bNeedsViewBuild = false;
}
void CameraComponent::buildProjectionMatrix()
void Camera::buildProjectionMatrix()
{
projectionMatrix = glm::perspective(fieldOfView, aspectRatio, 1.0f, 1000.f);
static Matrix4 correctionMatrix =
@@ -2,32 +2,30 @@
#include "Component.h"
#include "Math/Matrix.h"
#include "Graphics/GraphicsResources.h"
#include "Transform.h"
namespace Seele
{
class CameraComponent : public Component
namespace Component
{
public:
CameraComponent();
virtual ~CameraComponent();
struct Camera
{
REQUIRE_COMPONENT(Transform)
Camera();
~Camera();
Matrix4 getViewMatrix()
Math::Matrix4 getViewMatrix()
{
if (bNeedsViewBuild)
{
buildViewMatrix();
}
assert (!bNeedsViewBuild);
return viewMatrix;
}
Matrix4 getProjectionMatrix()
Math::Matrix4 getProjectionMatrix()
{
if (bNeedsProjectionBuild)
{
buildProjectionMatrix();
}
assert (!bNeedsProjectionBuild);
return projectionMatrix;
}
Vector getCameraPosition()
Math::Vector getCameraPosition()
{
return getTransform().getPosition();
}
@@ -38,19 +36,19 @@ public:
void moveY(float amount);
float aspectRatio;
float fieldOfView;
void buildViewMatrix();
void buildProjectionMatrix();
private:
bool bNeedsViewBuild;
bool bNeedsProjectionBuild;
void buildViewMatrix();
void buildProjectionMatrix();
Gfx::PViewport viewport;
//Transforms relative to actor
Matrix4 viewMatrix;
Matrix4 projectionMatrix;
Math::Matrix4 viewMatrix;
Math::Matrix4 projectionMatrix;
float yaw;
float pitch;
};
DEFINE_REF(CameraComponent)
} // namespace Component
} // namespace Seele
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <concepts>
#include <tuple>
namespace Seele
{
template<typename... Types>
struct Dependencies;
template<>
struct Dependencies<>
{};
template<typename This, typename... Rest>
struct Dependencies<This, Rest...> : public Dependencies<Rest...>
{
template<typename... Right>
Dependencies<This, Rest..., Right...> operator|(const Dependencies<Right...>& other)
{
return Dependencies<This, Rest..., Right...>();
}
};
namespace Component
{
#pragma warning(disable: 4505)
template<typename Comp>
static int accessComponent(Comp& comp);
}
template<typename T, typename... Deps>
concept is_component = std::same_as<decltype(T::dependencies), Dependencies<Deps...>>;
#define REQUIRE_COMPONENT(x) \
private: \
x& get##x() { return *tl_##x; } \
const x& get##x() const { return *tl_##x; }; \
public: \
static Dependencies<x> dependencies;
#define DECLARE_COMPONENT(x) \
thread_local extern x* tl_##x; \
template<> \
int accessComponent<x>(x& val) { tl_##x = &val; return 0; }
#define DEFINE_COMPONENT(x) \
thread_local x* Seele::Component::tl_##x;
} // namespace Seele
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "Graphics/GraphicsResources.h"
namespace Seele
{
namespace Component
{
struct StaticMesh
{
PVertexShaderInput vertexBuffer;
Gfx::PIndexBuffer indexBuffer;
PMaterialAsset material;
};
} // namespace Component
} // namespace Seele
+34
View File
@@ -0,0 +1,34 @@
#include "Transform.h"
using namespace Seele::Component;
DEFINE_COMPONENT(Transform)
void Transform::setRelativeLocation(Math::Vector location)
{
transform = Math::Transform(location, transform.getRotation(), transform.getScale());
}
void Transform::setRelativeRotation(Math::Vector rotation)
{
transform = Math::Transform(transform.getPosition(), Math::Quaternion(rotation), transform.getScale());
}
void Transform::setRelativeRotation(Math::Quaternion rotation)
{
transform = Math::Transform(transform.getPosition(), rotation, transform.getScale());
}
void Transform::setRelativeScale(Math::Vector scale)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation(), scale);
}
void Transform::addRelativeLocation(Math::Vector translation)
{
transform = Math::Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale());
}
void Transform::addRelativeRotation(Math::Vector rotation)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Math::Quaternion(rotation), transform.getScale());
}
void Transform::addRelativeRotation(Math::Quaternion rotation)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale());
}
+52
View File
@@ -0,0 +1,52 @@
#pragma once
#include "Math/Transform.h"
#include "Component.h"
namespace Seele
{
namespace Component
{
struct Transform
{
Transform() {}
Transform(const Transform& other) : transform(other.transform) {}
Transform(Transform&& other) : transform(other.transform) {}
Transform& operator=(const Transform& other) {
if (&other != this)
{
transform = other.transform;
}
return *this;
}
Transform& operator=(Transform&& other) {
if(&other != this)
{
transform = std::move(other.transform);
}
return *this;
}
Math::Vector getPosition() const { return transform.getPosition(); }
Math::Quaternion getRotation() const { return transform.getRotation(); }
Math::Vector getScale() const { return transform.getScale(); }
Math::Vector getForward() const { return transform.getForward(); }
Math::Vector getUp() const { return transform.getUp(); }
Math::Vector getRight() const { return transform.getRight(); }
Math::Matrix4 toMatrix() const { return transform.toMatrix(); }
void setRelativeLocation(Math::Vector location);
void setRelativeRotation(Math::Quaternion rotation);
void setRelativeRotation(Math::Vector rotation);
void setRelativeScale(Math::Vector scale);
void addRelativeLocation(Math::Vector translation);
void addRelativeRotation(Math::Quaternion rotation);
void addRelativeRotation(Math::Vector rotation);
private:
Math::Transform transform;
};
DECLARE_COMPONENT(Transform)
} // namespace Component
} // namespace Seele
@@ -1,12 +0,0 @@
target_sources(Engine
PUBLIC
CameraComponent.h
CameraComponent.cpp
Component.h
Component.cpp
MyComponent.h
MyComponent.cpp
MyOtherComponent.h
MyOtherComponent.cpp
PrimitiveComponent.cpp
PrimitiveComponent.h)
-201
View File
@@ -1,201 +0,0 @@
#include "Component.h"
#include "Scene/Actor/Actor.h"
#include "Scene/Scene.h"
using namespace Seele;
Component::Component()
{
}
Component::~Component()
{
}
void Component::launchStart()
{
for(auto child : children)
{
child->launchStart();
}
start();
}
void Component::launchTick(float deltaTime) const
{
for(auto child : children)
{
child->launchTick(deltaTime);
}
tick(deltaTime);
}
void Component::launchUpdate()
{
for(auto child : children)
{
child->launchUpdate();
}
update();
}
PComponent Component::getParent()
{
return parent;
}
PActor Component::getOwner()
{
if (owner != nullptr)
{
return owner;
}
if (parent != nullptr)
{
return parent->getOwner();
}
return nullptr;
}
const Array<PComponent>& Component::getChildComponents()
{
return children;
}
void Component::setParent(PComponent newParent)
{
parent = newParent;
}
void Component::setOwner(PActor newOwner)
{
owner = newOwner;
}
void Component::addChildComponent(PComponent component)
{
children.add(component);
}
void Component::notifySceneAttach(PScene scene)
{
owningScene = scene;
for (auto child : children)
{
child->notifySceneAttach(scene);
}
}
//void Component::setAbsoluteLocation(Vector location)
//{
// Vector newRelLocation = location;
// if (parent != nullptr)
// {
// Transform parentToWorld = getParent()->getTransform();
// newRelLocation = parentToWorld.inverseTransformPosition(location);
// }
// setRelativeLocation(newRelLocation);
//}
//void Component::setAbsoluteRotation(Vector rotation)
//{
// Vector newRelRotator = rotation;
// if (parent == nullptr)
// {
// setRelativeRotation(rotation);
// }
// else
// {
// setAbsoluteRotation(toQuaternion(newRelRotator));
// }
//}
//void Component::setAbsoluteRotation(Quaternion rotation)
//{
// Quaternion newRelRotation = getRelativeWorldRotation(rotation);
// setRelativeRotation(newRelRotation);
//}
//void Component::setWorldScale(Vector scale)
//{
// Vector newRelScale = scale;
// if (parent != nullptr)
// {
// Transform parentToWorld = parent->getTransform();
// newRelScale = scale * parentToWorld.getSafeScaleReciprocal(Vector4(parentToWorld.getScale(), 0));
// }
// setRelativeScale(newRelScale);
//}
void Component::setRelativeLocation(Vector location)
{
transform = Transform(location, transform.getRotation(), transform.getScale());
propagateTransformUpdate();
}
void Component::setRelativeRotation(Vector rotation)
{
transform = Transform(transform.getPosition(), Quaternion(rotation), transform.getScale());
propagateTransformUpdate();
}
void Component::setRelativeRotation(Quaternion rotation)
{
transform = Transform(transform.getPosition(), rotation, transform.getScale());
propagateTransformUpdate();
}
void Component::setRelativeScale(Vector scale)
{
transform = Transform(transform.getPosition(), transform.getRotation(), scale);
propagateTransformUpdate();
}
//void Component::addAbsoluteTranslation(Vector translation)
//{
// const Vector newWorldLocation = translation + getTransform().getPosition();
// setAbsoluteLocation(newWorldLocation);
//}
//void Component::addAbsoluteRotation(Vector rotation)
//{
// const Quaternion newWorldRotation = toQuaternion(rotation) * getTransform().getRotation();
// setAbsoluteRotation(newWorldRotation);
//}
//void Component::addAbsoluteRotation(Quaternion rotation)
//{
// const Quaternion newWorldRotation = rotation * getTransform().getRotation();
// setAbsoluteRotation(newWorldRotation);
//}
void Component::addRelativeLocation(Vector translation)
{
transform = Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale());
propagateTransformUpdate();
}
void Component::addRelativeRotation(Vector rotation)
{
transform = Transform(transform.getPosition(), transform.getRotation() * Quaternion(rotation), transform.getScale());
propagateTransformUpdate();
}
void Component::addRelativeRotation(Quaternion rotation)
{
transform = Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale());
propagateTransformUpdate();
}
Transform Component::getTransform() const
{
return transform;
}
Transform Component::getAbsoluteTransform() const
{
return absoluteTransform;
}
void Component::propagateTransformUpdate()
{
if(parent != nullptr)
{
absoluteTransform = transform + parent->getAbsoluteTransform();
}
else
{
absoluteTransform = transform;
}
for(auto child : children)
{
child->propagateTransformUpdate();
}
}
-77
View File
@@ -1,77 +0,0 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Transform.h"
#include "Scene/Util.h"
namespace Seele
{
DECLARE_REF(Actor)
DECLARE_REF(Scene)
DECLARE_REF(Component)
class Component
{
public:
Component();
virtual ~Component();
void launchStart();
virtual void start() {};
void launchTick(float deltaTime) const;
virtual void tick(float) const { }//co_return; }
void launchUpdate();
virtual void update() { }//co_return; }
PComponent getParent();
PActor getOwner();
const Array<PComponent>& getChildComponents();
void setParent(PComponent parent);
void setOwner(PActor owner);
void addChildComponent(PComponent component);
virtual void notifySceneAttach(PScene scene);
void setRelativeLocation(Vector location);
void setRelativeRotation(Vector rotation);
void setRelativeRotation(Quaternion rotation);
void setRelativeScale(Vector scale);
void addRelativeLocation(Vector translation);
void addRelativeRotation(Vector rotation);
void addRelativeRotation(Quaternion rotation);
Transform getTransform() const;
Transform getAbsoluteTransform() const;
template<typename ComponentType>
RefPtr<ComponentType> getComponent()
{
return tryFindComponent<ComponentType>();
}
private:
template<typename ComponentType>
RefPtr<ComponentType> tryFindComponent()
{
for(auto child : children)
{
RefPtr<ComponentType> result = child.cast<ComponentType>();
if(result != nullptr)
{
return result;
}
result = parent->tryFindComponent<ComponentType>();
if(result != nullptr)
{
return result;
}
}
return nullptr;
}
void propagateTransformUpdate();
Transform transform;
Transform absoluteTransform;
PScene owningScene;
PActor owner;
PComponent parent;
Array<PComponent> children;
friend class Actor;
};
DEFINE_REF(Component)
} // namespace Seele
@@ -1,30 +0,0 @@
#include "MyComponent.h"
using namespace Seele;
MyComponent::MyComponent()
{
}
void MyComponent::start()
{
otherComp = getComponent<MyOtherComponent>();
otherComp.update();
}
void MyComponent::tick(float) const
{
//std::cout << "MyComponent::tick" << std::endl;
++writable;
//std::cout << "MyComponent::tick finished" << std::endl;
otherComp->data = *writable;
//co_return;
}
void MyComponent::update()
{
//std::cout << "MyComponent::update" << std::endl;
writable.update();
//std::cout << "MyComponent::update finished" << std::endl;
//co_return;
}
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include "Component.h"
#include "MyOtherComponent.h"
namespace Seele
{
class MyComponent : public Component
{
public:
MyComponent();
virtual void start();
virtual void tick(float deltatime) const;
virtual void update();
private:
Writable<PMyOtherComponent> otherComp;
Writable<uint32> writable = 0;
uint32 notWritable = 10;
};
DECLARE_REF(MyComponent);
} // namespace Seele
@@ -1,15 +0,0 @@
#include "MyOtherComponent.h"
using namespace Seele;
void MyOtherComponent::tick(float) const
{
//std::cout << *data << std::endl;
//co_return;
}
void MyOtherComponent::update()
{
data.update();
//co_return;
}
@@ -1,15 +0,0 @@
#pragma once
#include "Component.h"
namespace Seele
{
class MyOtherComponent : public Component
{
public:
virtual void tick(float deltaTime) const;
virtual void update();
Writable<uint32> data = Writable<uint32>(0);
private:
};
DEFINE_REF(MyOtherComponent);
} // namespace Seele
@@ -1,54 +0,0 @@
#include "PrimitiveComponent.h"
#include "Scene/Scene.h"
#include "Material/MaterialAsset.h"
#include "Asset/MeshAsset.h"
#include "Graphics/VertexShaderInput.h"
#include <iostream>
using namespace Seele;
PrimitiveComponent::PrimitiveComponent()
{
}
PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
{
auto assetMeshes = asset->getMeshes();
staticMeshes.resize(assetMeshes.size());
for (uint32 i = 0; i < assetMeshes.size(); i++)
{
auto& batch = staticMeshes[i];
batch.material = asset->referencedMaterials[i];
batch.isBackfaceCullingDisabled = false;
batch.isCastingShadow = true;
batch.primitiveComponent = this;
batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
batch.useReverseCulling = false;
batch.useWireframe = false;
batch.vertexInput = assetMeshes[i]->vertexInput;
MeshBatchElement batchElement;
batchElement.baseVertexIndex = 0;
batchElement.firstIndex = 0;
batchElement.indexBuffer = assetMeshes[i]->indexBuffer;
batchElement.indirectArgsBuffer = nullptr;
batchElement.instanceRuns = nullptr;
batchElement.isInstanced = false;
batchElement.numInstances = 1;
batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded
batch.elements.push_back(batchElement);
}
}
PrimitiveComponent::~PrimitiveComponent()
{
}
void PrimitiveComponent::notifySceneAttach(PScene scene)
{
scene->addPrimitiveComponent(this);
}
Matrix4 PrimitiveComponent::getRenderMatrix()
{
return getAbsoluteTransform().toMatrix();
}
@@ -1,36 +0,0 @@
#pragma once
#include "Component.h"
#include "Graphics/GraphicsResources.h"
#include "Graphics/Mesh.h"
#include "Material/MaterialAsset.h"
#include "Graphics/MeshBatch.h"
namespace Seele
{
DECLARE_REF(MeshAsset)
class PrimitiveComponent : public Component
{
public:
PrimitiveComponent();
PrimitiveComponent(PMeshAsset asset);
~PrimitiveComponent();
virtual void notifySceneAttach(PScene scene) override;
Matrix4 getRenderMatrix();
std::vector<StaticMeshBatch>& getStaticMeshes()
{
return staticMeshes;
}
private:
std::vector<PMaterialAsset> materials;
Gfx::PUniformBuffer uniformBuffer;
std::vector<StaticMeshBatch> staticMeshes;
friend class Scene;
};
DEFINE_REF(PrimitiveComponent)
struct PrimitiveUniformBuffer
{
Matrix4 localToWorld;
Matrix4 worldToLocal;
Vector4 actorWorldPosition;
};
} // namespace Seele
+65 -51
View File
@@ -1,7 +1,8 @@
#include "Scene.h"
#include "Components/PrimitiveComponent.h"
#include "Material/MaterialAsset.h"
#include "Graphics/Graphics.h"
#include "Component/StaticMesh.h"
#include "Component/Transform.h"
using namespace Seele;
@@ -13,19 +14,6 @@ inline float frand()
Scene::Scene(Gfx::PGraphics graphics)
: graphics(graphics)
{
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1);
lightEnv.numDirectionalLights = 1;
srand((unsigned int)time(NULL));
for(uint32 i = 0; i < 16; ++i)
{
lightEnv.pointLights[i].colorRange = Vector4(frand(), frand(), frand(), frand() * 300);
lightEnv.pointLights[i].positionWS = Vector4(frand() * 100-50, frand(), frand() * 100-50, 1);
}
lightEnv.numPointLights = 16;
lightEnv.pointLights[0].colorRange = Vector4(1, 0, 1, 1000);
lightEnv.pointLights[0].positionWS = Vector4(0, 10, 0, 1);
}
Scene::~Scene()
@@ -34,23 +22,20 @@ Scene::~Scene()
void Scene::start()
{
for(auto actor : rootActors)
{
actor->launchStart();
}
//for(auto actor : rootActors)
//{
// actor->launchStart();
//}
}
static int64 lastUpdate;
static uint64 numUpdates;
void Scene::beginUpdate(double deltaTime)
void Scene::beginUpdate(double)
{
//std::cout << "Scene::beginUpdate" << std::endl;
auto startTime = std::chrono::high_resolution_clock::now();
for(auto actor : rootActors)
{
actor->launchTick(static_cast<float>(deltaTime));
}
// TODO
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count();
lastUpdate += delta;
@@ -66,38 +51,67 @@ void Scene::beginUpdate(double deltaTime)
void Scene::commitUpdate()
{
//std::cout << "Scene::commitUpdate" << std::endl;
for(auto actor : rootActors)
{
actor->launchUpdate();
}
//for(auto actor : rootActors)
//{
// actor->launchUpdate();
//}
//std::cout << "Scene::commitUpdate finished waiting" << std::endl;
}
void Scene::addActor(PActor actor)
Array<StaticMeshBatch> Scene::getStaticMeshes()
{
rootActors.push_back(actor);
actor->notifySceneAttach(this);
Array<StaticMeshBatch> result;
auto view = registry.view<Component::StaticMesh, Component::Transform>();
struct PrimitiveSceneData
{
Math::Matrix4 localToWorld;
Math::Matrix4 worldToLocal;
Math::Vector4 actorLocation;
};
for(auto&& [entity, mesh, transform] : view.each())
{
PrimitiveSceneData sceneData = {
.localToWorld = transform.toMatrix(),
.worldToLocal = glm::inverse(transform.toMatrix()),
.actorLocation = Math::Vector4(transform.getPosition(), 1.0f)
};
UniformBufferCreateInfo info = {
.resourceData = {
.size = sizeof(PrimitiveSceneData),
.data = (uint8_t*)&sceneData,
}
};
Gfx::PUniformBuffer transformBuf = graphics->createUniformBuffer(info);
auto& batch = result.add();
batch.material = mesh.material;
batch.isBackfaceCullingDisabled = false;
batch.isCastingShadow = true;
batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
batch.useReverseCulling = false;
batch.useWireframe = false;
batch.vertexInput = mesh.vertexBuffer;
MeshBatchElement batchElement;
batchElement.baseVertexIndex = 0;
batchElement.firstIndex = 0;
batchElement.indexBuffer = mesh.indexBuffer;
batchElement.indirectArgsBuffer = nullptr;
batchElement.instanceRuns = nullptr;
batchElement.isInstanced = false;
batchElement.numInstances = 1;
batchElement.uniformBuffer = transformBuf;
batchElement.numPrimitives = static_cast<uint32>(mesh.indexBuffer->getNumIndices() / 3); //TODO: hardcoded
batch.elements.add(batchElement);
}
return result;
}
void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
LightEnv Scene::getLightBuffer() const
{
primitives.push_back(comp);
for(auto& batch : comp->getStaticMeshes())
{
PrimitiveUniformBuffer data;
data.actorWorldPosition = Vector4(comp->getTransform().getPosition(), 1);
data.localToWorld = comp->getRenderMatrix();
data.worldToLocal = glm::inverse(data.localToWorld);
UniformBufferCreateInfo createInfo;
createInfo.resourceData.data = reinterpret_cast<uint8*>(&data);
createInfo.resourceData.owner = Gfx::QueueType::GRAPHICS;
createInfo.resourceData.size = sizeof(data);
createInfo.bDynamic = true;
Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(createInfo);
for(auto& element : batch.elements)
{
element.uniformBuffer = uniformBuffer;
}
staticMeshes.push_back(batch);
}
}
LightEnv result;
result.directionalLights[0].color = Math::Vector4(0.4, 0.3, 0.5, 1.0);
result.directionalLights[0].direction = Math::Vector4(0.5, 0.5, 0, 0);
result.directionalLights[0].intensity = Math::Vector4(1.0, 0.9, 0.7, 0.5);\
result.numDirectionalLights = 1;
result.numPointLights = 0;
return result;
}
+31 -17
View File
@@ -1,26 +1,26 @@
#pragma once
#include <entt/entt.hpp>
#include "MinimalEngine.h"
#include "Actor/Actor.h"
#include "Graphics/GraphicsResources.h"
#include "Components/PrimitiveComponent.h"
#include "Graphics/MeshBatch.h"
namespace Seele
{
DECLARE_REF(Material)
DECLARE_REF(Entity)
struct DirectionalLight
{
Vector4 color;
Vector4 direction;
Vector4 intensity;
Math::Vector4 color;
Math::Vector4 direction;
Math::Vector4 intensity;
};
struct PointLight
{
Vector4 positionWS;
Math::Vector4 positionWS;
//Vector4 positionVS;
Vector4 colorRange;
Math::Vector4 colorRange;
};
#define MAX_DIRECTIONAL_LIGHTS 4
@@ -41,17 +41,31 @@ public:
void start();
void beginUpdate(double deltaTime);
void commitUpdate();
void addActor(PActor actor);
void addPrimitiveComponent(PPrimitiveComponent comp);
const std::vector<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const std::vector<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
LightEnv& getLightBuffer() { return lightEnv; }
entt::entity createEntity()
{
return registry.create();
}
template<typename Component, typename... Args>
Component& attachComponent(entt::entity entity, Args... args)
{
return registry.emplace<Component>(entity, args...);
}
template<typename Component>
Component& accessComponent(entt::entity entity)
{
return registry.get<Component>(entity);
}
template<typename Component>
const Component& accessComponent(entt::entity entity) const
{
return registry.get<Component>(entity);
}
Array<StaticMeshBatch> getStaticMeshes();
LightEnv getLightBuffer() const;
entt::registry registry;
private:
std::vector<StaticMeshBatch> staticMeshes;
std::vector<PActor> rootActors;
std::vector<PPrimitiveComponent> primitives;
LightEnv lightEnv;
Gfx::PGraphics graphics;
};
DEFINE_REF(Scene)
} // namespace Seele
-75
View File
@@ -1,75 +0,0 @@
#include "SceneUpdater.h"
#include "Components/Component.h"
#include "Actor/Actor.h"
using namespace Seele;
SceneUpdater::SceneUpdater()
: pendingUpdatesSem(0)
{
running.store(true);
workers.resize(std::thread::hardware_concurrency());
for (size_t i = 0; i < workers.size(); i++)
{
workers[i] = std::thread(&SceneUpdater::work, this);
}
}
SceneUpdater::~SceneUpdater()
{
running.store(false);
for (size_t i = 0; i < workers.size(); i++)
{
workers[i].join();
}
}
void SceneUpdater::registerComponentUpdate(PComponent component)
{
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add([component](float delta) mutable { component->tick(delta); });
}
void SceneUpdater::registerActorUpdate(PActor actor)
{
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add([actor](float delta) mutable { actor->tick(delta); });
}
void SceneUpdater::runUpdates(float delta)
{
std::scoped_lock pendingLock(pendingUpdatesLock);
frameDelta = delta;
pendingUpdates = std::move(updatesRan);
updatesRan = List<std::function<void(float)>>();
std::scoped_lock lck(frameFinishedLock);
pendingLock.unlock();
pendingUpdatesSem.release(pendingUpdates.size());
frameFinishedCV.wait(lck);
}
void SceneUpdater::work()
{
while(running.load())
{
pendingUpdatesSem.acquire();
std::function<void(float)> function;
{
std::scoped_lock lck(pendingUpdatesLock);
function = std::move(pendingUpdates.front());
pendingUpdates.popFront();
if(pendingUpdates.empty())
{
std::scoped_lock lck(frameFinishedLock);
frameFinishedCV.notify_all();
}
}
function(frameDelta);
{
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add(std::move(function));
}
}
}
-31
View File
@@ -1,31 +0,0 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <semaphore>
//DEPRECATED
namespace Seele
{
DECLARE_REF(Component);
DECLARE_REF(Actor);
class SceneUpdater
{
public:
SceneUpdater();
~SceneUpdater();
void registerComponentUpdate(PComponent component);
void registerActorUpdate(PActor actor);
void runUpdates(float delta);
private:
Array<std::thread> workers;
std::mutex pendingUpdatesLock;
std::counting_semaphore<> pendingUpdatesSem;
List<std::function<void(float)>> pendingUpdates;
List<std::function<void(float)>> updatesRan;
void work();
float frameDelta;
std::atomic_bool running;
std::mutex frameFinishedLock;
std::condition_variable frameFinishedCV;
};
DEFINE_REF(SceneUpdater)
} // namespace Seele
+7
View File
@@ -0,0 +1,7 @@
target_sources(Engine
PUBLIC
Executor.h
Executor.cpp
CameraSystem.h
CameraSystem.cpp
SystemBase.h)
+11
View File
@@ -0,0 +1,11 @@
#include "CameraSystem.h"
#include "Scene/Component/Camera.h"
using namespace Seele;
using namespace Seele::System;
void CameraSystem::update(Component::Camera& camera)
{
camera.buildViewMatrix();
camera.buildProjectionMatrix();
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "SystemBase.h"
#include "Scene/Component/Camera.h"
namespace Seele
{
namespace System
{
class CameraSystem : public SystemBase<Component::Camera>
{
public:
CameraSystem(entt::registry& registry) : SystemBase(registry) {}
virtual ~CameraSystem() {}
virtual void update(Component::Camera& component);
private:
};
} // namespace System
} // namespace Seele
+4
View File
@@ -0,0 +1,4 @@
#include "Executor.h"
using namespace Seele;
using namespace Seele::System;
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "MinimalEngine.h"
#include "SystemBase.h"
#include <thread_pool/thread_pool.h>
namespace Seele
{
namespace System
{
class Executor
{
public:
Executor();
~Executor();
private:
dp::thread_pool<> pool;
};
} // namespace System
} // namespace Seele
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <entt/entt.hpp>
#include <thread_pool/thread_pool.h>
#include "Scene/Component/Component.h"
namespace Seele
{
namespace System
{
template<typename... Components>
class SystemBase
{
public:
SystemBase(entt::registry& registry) : registry(registry) {}
virtual ~SystemBase() {}
template<typename Comp>
auto getDependencies()
{
return Comp::dependencies;
}
template<typename... Dep>
auto mergeDependencies(Dep... deps)
{
return (deps | ...);
}
template<typename... Deps>
void setupView(Dependencies<Deps...>, dp::thread_pool<>&)
{
registry.view<Components..., Deps...>().each([&](Components&... comp, Deps&... deps){
//pool.enqueue_detach([&](){
int ret = (accessComponent(deps) + ...);
assert(ret == 0);
update((comp,...));
//});
});
}
void run(dp::thread_pool<>& pool)
{
setupView(mergeDependencies((getDependencies<Components>(),...)), pool);
}
virtual void update(Components&... components) = 0;
private:
entt::registry& registry;
};
} // namespace System
} // namespace Seele