New scene items system
This commit is contained in:
14
src/dawn/scene/CMakeLists.txt
Normal file
14
src/dawn/scene/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Scene.cpp
|
||||
SceneItem.cpp
|
||||
SceneComponent.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(item)
|
36
src/dawn/scene/Scene.cpp
Normal file
36
src/dawn/scene/Scene.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Scene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Scene::Scene(
|
||||
const std::weak_ptr<Game> game,
|
||||
const std::function<void(Scene&)> sceneInitializer
|
||||
) :
|
||||
game(game),
|
||||
sceneInitializer(sceneInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::stage() {
|
||||
Scene &selfReference = *this;
|
||||
sceneInitializer(selfReference);
|
||||
}
|
||||
|
||||
std::shared_ptr<Game> Scene::getGame() {
|
||||
return game.lock();
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
||||
auto item = std::make_shared<SceneItem>(shared_from_this());
|
||||
sceneItems.push_back(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
}
|
52
src/dawn/scene/Scene.hpp
Normal file
52
src/dawn/scene/Scene.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "game/Game.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Scene final : public std::enable_shared_from_this<Scene> {
|
||||
private:
|
||||
std::weak_ptr<Game> game;
|
||||
const std::function<void(Scene&)> sceneInitializer;
|
||||
std::vector<std::shared_ptr<SceneItem>> sceneItems;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a scene object.
|
||||
*
|
||||
* @param game Game that initialized this scene.
|
||||
*/
|
||||
Scene(
|
||||
const std::weak_ptr<Game> game,
|
||||
const std::function<void(Scene&)> sceneInitializer
|
||||
);
|
||||
|
||||
/**
|
||||
* Stages all of the scene items on the scene.
|
||||
*/
|
||||
void stage();
|
||||
|
||||
/**
|
||||
* Returns a copy of the game instance that this scene belongs to.
|
||||
*
|
||||
* @return Shared pointer to the game instance.
|
||||
*/
|
||||
std::shared_ptr<Game> getGame();
|
||||
|
||||
/**
|
||||
* Creates a scene item that belongs to this scene.
|
||||
*
|
||||
* @return Pointer to the new scene item.
|
||||
*/
|
||||
std::shared_ptr<SceneItem> createSceneItem();
|
||||
|
||||
/**
|
||||
* Destroys the scene object and cleans up all of its children.
|
||||
*/
|
||||
virtual ~Scene();
|
||||
};
|
||||
}
|
17
src/dawn/scene/SceneComponent.cpp
Normal file
17
src/dawn/scene/SceneComponent.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneComponent.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void SceneComponent::init(const std::shared_ptr<SceneItem> item) {
|
||||
this->item = item;
|
||||
this->onInit();
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneItem> SceneComponent::getItem() {
|
||||
return this->item.lock();
|
||||
}
|
38
src/dawn/scene/SceneComponent.hpp
Normal file
38
src/dawn/scene/SceneComponent.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
|
||||
class SceneComponent : std::enable_shared_from_this<SceneComponent> {
|
||||
private:
|
||||
std::weak_ptr<SceneItem> item;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Custom component listener that is invoked when the component is meant
|
||||
* to initialize.
|
||||
*/
|
||||
virtual void onInit() = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes this scene component.
|
||||
*
|
||||
* @param item Scene item that this component belongs to.
|
||||
*/
|
||||
void init(const std::shared_ptr<SceneItem> item);
|
||||
|
||||
/**
|
||||
* Returns the scene item that this scene component belongs to.
|
||||
*
|
||||
* @return Reference to the scene item that this component belongs to.
|
||||
*/
|
||||
std::shared_ptr<SceneItem> getItem();
|
||||
};
|
||||
}
|
28
src/dawn/scene/SceneItem.cpp
Normal file
28
src/dawn/scene/SceneItem.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "scene/SceneItem.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItem::SceneItem(const std::weak_ptr<Scene> scene) :
|
||||
scene(scene),
|
||||
SceneItemTransform(),
|
||||
SceneItemComponents()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneItem> SceneItem::sceneItemComponentsSelf() {
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
std::shared_ptr<Scene> SceneItem::getScene() {
|
||||
return scene.lock();
|
||||
}
|
||||
|
||||
SceneItem::~SceneItem() {
|
||||
|
||||
}
|
46
src/dawn/scene/SceneItem.hpp
Normal file
46
src/dawn/scene/SceneItem.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/item/SceneItemTransform.hpp"
|
||||
#include "scene/item/SceneItemComponents.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Scene;
|
||||
|
||||
class SceneItem final :
|
||||
public SceneItemTransform,
|
||||
public SceneItemComponents,
|
||||
public std::enable_shared_from_this<SceneItem>
|
||||
{
|
||||
private:
|
||||
std::weak_ptr<Scene> scene;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<SceneItem> sceneItemComponentsSelf() override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a scene item.
|
||||
*
|
||||
* @param scene Scene that this item belongs to.
|
||||
*/
|
||||
SceneItem(const std::weak_ptr<Scene> scene);
|
||||
|
||||
/**
|
||||
* Returns the scene that this scene item belongs to.
|
||||
*
|
||||
* @return Pointer to the scene that this item belongs to.
|
||||
*/
|
||||
std::shared_ptr<Scene> getScene();
|
||||
|
||||
/**
|
||||
* Returns the scene that this item belongs to.
|
||||
*
|
||||
* @return Scene that this item belongs to.
|
||||
*/
|
||||
virtual ~SceneItem();
|
||||
};
|
||||
}
|
10
src/dawn/scene/item/CMakeLists.txt
Normal file
10
src/dawn/scene/item/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
SceneItemComponents.cpp
|
||||
SceneItemTransform.cpp
|
||||
)
|
24
src/dawn/scene/item/SceneItemComponents.cpp
Normal file
24
src/dawn/scene/item/SceneItemComponents.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItemComponents.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItemComponents::SceneItemComponents() {
|
||||
|
||||
}
|
||||
|
||||
void SceneItemComponents::removeComponent(
|
||||
const std::shared_ptr<SceneComponent> component
|
||||
) {
|
||||
auto it = std::find(components.begin(), components.end(), component);
|
||||
if(it == components.end()) return; //Not found?
|
||||
components.erase(it);
|
||||
}
|
||||
|
||||
SceneItemComponents::~SceneItemComponents() {
|
||||
|
||||
}
|
54
src/dawn/scene/item/SceneItemComponents.hpp
Normal file
54
src/dawn/scene/item/SceneItemComponents.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
|
||||
class SceneItemComponents {
|
||||
protected:
|
||||
std::vector<std::shared_ptr<SceneComponent>> components;
|
||||
|
||||
/**
|
||||
* Shorthand way of allowing this class to retreive itself as a SceneItem.
|
||||
*
|
||||
* @return This as a shared pointer to a SceneItem.
|
||||
*/
|
||||
virtual std::shared_ptr<SceneItem> sceneItemComponentsSelf() = 0;
|
||||
|
||||
public:
|
||||
SceneItemComponents();
|
||||
|
||||
/**
|
||||
* Removes a component from this item.
|
||||
*
|
||||
* @param component Component to remove.
|
||||
*/
|
||||
void removeComponent(const std::shared_ptr<SceneComponent> component);
|
||||
|
||||
/**
|
||||
* Adds a component to this item. You are given a shared pointer back but
|
||||
* you are not intended to take responsibility for the component.
|
||||
*
|
||||
* @return Shared pointer to the created component.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> addComponent() {
|
||||
//Create the component and add it.
|
||||
std::shared_ptr<T> component = std::make_shared<T>();
|
||||
this->components.push_back(
|
||||
static_pointer_cast<SceneComponent>(component)
|
||||
);
|
||||
|
||||
// Init compoonent and return
|
||||
component->init(sceneItemComponentsSelf());
|
||||
return component;
|
||||
}
|
||||
|
||||
virtual ~SceneItemComponents();
|
||||
};
|
||||
}
|
122
src/dawn/scene/item/SceneItemTransform.cpp
Normal file
122
src/dawn/scene/item/SceneItemTransform.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assert.hpp"
|
||||
#include "scene/item/SceneItemTransform.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItemTransform::SceneItemTransform() :
|
||||
transformLocal(1.0f),
|
||||
transformWorld(1.0f)
|
||||
{
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void SceneItemTransform::updateLocalValuesFromLocalTransform() {
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(
|
||||
this->transformLocal,
|
||||
this->localScale,
|
||||
this->localRotation,
|
||||
this->localPosition,
|
||||
skew,
|
||||
perspective
|
||||
);
|
||||
}
|
||||
|
||||
void SceneItemTransform::updateLocalTransformFromWorldTransform() {
|
||||
auto parent = this->getParent();
|
||||
if(!parent) {
|
||||
this->transformLocal = this->transformWorld;
|
||||
} else {
|
||||
this->transformLocal = (
|
||||
glm::inverse(parent->transformWorld) * this->transformWorld
|
||||
);
|
||||
}
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void SceneItemTransform::updateChildrenWorldTransforms() {
|
||||
std::for_each(
|
||||
this->children.begin(),
|
||||
this->children.end(),
|
||||
[](std::weak_ptr<SceneItem> &item) {
|
||||
if(auto child = item.lock()) child->updateWorldTransformFromParent();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void SceneItemTransform::updateWorldTransformFromParent() {
|
||||
auto parent = this->getParent();
|
||||
if(!parent) {
|
||||
this->transformWorld = this->transformLocal;
|
||||
} else {
|
||||
this->transformWorld = (
|
||||
parent->transformWorld * this->transformLocal
|
||||
);
|
||||
}
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
this->updateChildrenWorldTransforms();
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneItem> SceneItemTransform::getParent() {
|
||||
return parent.lock();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<SceneItem>> SceneItemTransform::getChildren() {
|
||||
std::vector<std::shared_ptr<SceneItem>> children;
|
||||
std::for_each(
|
||||
this->children.begin(),
|
||||
this->children.end(),
|
||||
[&children](std::weak_ptr<SceneItem> &item) {
|
||||
if(auto child = item.lock()) children.push_back(child);
|
||||
}
|
||||
);
|
||||
return children;
|
||||
}
|
||||
|
||||
glm::mat4 SceneItemTransform::getLocalTransform() {
|
||||
return this->transformLocal;
|
||||
}
|
||||
|
||||
void SceneItemTransform::setWorldTransform(const glm::mat4 transform) {
|
||||
this->transformWorld = transform;
|
||||
this->updateLocalTransformFromWorldTransform();
|
||||
this->updateChildrenWorldTransforms();
|
||||
}
|
||||
|
||||
bool_t SceneItemTransform::isChildOf(std::shared_ptr<SceneItem> item) {
|
||||
assertNotNull(item, "Cannot check if child of null item.");
|
||||
auto parent = this->getParent();
|
||||
while(parent) {
|
||||
if(parent == item) return true;
|
||||
parent = parent->getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SceneItemTransform::lookAt(
|
||||
const glm::vec3 position,
|
||||
const glm::vec3 target,
|
||||
const glm::vec3 up
|
||||
) {
|
||||
this->setWorldTransform(glm::lookAt(position, target, up));
|
||||
}
|
||||
|
||||
SceneItemTransform::~SceneItemTransform() {
|
||||
std::for_each(
|
||||
this->children.begin(),
|
||||
this->children.end(),
|
||||
[](std::weak_ptr<SceneItem> &item) {
|
||||
if(auto child = item.lock()) {
|
||||
child->parent.reset();
|
||||
child->updateWorldTransformFromParent();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
103
src/dawn/scene/item/SceneItemTransform.hpp
Normal file
103
src/dawn/scene/item/SceneItemTransform.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
|
||||
class SceneItemTransform {
|
||||
protected:
|
||||
// Local (real) values
|
||||
glm::vec3 localPosition;
|
||||
glm::vec3 localScale;
|
||||
glm::quat localRotation;
|
||||
|
||||
// Cached (non-real) values
|
||||
glm::mat4 transformLocal;
|
||||
glm::mat4 transformWorld;
|
||||
|
||||
// Heirarchy
|
||||
std::weak_ptr<SceneItem> parent;
|
||||
std::vector<std::weak_ptr<SceneItem>> children;
|
||||
|
||||
/**
|
||||
* Unpacks the local transform into the local transform matrix values.
|
||||
*/
|
||||
void updateLocalValuesFromLocalTransform();
|
||||
|
||||
/**
|
||||
* Sets the local transform (and all local real values) to match the world
|
||||
* transform values.
|
||||
*/
|
||||
void updateLocalTransformFromWorldTransform();
|
||||
|
||||
/**
|
||||
* Updates the world transform of this items children.
|
||||
*/
|
||||
void updateChildrenWorldTransforms();
|
||||
|
||||
/**
|
||||
* Called by the parent of this item when it's transform changes.
|
||||
*/
|
||||
void updateWorldTransformFromParent();
|
||||
|
||||
public:
|
||||
SceneItemTransform();
|
||||
|
||||
/**
|
||||
* Returns the parent of this scene item.
|
||||
*
|
||||
* @return Pointer to the parent of this scene item.
|
||||
*/
|
||||
std::shared_ptr<SceneItem> getParent();
|
||||
|
||||
/**
|
||||
* Returns the children of this scene item.
|
||||
*
|
||||
* @return Vector of pointers to the children of this scene item.
|
||||
*/
|
||||
std::vector<std::shared_ptr<SceneItem>> getChildren();
|
||||
|
||||
/**
|
||||
* Returns the local transform of this item (relative to its parent).
|
||||
*
|
||||
* @return Local transform of this item.
|
||||
*/
|
||||
glm::mat4 getLocalTransform();
|
||||
|
||||
/**
|
||||
* Sets the transform of this item within world space (relative to scene
|
||||
* root)
|
||||
*
|
||||
* @param transform Transform of this item in world space.
|
||||
*/
|
||||
void setWorldTransform(const glm::mat4 transform);
|
||||
|
||||
/**
|
||||
* Returns whether or not this item is a child of the given item. This
|
||||
* will traverse up the entire heirarchy to confirm.
|
||||
*
|
||||
* @return True if this item is within the given item's heirarchy.
|
||||
*/
|
||||
bool_t isChildOf(std::shared_ptr<SceneItem> item);
|
||||
|
||||
/**
|
||||
* Orients this transform to look at a given point in world space.
|
||||
*
|
||||
* @param position Position of the origin of this transform.
|
||||
* @param look Position in world space this transform looks at.
|
||||
* @param up Up vector of this transform.
|
||||
*/
|
||||
void lookAt(
|
||||
const glm::vec3 position,
|
||||
const glm::vec3 look,
|
||||
const glm::vec3 up
|
||||
);
|
||||
|
||||
virtual ~SceneItemTransform();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user