added basic structures
This commit is contained in:
16
TSE_Core/src/BehaviourScripts/MeshContainer.cpp
Normal file
16
TSE_Core/src/BehaviourScripts/MeshContainer.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "MeshContainer.hpp"
|
||||
|
||||
TSE::MeshContainer::MeshContainer() = default;
|
||||
|
||||
TSE::MeshContainer::MeshContainer(Mesh *m)
|
||||
: mesh(m) {}
|
||||
|
||||
void TSE::MeshContainer::SetMesh(Mesh *m)
|
||||
{
|
||||
mesh = m;
|
||||
}
|
||||
|
||||
TSE::Mesh *TSE::MeshContainer::GetMesh() const
|
||||
{
|
||||
return mesh;
|
||||
}
|
||||
28
TSE_Core/src/BehaviourScripts/MeshContainer.hpp
Normal file
28
TSE_Core/src/BehaviourScripts/MeshContainer.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#define MESH_CONTAINER typeid(TSE::MeshContainer).name()
|
||||
|
||||
#include "Types.hpp"
|
||||
#include "Mesh.hpp"
|
||||
#include "elements/BehaviourScript.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class MeshContainer : public BehaviourScript
|
||||
{
|
||||
private:
|
||||
Mesh* mesh = nullptr;
|
||||
|
||||
public:
|
||||
MeshContainer();
|
||||
explicit MeshContainer(Mesh* mesh);
|
||||
|
||||
void SetMesh(Mesh* mesh);
|
||||
Mesh* GetMesh() const;
|
||||
|
||||
inline const char* GetName() override
|
||||
{
|
||||
return "Mesh Container";
|
||||
};
|
||||
};
|
||||
} // namespace TSE
|
||||
92
TSE_Core/src/BehaviourScripts/RectBase.cpp
Normal file
92
TSE_Core/src/BehaviourScripts/RectBase.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "RectBase.hpp"
|
||||
|
||||
#include "elements/Transformable.hpp"
|
||||
|
||||
TSE::RectBase::RectBase()
|
||||
{
|
||||
meshCach = Mesh::GetQuadMesh();
|
||||
}
|
||||
|
||||
TSE::Mesh *TSE::RectBase::GetMesh()
|
||||
{
|
||||
return &meshCach;
|
||||
}
|
||||
|
||||
void TSE::RectBase::SetCustomUVs(const std::vector<Vector2> &uvs)
|
||||
{
|
||||
meshCach.uvs = uvs;
|
||||
}
|
||||
|
||||
void TSE::RectBase::OnParentChanged(RectBase *parent)
|
||||
{
|
||||
if(anchors != Rect(0.5f,0.5f, 0.5f, 0.5f))
|
||||
RecalculateMesh(parent);
|
||||
}
|
||||
|
||||
bool IsTransformableRect(TSE::Transformable* trans)
|
||||
{
|
||||
if(trans == nullptr || !trans->HasBehaviourScript(RECT_BASE)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TSE::RectBase::RecalculateMesh(RectBase *parent)
|
||||
{
|
||||
// Determin parent size, or fallback to 1x1
|
||||
Vector2 psize (1,1);
|
||||
if(parent != nullptr)
|
||||
psize = parent->tmpSize;
|
||||
Vector2 phsize = psize * 0.5f;
|
||||
|
||||
|
||||
Vector2 pposoffset (0,0);
|
||||
if(parent != nullptr)
|
||||
{
|
||||
pposoffset = ((parent->pivit * 2) - Vector2::one) * phsize;
|
||||
}
|
||||
|
||||
Vector2 mappedAnchor = (Vector2::Midpoint(anchors.p1,anchors.p2) * 2 - Vector2::one) * phsize;
|
||||
pposoffset = pposoffset + mappedAnchor;
|
||||
|
||||
Vector2 strechscaler = anchors.p2 - anchors.p1;
|
||||
|
||||
tmpSize = psize * strechscaler + size;
|
||||
|
||||
Vector2 hs = tmpSize * 0.5f;
|
||||
|
||||
Vector2 mappedPivit = pivit * 2 - Vector2::one;
|
||||
Vector2 pivitOffset = hs * mappedPivit;
|
||||
|
||||
meshCach.vertecies.clear();
|
||||
meshCach.vertecies.push_back(Vector2(-hs.x, -hs.y) + pivitOffset);
|
||||
meshCach.vertecies.push_back(Vector2( hs.x, -hs.y) + pivitOffset);
|
||||
meshCach.vertecies.push_back(Vector2( hs.x, hs.y) + pivitOffset);
|
||||
meshCach.vertecies.push_back(Vector2(-hs.x, hs.y) + pivitOffset);
|
||||
|
||||
|
||||
baseObject->position = pposoffset;
|
||||
|
||||
lastSize = size;
|
||||
lastAnchors = anchors;
|
||||
lastPivit = pivit;
|
||||
|
||||
// Notify children of change
|
||||
auto children = baseObject->GetChildren();
|
||||
for(auto child : children)
|
||||
{
|
||||
if(IsTransformableRect(child))
|
||||
{
|
||||
((RectBase*)child->GetBehaviourScript(RECT_BASE))->OnParentChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TSE::RectBase::OnUpdate()
|
||||
{
|
||||
if(lastSize != size || lastAnchors != anchors || pivit != lastPivit){
|
||||
//local change
|
||||
RectBase* parent = nullptr;
|
||||
if(baseObject->GetParent() != nullptr)
|
||||
parent = (RectBase*)baseObject->GetParent()->GetBehaviourScript(RECT_BASE);
|
||||
RecalculateMesh(parent);
|
||||
}
|
||||
}
|
||||
42
TSE_Core/src/BehaviourScripts/RectBase.hpp
Normal file
42
TSE_Core/src/BehaviourScripts/RectBase.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#define RECT_BASE typeid(TSE::RectBase).name()
|
||||
|
||||
#include "elements/BehaviourScript.hpp"
|
||||
#include "Rect.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Mesh.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class RectBase : public BehaviourScript
|
||||
{
|
||||
private:
|
||||
Rect lastAnchors = Rect(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
Vector2 lastSize = Vector2(0,0);
|
||||
Vector2 lastPivit = Vector2(0.5f,0.5f);
|
||||
Mesh meshCach;
|
||||
|
||||
Vector2 tmpSize;
|
||||
|
||||
public:
|
||||
Rect anchors = Rect(0.5f,0.5f, 0.5f, 0.5f); //streching in parent
|
||||
Vector2 size = Vector2(1,1); //size
|
||||
Vector2 pivit = Vector2(0.5f,0.5f); //positioning in parent
|
||||
|
||||
RectBase();
|
||||
Mesh* GetMesh();
|
||||
void SetCustomUVs(const std::vector<Vector2>& uvs);
|
||||
|
||||
private:
|
||||
void OnParentChanged(RectBase* parent);
|
||||
void RecalculateMesh(RectBase *parent);
|
||||
|
||||
public:
|
||||
void OnUpdate() override;
|
||||
inline const char* GetName() override
|
||||
{
|
||||
return "Rect Base";
|
||||
}
|
||||
};
|
||||
} // namespace TSE
|
||||
42
TSE_Core/src/BehaviourScripts/Renderable.cpp
Normal file
42
TSE_Core/src/BehaviourScripts/Renderable.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "Renderable.hpp"
|
||||
|
||||
#include <typeinfo>
|
||||
#include "MeshContainer.hpp"
|
||||
#include "elements/Transformable.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
Renderable::Renderable() = default;
|
||||
|
||||
Renderable::Renderable(Material* mat)
|
||||
{
|
||||
SetMaterial(mat);
|
||||
}
|
||||
|
||||
void Renderable::SetMaterial(Material* mat) {
|
||||
material = mat;
|
||||
}
|
||||
|
||||
Material* Renderable::GetMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
Mesh* Renderable::GetMeshContainer() const {
|
||||
if(baseObject->HasBehaviourScript(MESH_CONTAINER))
|
||||
return dynamic_cast<MeshContainer*>(baseObject->GetBehaviourScript(MESH_CONTAINER))->GetMesh();
|
||||
// if(baseObject->HasBehaviourScript(RECT_BASE))
|
||||
// return dynamic_cast<RectBase*>(baseObject->GetBehaviourScript(RECT_BASE))->GetMesh();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Vector3* Renderable::GetVertices() const {
|
||||
auto* container = GetMeshContainer();
|
||||
return container ? container->vertecies.data() : nullptr;
|
||||
}
|
||||
|
||||
const Vector2* Renderable::GetUVs() const {
|
||||
auto* container = GetMeshContainer();
|
||||
return container ? container->uvs.data() : nullptr;
|
||||
}
|
||||
} // namespace TSE
|
||||
|
||||
35
TSE_Core/src/BehaviourScripts/Renderable.hpp
Normal file
35
TSE_Core/src/BehaviourScripts/Renderable.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#define RENDERABLE typeid(TSE::Renderable).name()
|
||||
|
||||
#include "elements/Material.hpp"
|
||||
#include "interfaces/IRenderable.hpp"
|
||||
#include "elements/BehaviourScript.hpp"
|
||||
#include "Mesh.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Renderable : public BehaviourScript, public IRenderable
|
||||
{
|
||||
private:
|
||||
Material* material = nullptr;
|
||||
|
||||
public:
|
||||
Renderable();
|
||||
explicit Renderable(Material* material);
|
||||
|
||||
const Vector3* GetVertices() const override;
|
||||
const Vector2* GetUVs() const override;
|
||||
const std::vector<ushort> GetIndices() const override;
|
||||
size_t GetVertexCount() const override;
|
||||
inline const char* GetName() override
|
||||
{
|
||||
return "Renderable";
|
||||
}
|
||||
void SetMaterial(Material* material);
|
||||
Material* GetMaterial();
|
||||
|
||||
private:
|
||||
Mesh* GetMeshContainer() const;
|
||||
};
|
||||
} // namespace TSE
|
||||
23
TSE_Core/src/elements/BehaviourScript.cpp
Normal file
23
TSE_Core/src/elements/BehaviourScript.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "BehaviourScript.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
BehaviourScript::BehaviourScript()
|
||||
: baseObject(nullptr), enabled(true) {}
|
||||
|
||||
void BehaviourScript::SetEnabled(bool value) {
|
||||
enabled = value;
|
||||
}
|
||||
|
||||
bool BehaviourScript::IsEnabled() const {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void BehaviourScript::SetBaseObject(Transformable* obj) {
|
||||
baseObject = obj;
|
||||
}
|
||||
|
||||
Transformable* BehaviourScript::GetTransform() const {
|
||||
return baseObject;
|
||||
}
|
||||
} // namespace TSE
|
||||
29
TSE_Core/src/elements/BehaviourScript.hpp
Normal file
29
TSE_Core/src/elements/BehaviourScript.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Transformable;
|
||||
|
||||
class BehaviourScript
|
||||
{
|
||||
public:
|
||||
BehaviourScript();
|
||||
virtual ~BehaviourScript() = default;
|
||||
|
||||
inline virtual void OnUpdate() { };
|
||||
inline virtual void OnEnable() { };
|
||||
inline virtual void OnDisable() { };
|
||||
inline virtual void Start() { };
|
||||
virtual const char* GetName() = 0;
|
||||
inline virtual void CustomDraw(const bool& debug) { };
|
||||
void SetEnabled(bool v);
|
||||
bool IsEnabled() const;
|
||||
|
||||
void SetBaseObject(Transformable* obj);
|
||||
Transformable* GetTransform() const;
|
||||
|
||||
Transformable* baseObject;
|
||||
protected:
|
||||
bool enabled = true;
|
||||
};
|
||||
} // namespace TSE
|
||||
96
TSE_Core/src/elements/Layer.cpp
Normal file
96
TSE_Core/src/elements/Layer.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "Layer.hpp"
|
||||
#include "BehaviourScripts/Renderable.hpp"
|
||||
#include "elements/BehaviourScript.hpp"
|
||||
|
||||
void HandleObject(TSE::Transformable* trans, TSE::TransformationStack& stack, TSE::IRenderer& rnd)
|
||||
{
|
||||
using namespace TSE;
|
||||
if(!trans->IsEnabled()) return;
|
||||
//OPTIMIZE this if statement
|
||||
if(trans->HasBehaviourScript(RENDERABLE) && trans->GetBehaviourScript(RENDERABLE)->IsEnabled() && ((Renderable*)trans->GetBehaviourScript(RENDERABLE))->GetMaterial() != nullptr && ((Renderable*)trans->GetBehaviourScript(RENDERABLE))->GetMaterial()->GetShader() != nullptr)
|
||||
{
|
||||
rnd.Submit(*trans, ((Renderable*)trans->GetBehaviourScript(RENDERABLE))->GetMaterial()->GetShader(), stack);
|
||||
}
|
||||
if(trans->GetChildren().size() > 0)
|
||||
{
|
||||
stack.Push(trans->GetLocalMatrix());
|
||||
for(auto child : trans->GetChildren())
|
||||
{
|
||||
HandleObject(child, stack, rnd);
|
||||
}
|
||||
stack.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
TSE::Layer::Layer(string &n)
|
||||
{
|
||||
name = n;
|
||||
}
|
||||
|
||||
void TSE::Layer::Render(IRenderer &rnd) const
|
||||
{
|
||||
TransformationStack stack;
|
||||
for(auto obj : objectsToRender)
|
||||
{
|
||||
HandleObject(obj, stack, rnd);
|
||||
}
|
||||
}
|
||||
|
||||
void TSE::Layer::AddTransformable(Transformable *t)
|
||||
{
|
||||
objectsToRender.push_back(t);
|
||||
}
|
||||
|
||||
bool TSE::Layer::HasTransformable(const Transformable *t) const
|
||||
{
|
||||
for(auto trans2 : objectsToRender)
|
||||
{
|
||||
if(t->id == trans2->id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TSE::Layer::RemoveTransformable(const Transformable *t)
|
||||
{
|
||||
RemoveTransformable(t->id);
|
||||
}
|
||||
|
||||
void TSE::Layer::RemoveTransformable(const uuids::uuid id)
|
||||
{
|
||||
auto it = objectsToRender.begin();
|
||||
for(auto trans : objectsToRender)
|
||||
{
|
||||
if(trans->id == id)
|
||||
{
|
||||
objectsToRender.erase(it);
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
TSE::string TSE::Layer::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void TSE::Layer::SetName(const string &n)
|
||||
{
|
||||
name = n;
|
||||
}
|
||||
|
||||
std::vector<TSE::Transformable *> &TSE::Layer::GetAllObjects()
|
||||
{
|
||||
return objectsToRender;
|
||||
}
|
||||
|
||||
void TSE::Layer::Update()
|
||||
{
|
||||
for(auto trans : objectsToRender)
|
||||
{
|
||||
trans->Update();
|
||||
}
|
||||
}
|
||||
31
TSE_Core/src/elements/Layer.hpp
Normal file
31
TSE_Core/src/elements/Layer.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "Transformable.hpp"
|
||||
#include "Types.hpp"
|
||||
#include "interfaces/IRenderer.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Layer
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
std::vector<Transformable*> objectsToRender;
|
||||
|
||||
public:
|
||||
Layer(string& name);
|
||||
|
||||
void Render(IRenderer& rnd) const;
|
||||
void AddTransformable(Transformable* t);
|
||||
bool HasTransformable(const Transformable* t) const;
|
||||
|
||||
void RemoveTransformable(const Transformable* t);
|
||||
void RemoveTransformable(const uuids::uuid id);
|
||||
|
||||
string GetName() const;
|
||||
void SetName(const string& name);
|
||||
std::vector<Transformable*>& GetAllObjects();
|
||||
void Update();
|
||||
};
|
||||
} // namespace TSE
|
||||
81
TSE_Core/src/elements/Material.cpp
Normal file
81
TSE_Core/src/elements/Material.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "Material.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include "IdGenerator.hpp"
|
||||
#include "interfaces/ITexture.hpp"
|
||||
#include "Types.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector4.hpp"
|
||||
#include "Color.hpp"
|
||||
#include "Matrix4x4.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
Material::Material()
|
||||
: name(""), shader(nullptr)
|
||||
{
|
||||
id = GenerateRandomUUID();
|
||||
}
|
||||
Material::Material(const string& name, IShader* shader, uuids::uuid id)
|
||||
: name(name), shader(shader), id(id) {}
|
||||
|
||||
Material::Material(const string &name, IShader *shader)
|
||||
: name(name), shader(shader)
|
||||
{
|
||||
id = GenerateRandomUUID();
|
||||
}
|
||||
bool Material::HasValue(const string &key) const
|
||||
{
|
||||
return values.find(key) != values.end();
|
||||
}
|
||||
int Material::GetValueCount() const
|
||||
{
|
||||
return values.size();
|
||||
}
|
||||
std::tuple<std::any, string, string> &Material::GetValueAt(int j)
|
||||
{
|
||||
auto it = values.begin();
|
||||
for (int i = 0; i < j; i++)
|
||||
{
|
||||
it++;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
string &Material::GetName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
IShader *Material::GetShader() const
|
||||
{
|
||||
return shader;
|
||||
}
|
||||
void Material::SetShader(IShader *shader)
|
||||
{
|
||||
this->shader = shader;
|
||||
}
|
||||
uuids::uuid Material::GetID() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
template void Material::SetValue<int>(const string&, const int&);
|
||||
template void Material::SetValue<float>(const string&, const float&);
|
||||
template void Material::SetValue<Vector2>(const string&, const Vector2&);
|
||||
template void Material::SetValue<Vector3>(const string&, const Vector3&);
|
||||
template void Material::SetValue<Vector4>(const string&, const Vector4&);
|
||||
template void Material::SetValue<Matrix4x4>(const string&, const Matrix4x4&);
|
||||
template void Material::SetValue<Color>(const string&, const Color&);
|
||||
template void Material::SetValue<string>(const string&, const string&);
|
||||
template void Material::SetValue<ITexture>(const string&, const ITexture*);
|
||||
|
||||
template int Material::GetValue<int>(const string&) const;
|
||||
template float Material::GetValue<float>(const string&) const;
|
||||
template Vector2 Material::GetValue<Vector2>(const string&) const;
|
||||
template Vector3 Material::GetValue<Vector3>(const string&) const;
|
||||
template Vector4 Material::GetValue<Vector4>(const string&) const;
|
||||
template Matrix4x4 Material::GetValue<Matrix4x4>(const string&) const;
|
||||
template Color Material::GetValue<Color>(const string&) const;
|
||||
template string Material::GetValue<string>(const string&) const;
|
||||
template ITexture* Material::GetValue<ITexture*>(const string&) const;
|
||||
} // namespace TSE
|
||||
65
TSE_Core/src/elements/Material.hpp
Normal file
65
TSE_Core/src/elements/Material.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include "uuid.h"
|
||||
#include "interfaces/IShader.hpp"
|
||||
#include <unordered_map>
|
||||
#include <any>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
struct Material
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
uuids::uuid id;
|
||||
IShader* shader;
|
||||
|
||||
std::unordered_map<string, std::tuple<std::any, string, string>> values;
|
||||
|
||||
public:
|
||||
Material();
|
||||
Material(const string& name, IShader* shader);
|
||||
Material(const string& name, IShader* shader, uuids::uuid id);
|
||||
|
||||
template<typename T>
|
||||
void SetValue(const string& key, const T& value);
|
||||
|
||||
template<typename T>
|
||||
T GetValue(const string& key) const;
|
||||
|
||||
template<typename T>
|
||||
void SetValue(const string& key, const T* value);
|
||||
|
||||
bool HasValue(const string& key) const;
|
||||
int GetValueCount() const;
|
||||
|
||||
std::tuple<std::any, string, string>& GetValueAt(int i);
|
||||
string& GetName();
|
||||
IShader* GetShader() const;
|
||||
void SetShader(IShader* shader);
|
||||
uuids::uuid GetID() const;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void Material::SetValue(const string& key, const T& value) {
|
||||
values[key] = std::make_tuple(value, typeid(T).name(), key);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Material::GetValue(const string& key) const {
|
||||
auto it = values.find(key);
|
||||
if (it == values.end()) {
|
||||
throw std::runtime_error("Material::GetValue - key '" + key + "' not found");
|
||||
}
|
||||
auto [a,b,c] = it->second;
|
||||
return std::any_cast<T>(a);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Material::SetValue(const string& key, const T* value) {
|
||||
values[key] = std::make_tuple(value, typeid(T).name(), key);
|
||||
}
|
||||
|
||||
} // namespace TSE
|
||||
469
TSE_Core/src/elements/Transformable.cpp
Normal file
469
TSE_Core/src/elements/Transformable.cpp
Normal file
@@ -0,0 +1,469 @@
|
||||
#include "Transformable.hpp"
|
||||
|
||||
#include "IdGenerator.hpp"
|
||||
#include "MathF.hpp"
|
||||
#include "BehaviourScript.hpp"
|
||||
#include "Layer.hpp"
|
||||
#include "Debug.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
Transformable::Transformable()
|
||||
: position(0, 0, 0), scale(1, 1, 1), rotation(), name("")
|
||||
{
|
||||
id = GenerateRandomUUID();
|
||||
objectEntries[id] = this;
|
||||
}
|
||||
|
||||
Transformable::Transformable(uuids::uuid id)
|
||||
: id(id), position(0, 0, 0), scale(1, 1, 1), rotation(), name("")
|
||||
{
|
||||
objectEntries[id] = this;
|
||||
}
|
||||
|
||||
Transformable::Transformable(const string &name)
|
||||
: position(0, 0, 0), scale(1, 1, 1), rotation(), name(name)
|
||||
{
|
||||
id = GenerateRandomUUID();
|
||||
objectEntries[id] = this;
|
||||
}
|
||||
|
||||
Transformable::Transformable(const string &name, uuids::uuid id)
|
||||
: id(id), position(0, 0, 0), scale(1, 1, 1), rotation(), name(name)
|
||||
{
|
||||
objectEntries[id] = this;
|
||||
}
|
||||
|
||||
Vector3 Transformable::forward() const
|
||||
{
|
||||
return Vector3::Normalize(GetGlobalMatrix() * Vector3::forward - GetGlobalMatrix() * Vector3::zero);
|
||||
}
|
||||
|
||||
Vector3 Transformable::right() const
|
||||
{
|
||||
return Vector3::Normalize(GetGlobalMatrix() * Vector3::right - GetGlobalMatrix() * Vector3::zero);
|
||||
}
|
||||
|
||||
Vector3 Transformable::up() const
|
||||
{
|
||||
return Vector3::Normalize(GetGlobalMatrix() * Vector3::up - GetGlobalMatrix() * Vector3::zero);
|
||||
}
|
||||
|
||||
Vector3 Transformable::GetPosition() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
void Transformable::SetPosition(const Vector3 &pos)
|
||||
{
|
||||
position = pos;
|
||||
}
|
||||
|
||||
Quaternion Transformable::GetRotation() const
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void Transformable::SetRotation(const Quaternion &rot)
|
||||
{
|
||||
rotation = rot;
|
||||
}
|
||||
|
||||
Vector3 Transformable::GetScale() const
|
||||
{
|
||||
return scale;
|
||||
}
|
||||
|
||||
void Transformable::SetScale(const Vector3 &s)
|
||||
{
|
||||
scale = s;
|
||||
}
|
||||
|
||||
string Transformable::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
uuids::uuid Transformable::GetId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
Vector3 Transformable::GetEuler()
|
||||
{
|
||||
return rotation.ToEulerAngles();
|
||||
}
|
||||
|
||||
void Transformable::SetEuler(const Vector3 &euler)
|
||||
{
|
||||
rotation = Quaternion::FromEulerAngles(euler);
|
||||
}
|
||||
|
||||
int Transformable::GetComponentCount()
|
||||
{
|
||||
return components.size();
|
||||
}
|
||||
|
||||
Matrix4x4 Transformable::GetLocalMatrix() const
|
||||
{
|
||||
return Matrix4x4::ToTranslationMatrix(position) * Matrix4x4::ToRotationMatrix(rotation) * Matrix4x4::ToScaleMatrix(scale);;
|
||||
}
|
||||
|
||||
Matrix4x4 Transformable::GetGlobalMatrix() const
|
||||
{
|
||||
if (parent != nullptr)
|
||||
return parent->GetGlobalMatrix() * GetLocalMatrix();
|
||||
return GetLocalMatrix();
|
||||
}
|
||||
|
||||
Vector3 Transformable::GetGlobalPosition() const
|
||||
{
|
||||
return LocalToGlobalPosition(Vector3::zero);
|
||||
}
|
||||
|
||||
Vector3 Transformable::GlobalToLocalPosition(const Vector3& global) const
|
||||
{
|
||||
Matrix4x4 globalMatrix = GetGlobalMatrix();
|
||||
if(globalMatrix.IsAffine())
|
||||
{
|
||||
globalMatrix.InvertAffine();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalMatrix.Invert();
|
||||
}
|
||||
return globalMatrix * global;
|
||||
}
|
||||
|
||||
Vector3 Transformable::LocalToGlobalPosition(const Vector3& local) const
|
||||
{
|
||||
return GetGlobalMatrix() * local;
|
||||
}
|
||||
|
||||
void Transformable::LookAt_2D(const Vector3& globalTarget)
|
||||
{
|
||||
Vector3 to = globalTarget - GetGlobalPosition();
|
||||
Vector3 toXY = {to.x, to.y, 0.0f};
|
||||
if(Vector3::Dot(toXY, toXY) < TSE_EPSILON) return;
|
||||
toXY.Normalize();
|
||||
|
||||
Vector3 fwdWorld = rotation.Rotate(Vector3::up);
|
||||
Vector3 fwdXY = Vector3(fwdWorld.x, fwdWorld.y, 0);
|
||||
fwdXY.Normalize();
|
||||
|
||||
float cosA = std::clamp(Vector3::Dot(fwdXY, toXY), -1.0f, 1.0f);
|
||||
float sinA = fwdXY.x * toXY.y - fwdXY.y * toXY.x;
|
||||
float angle = atan2(sinA, cosA);
|
||||
|
||||
Quaternion twist = Quaternion::FromAngleAxis(angle, Vector3::forward);
|
||||
rotation = twist * rotation;
|
||||
}
|
||||
|
||||
void Transformable::SetParent(Transformable *p)
|
||||
{
|
||||
Transformable* t(this);
|
||||
if (parent != nullptr && parent != p) {
|
||||
|
||||
auto it = parent->children.begin();
|
||||
for (int i = 0; i < parent->children.size(); i++)
|
||||
{
|
||||
if(**it == *t)
|
||||
{
|
||||
parent->children.erase(it);
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (p != nullptr && p != parent) {
|
||||
p->children.push_back(t);
|
||||
}
|
||||
parent = p;
|
||||
}
|
||||
|
||||
Transformable *Transformable::GetParent() const
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
const std::vector<Transformable *> &Transformable::GetChildren() const
|
||||
{
|
||||
return children;
|
||||
}
|
||||
|
||||
bool Transformable::IsMyChild(Transformable *other)
|
||||
{
|
||||
for (auto child : children)
|
||||
{
|
||||
if(child->id == other->id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(child->IsMyChild(other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Transformable::MoveUp(Layer *l)
|
||||
{
|
||||
if(l != nullptr)
|
||||
{
|
||||
auto it = l->GetAllObjects().begin();
|
||||
for(int i = 0; i < l->GetAllObjects().size(); i++)
|
||||
{
|
||||
if((*it)->id == id)
|
||||
{
|
||||
if(i == 0) return;
|
||||
std::swap(l->GetAllObjects()[i - 1], l->GetAllObjects()[i]);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto it = parent->children.begin();
|
||||
for(int i = 0; i < parent->children.size(); i++)
|
||||
{
|
||||
if((*it)->id == id)
|
||||
{
|
||||
if(i == 0) return;
|
||||
std::swap(parent->children[i - 1], parent->children[i]);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void Transformable::MoveDown(Layer *l)
|
||||
{
|
||||
if(l != nullptr)
|
||||
{
|
||||
auto it = l->GetAllObjects().begin();
|
||||
for(int i = 0; i < l->GetAllObjects().size(); i++)
|
||||
{
|
||||
if((*it)->id == id)
|
||||
{
|
||||
if(i == l->GetAllObjects().size() - 1) return;
|
||||
std::swap(l->GetAllObjects()[i + 1], l->GetAllObjects()[i]);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto it = parent->children.begin();
|
||||
for(int i = 0; i < parent->children.size(); i++)
|
||||
{
|
||||
if((*it)->id == id)
|
||||
{
|
||||
if(i == parent->children.size() - 1) return;
|
||||
std::swap(parent->children[i + 1], parent->children[i]);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
bool Transformable::IsEnabled() const
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
void Transformable::SetEnabled(bool v)
|
||||
{
|
||||
if (_enabled != v) {
|
||||
_enabled = v;
|
||||
if (_enabled) OnEnable();
|
||||
else OnDisable();
|
||||
}
|
||||
}
|
||||
|
||||
BehaviourScript *Transformable::AddBehaviourScript(BehaviourScript *script)
|
||||
{
|
||||
if (!script) return nullptr;
|
||||
const std::string key = typeid(*script).name();
|
||||
components.emplace(key, script);
|
||||
script->SetBaseObject(this);
|
||||
script->Start();
|
||||
return script;
|
||||
}
|
||||
|
||||
BehaviourScript *Transformable::GetBehaviourScript(const string &name) const
|
||||
{
|
||||
auto it = components.find(name);
|
||||
return (it != components.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
BehaviourScript *Transformable::GetBehaviourScriptAt(const int i) const
|
||||
{
|
||||
auto it = components.begin();
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
it++;
|
||||
|
||||
}
|
||||
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
std::vector<BehaviourScript *> Transformable::GetAllBehaviourScripts(const string &name) const
|
||||
{
|
||||
std::vector<BehaviourScript *> res;
|
||||
|
||||
auto it = components.begin();
|
||||
while(it != components.end())
|
||||
{
|
||||
if((*it).first == name)
|
||||
{
|
||||
res.push_back((*it).second);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Transformable::RemoveBehaviourScript(BehaviourScript *script)
|
||||
{
|
||||
for (auto it = components.begin(); it != components.end(); ++it) {
|
||||
if (it->second == script) {
|
||||
components.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Transformable::HasBehaviourScript(const string &name) const
|
||||
{
|
||||
auto it = components.find(name);
|
||||
return it != components.end();
|
||||
}
|
||||
|
||||
void Transformable::Update()
|
||||
{
|
||||
for (auto& [name, script] : components) {
|
||||
if (script && script->IsEnabled()) script->OnUpdate();
|
||||
}
|
||||
for (auto child : children)
|
||||
{
|
||||
child->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void Transformable::Delete(Transformable *t)
|
||||
{
|
||||
objectEntries.erase(t->id);
|
||||
delete t;
|
||||
}
|
||||
|
||||
void Transformable::Delete(const uuids::uuid id)
|
||||
{
|
||||
if(!Exists(id)) return;
|
||||
Transformable* t = objectEntries.at(id);
|
||||
objectEntries.erase(id);
|
||||
delete t;
|
||||
}
|
||||
|
||||
void Transformable::HardDelete(Transformable *t, bool onlyThis)
|
||||
{
|
||||
//deleting children
|
||||
if(!onlyThis)
|
||||
for(auto child : t->children)
|
||||
{
|
||||
HardDelete(child);
|
||||
}
|
||||
|
||||
//deleting atteched scripts
|
||||
for (auto& [_, script] : t->components)
|
||||
delete script;
|
||||
|
||||
//deleting self
|
||||
Delete(t);
|
||||
}
|
||||
|
||||
void Transformable::HardDelete(const uuids::uuid id, bool onlyThis)
|
||||
{
|
||||
if(!Exists(id)) return;
|
||||
Transformable* t = objectEntries.at(id);
|
||||
//deleting children
|
||||
if(!onlyThis)
|
||||
for(auto child : t->children)
|
||||
{
|
||||
HardDelete(child);
|
||||
}
|
||||
|
||||
//deleting atteched scripts
|
||||
for (auto& [_, script] : t->components)
|
||||
delete script;
|
||||
|
||||
//deleting self
|
||||
Delete(t);
|
||||
}
|
||||
|
||||
void Transformable::DeleteAll()
|
||||
{
|
||||
auto it = objectEntries.begin();
|
||||
for(int i = 0; i < objectEntries.size(); i++)
|
||||
{
|
||||
delete it->second;
|
||||
it++;
|
||||
}
|
||||
objectEntries.clear();
|
||||
}
|
||||
|
||||
bool Transformable::Exists(const uuids::uuid id)
|
||||
{
|
||||
auto it = objectEntries.find(id);
|
||||
return it != objectEntries.end();
|
||||
}
|
||||
|
||||
bool Transformable::operator==(const Transformable &other) const
|
||||
{
|
||||
return other.id == id;
|
||||
}
|
||||
|
||||
bool Transformable::operator!=(const Transformable &other) const
|
||||
{
|
||||
return other.id != id;
|
||||
}
|
||||
|
||||
void Transformable::OnEnable()
|
||||
{
|
||||
for (auto& [_, script] : components)
|
||||
if (script && script->IsEnabled()) script->OnEnable();
|
||||
}
|
||||
|
||||
void Transformable::OnDisable()
|
||||
{
|
||||
for (auto& [_, script] : components)
|
||||
if (script && script->IsEnabled()) script->OnDisable();
|
||||
}
|
||||
|
||||
int Transformable::GetTansformableCount()
|
||||
{
|
||||
return objectEntries.size();
|
||||
}
|
||||
|
||||
Transformable *Transformable::Find(string name)
|
||||
{
|
||||
for(auto obj : objectEntries)
|
||||
{
|
||||
if(obj.second->name == name)
|
||||
{
|
||||
return obj.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Transformable *Transformable::Find(uuids::uuid id)
|
||||
{
|
||||
for(auto obj : objectEntries)
|
||||
{
|
||||
if(obj.second->id == id)
|
||||
{
|
||||
return obj.second;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace TSE
|
||||
106
TSE_Core/src/elements/Transformable.hpp
Normal file
106
TSE_Core/src/elements/Transformable.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vector3.hpp"
|
||||
#include "Quaternion.hpp"
|
||||
#include "Matrix4x4.hpp"
|
||||
#include "uuid.h"
|
||||
#include "Types.hpp"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class BehaviourScript;
|
||||
class Layer;
|
||||
|
||||
class Transformable
|
||||
{
|
||||
public:
|
||||
Vector3 position;
|
||||
Vector3 scale;
|
||||
Quaternion rotation;
|
||||
string name;
|
||||
bool _enabled = true;
|
||||
uuids::uuid id;
|
||||
|
||||
private:
|
||||
std::unordered_multimap<string, BehaviourScript*> components;
|
||||
std::vector<Transformable*> children;
|
||||
Transformable* parent = nullptr;
|
||||
|
||||
static std::unordered_map<uuids::uuid, Transformable*> objectEntries;
|
||||
|
||||
public:
|
||||
Transformable();
|
||||
Transformable(uuids::uuid id);
|
||||
Transformable(const string& name);
|
||||
Transformable(const string& name, uuids::uuid id);
|
||||
~Transformable() = default;
|
||||
|
||||
Vector3 forward() const;
|
||||
Vector3 right() const;
|
||||
Vector3 up() const;
|
||||
|
||||
Vector3 GetPosition() const;
|
||||
void SetPosition(const Vector3& pos);
|
||||
Quaternion GetRotation() const;
|
||||
void SetRotation(const Quaternion& rot);
|
||||
Vector3 GetScale() const;
|
||||
void SetScale(const Vector3& scale);
|
||||
string GetName() const;
|
||||
uuids::uuid GetId() const;
|
||||
Vector3 GetEuler();
|
||||
void SetEuler(const Vector3& euler);
|
||||
int GetComponentCount();
|
||||
Matrix4x4 GetLocalMatrix() const;
|
||||
Matrix4x4 GetGlobalMatrix() const;
|
||||
Vector3 GetGlobalPosition() const;
|
||||
|
||||
Vector3 GlobalToLocalPosition(const Vector3& global) const;
|
||||
Vector3 LocalToGlobalPosition(const Vector3& local) const;
|
||||
|
||||
void LookAt_2D(const Vector3& globalTarget);
|
||||
|
||||
void SetParent(Transformable* parent);
|
||||
Transformable* GetParent() const;
|
||||
const std::vector<Transformable*>& GetChildren() const;
|
||||
bool IsMyChild(Transformable* other);
|
||||
|
||||
void MoveUp(Layer* l = nullptr);
|
||||
void MoveDown(Layer* l = nullptr);
|
||||
|
||||
bool IsEnabled() const;
|
||||
void SetEnabled(bool v);
|
||||
|
||||
BehaviourScript* AddBehaviourScript(BehaviourScript* script);
|
||||
BehaviourScript* GetBehaviourScript(const string& name) const;
|
||||
BehaviourScript* GetBehaviourScriptAt(const int i) const;
|
||||
std::vector<BehaviourScript*> GetAllBehaviourScripts(const string& name) const;
|
||||
void RemoveBehaviourScript(BehaviourScript* script);
|
||||
bool HasBehaviourScript(const string& name) const;
|
||||
|
||||
void Update();
|
||||
|
||||
static void Delete(Transformable* t);
|
||||
static void Delete(const uuids::uuid id);
|
||||
static void HardDelete(Transformable* t, bool onlyThis = false);
|
||||
static void HardDelete(const uuids::uuid id, bool onlyThis = false);
|
||||
static void DeleteAll();
|
||||
|
||||
static bool Exists(const uuids::uuid id);
|
||||
|
||||
bool operator==(const Transformable& other) const;
|
||||
bool operator!=(const Transformable& other) const;
|
||||
|
||||
private:
|
||||
void OnEnable();
|
||||
void OnDisable();
|
||||
|
||||
public:
|
||||
|
||||
static int GetTansformableCount();
|
||||
static Transformable* Find(string name);
|
||||
static Transformable* Find(uuids::uuid id);
|
||||
};
|
||||
}
|
||||
18
TSE_Core/src/interfaces/IRenderable.hpp
Normal file
18
TSE_Core/src/interfaces/IRenderable.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IRenderable
|
||||
{
|
||||
public:
|
||||
virtual const Vector3* GetVertices() const = 0;
|
||||
virtual const Vector2* GetUVs() const = 0;
|
||||
virtual const std::vector<ushort> GetIndices() const = 0;
|
||||
virtual size_t GetVertexCount() const = 0;
|
||||
virtual ~IRenderable() = default;
|
||||
};
|
||||
} // namespace TSE
|
||||
3
TSE_Core/src/interfaces/IRenderer.cpp
Normal file
3
TSE_Core/src/interfaces/IRenderer.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "IRenderer.hpp"
|
||||
|
||||
std::vector<TSE::Camera*> TSE::IRenderer::camerasToRenderWith = std::vector<TSE::Camera*>();
|
||||
26
TSE_Core/src/interfaces/IRenderer.hpp
Normal file
26
TSE_Core/src/interfaces/IRenderer.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "IShader.hpp"
|
||||
#include "TransformationStack.hpp"
|
||||
#include "elements/Transformable.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class Camera;
|
||||
|
||||
class IRenderer
|
||||
{
|
||||
public:
|
||||
|
||||
static std::vector<Camera*> camerasToRenderWith;
|
||||
|
||||
virtual void End() = 0;
|
||||
virtual void Flush() = 0;
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void Submit(const Transformable& trans, TransformationStack& stack) = 0;
|
||||
virtual void Submit(const Transformable& trans, IShader* shader, TransformationStack& stack) = 0;
|
||||
|
||||
virtual ~IRenderer() = default;
|
||||
};
|
||||
} // namespace TSE
|
||||
29
TSE_Core/src/interfaces/IShader.hpp
Normal file
29
TSE_Core/src/interfaces/IShader.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "Types.hpp"
|
||||
#include "Matrix4x4.hpp"
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector3.hpp"
|
||||
#include "Vector4.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class IShader
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void Bind() const = 0;
|
||||
virtual void Unbind() const = 0;
|
||||
|
||||
virtual void SetUniform(const char* name, int value) = 0;
|
||||
virtual void SetUniform(const char* name, const int* value, int count) = 0;
|
||||
virtual void SetUniform(const char* name, const Matrix4x4* value) = 0;
|
||||
virtual void SetUniform(const char* name, float value) = 0;
|
||||
virtual void SetUniform(const char* name, const float* value, int count) = 0;
|
||||
virtual void SetUniform(const char* name, const Vector2* value) = 0;
|
||||
virtual void SetUniform(const char* name, const Vector3* value) = 0;
|
||||
virtual void SetUniform(const char* name, const Vector4* value) = 0;
|
||||
|
||||
virtual ~IShader() = default;
|
||||
};
|
||||
} // namespace TSE
|
||||
16
TSE_Core/src/interfaces/ITexture.hpp
Normal file
16
TSE_Core/src/interfaces/ITexture.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "Vector2.hpp"
|
||||
|
||||
namespace TSE
|
||||
{
|
||||
class ITexture
|
||||
{
|
||||
public:
|
||||
virtual ~ITexture() = default;
|
||||
virtual Vector2 size() const = 0;
|
||||
virtual float width() const = 0;
|
||||
virtual float height() const = 0;
|
||||
virtual uint GetTextureId() const = 0;
|
||||
};
|
||||
} // namespace TSE
|
||||
Reference in New Issue
Block a user