Begin refactor to support 2D & 3D Scenes.

This commit is contained in:
2024-08-19 22:31:17 -04:00
parent f5ab983176
commit 22711d1db1
25 changed files with 241 additions and 205 deletions

View File

@@ -49,7 +49,7 @@ CPMAddPackage(
CPMAddPackage(
NAME JGL
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-20.zip
URL https://git.redacted.cc/josh/JGL/archive/Prerelease-25.zip
)
CPMAddPackage(

View File

@@ -1,5 +1,5 @@
#pragma once
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
namespace Occlusion {
//TODO

View File

@@ -3,7 +3,7 @@
#include <Redacted3D/types/vertex.h>
#include <Redacted3D/types/texture.h>
#include <Redacted3D/types/shader.h>
#include <Redacted3D/types/entity/entity.h>
#include <Redacted3D/types/entity/baseEntity.h>
#include <J3ML/LinearAlgebra/Vector3.h>
using J3ML::LinearAlgebra::Vector3;
@@ -24,21 +24,22 @@ class Serializable {
// A wrapper around a Tree Hierarchy Data Model.
class DataModel : public Entity {
class DataModel : public BaseEntity {
public:
Entity * GetParent() const override {return nullptr;}
[[nodiscard]] BaseEntity* GetParent() const override {return nullptr;}
std::vector<Entity> GetFlatEntityList();
template <class T>
void Serialize(T& archive) {
Entity::SerializeMemberData(archive);
BaseEntity::SerializeMemberData(archive);
archive & GetFlatEntityList();
}
void SetParent(Entity *parent) override {
void SetParent(BaseEntity *parent) override {
throw std::runtime_error("Cannot set parent of Hierarchy Root!");
}
DataModel() : Entity() {}
DataModel() : BaseEntity() {}
[[nodiscard]] int getEntityCount() const;
[[nodiscard]] int getMobyCount() const;
};

View File

@@ -0,0 +1,8 @@
///A moby with skeletal animations.
//TODO
#pragma once
#include <Redacted3D/types/entity/3D/moby.h>
class Actor : public Moby {};

View File

@@ -1,5 +1,5 @@
#pragma once
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
#include <Redacted3D/engine/engine.h>
#include <glad/glad.h>
#include <J3ML/Geometry.h>

View File

@@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <Redacted3D/types/entity/baseEntity.h>
#include <Redacted3D/types/vertex.h>
#include <Redacted3D/types/texture.h>
#include <J3ML/LinearAlgebra/Matrix4x4.h>
@@ -13,7 +14,7 @@ using J3ML::LinearAlgebra::Vector3;
typedef Vector3 Direction;
///Base entity type.
class Entity {
class Entity : public BaseEntity {
private:
///Pitch Yaw Roll, The orientation of the entity in the world,
Vector3 angle = {0,0,0};
@@ -22,11 +23,6 @@ private:
///The scale it should be rendered at.
Vector3 scale = {1.0f, 1.0f, 1.0f};
protected:
///If the entity has a parent entity, It's here.
Entity* parent;
///Entity list of child entities.
std::vector<Entity*> children;
///Loads the geometry for it.
void loadGeometry(const std::string& file);
void loadTexture(const std::string& file);
@@ -34,23 +30,6 @@ void loadMultiTexture(const std::vector<std::string>& files);
void loadMotionTexture(const std::vector<std::string>& files, u16 frameDelta, bool doAnim = true);
public:
std::string name; //Entity name. TODO remove this.
bool alive;
virtual std::vector<std::string> GetEntityUUIDList() const { return std::vector<std::string> { "" }; }
template <class T>
void SerializeMemberData(T& archive)
{
archive & uuid.c_str() & name.c_str() & alive;
}
template <class T>
void Serialize(T& archive)
{
SerializeMemberData(archive);
archive & GetEntityUUIDList();
}
///Whether an entity is solid. Entities are solid by default.
bool collidable = true;
@@ -64,45 +43,13 @@ public:
Sphere getSphere();
///Returns the OBB of the entity.
OBB getOBB();
///Returns the entity list of the entities children.
std::vector<Entity*> GetChildren();
///Sets a given entity as this entities parent.
virtual void SetParent(Entity* parent);
bool IsDescendantOf(Entity* ancestor);
bool IsAncestorOf(Entity* descendant);
std::vector<Entity*> GetDescendants();
std::vector<Entity*> GetAncestors();
virtual Entity* GetParent() const { return parent;}
Entity* FindFirstChild(std::string search_name);
[[nodiscard]] Entity* GetFamilyTreeRoot() const;
Entity *Add(Entity *newChild);
void setScale(const float& multiplier);
[[nodiscard]] Vector3 getScale() const;
// TODO: Constrain to DerivedEntityType
template <typename T>
T* FindFirstChildOfType() const
{
for (auto& child : children) {
T* p = dynamic_cast<T>(child);
if (p != nullptr)
return p;
}
return nullptr;
}
void DescendantAdded(Entity* ent) {}
void DescendantRemoved(Entity* ent) {}
void AncestorAdded(Entity* ent) {}
void AncestorRemoved(Entity* ent) {}
protected:
Matrix4x4 coordinates;
J3ML::LinearAlgebra::Position position; /// X Y Z
public:
std::string uuid;
u32 ticksAlive; //At 64tps it'd take 776 days to overflow.
[[nodiscard]] Position GetPos() const;
void SetPos(const Position& rhs);
@@ -114,19 +61,11 @@ public:
void setAngle(float pitch, float yaw, float roll);
///Removes an entity from the list, Checks if the assets are being used by any other entity. Removes them from their lists & deletes. Then deletes the entity.
void erase();
bool draw = true;
bool occluded();
bool isCollidingWith(Entity* entity);
virtual void pre_render() {}
virtual void post_render() {}
virtual void jglRenderPass() {}
///The default rendering routine. Works for 99% of cases.
virtual void render();
virtual void update(float elapsed) {}
virtual void ticc(int tics)
{
ticksAlive++;
}
///Default rendering routine. Works in 99% of cases.
void render() override;
Entity();

View File

@@ -1,6 +1,6 @@
#pragma once
#include <Redacted3D/types/entity/entity.h>
#include <Redacted3D/types/entity/3D/entity.h>
///A "Movable Object". Things that will move often are derived from this.
class Moby : public Entity {

View File

@@ -1,7 +1,7 @@
#pragma once
#include <Redacted3D/types/vertex.h>
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
///Simple skybox, A sphere with a texture on it where the center of the sphere is always the camera.
class Skybox : public Moby {

View File

@@ -0,0 +1,67 @@
#pragma once
#include <vector>
#include <string>
#include <J3ML/J3ML.h>
class BaseEntity {
protected:
///If the entity has a parent entity, It's here.
BaseEntity* parent;
///Entity list of child entities.
std::vector<BaseEntity*> children;
public:
u32 ticksAlive;
bool draw = true;
std::string uuid;
std::string name;
bool alive;
virtual std::vector<std::string> GetEntityUUIDList() const { return std::vector<std::string> { "" }; }
BaseEntity() = default;
std::vector<BaseEntity*> GetChildren();
///Sets a given entity as this entities parent.
virtual void SetParent(BaseEntity* parent);
bool IsDescendantOf(BaseEntity* ancestor);
bool IsAncestorOf(BaseEntity* descendant);
std::vector<BaseEntity*> GetDescendants();
std::vector<BaseEntity*> GetAncestors();
[[nodiscard]] virtual BaseEntity* GetParent() const { return parent;}
BaseEntity* FindFirstChild(std::string search_name);
[[nodiscard]] BaseEntity* GetFamilyTreeRoot() const;
BaseEntity* Add(BaseEntity* newChild);
void DescendantAdded(BaseEntity* ent) {}
void DescendantRemoved(BaseEntity* ent) {}
void AncestorAdded(BaseEntity* ent) {}
void AncestorRemoved(BaseEntity* ent) {}
template <class T>
void SerializeMemberData(T& archive){ archive & uuid.c_str() & name.c_str() & alive; }
template <class T>
void Serialize(T& archive) {
SerializeMemberData(archive);
archive & GetEntityUUIDList();
}
// TODO: Constrain to DerivedEntityType
template <typename T>
T* FindFirstChildOfType() const
{
for (auto& child : children) {
T* p = dynamic_cast<T>(child);
if (p != nullptr)
return p;
}
return nullptr;
}
virtual void pre_render() {}
virtual void post_render() {}
virtual void jglRenderPass() {}
///The default rendering routine. Works for 99% of cases.
virtual void render() {}
virtual void update(float elapsed) {}
virtual void ticc(int tics) { ticksAlive++; }
};

View File

@@ -3,7 +3,7 @@
#include <iostream>
#include <cmath>
#include <cstdint>
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
class Ball : public Moby {
public:

View File

@@ -3,7 +3,7 @@
#include <iostream>
#include <cmath>
#include <cstdint>
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
class Cube : public Moby {
public:

View File

@@ -1,4 +1,4 @@
#include <Redacted3D/types/entity/skybox.h>
#include <Redacted3D/types/entity/3D/skybox.h>
#pragma once
class DemoSkybox : public Skybox {

View File

@@ -3,11 +3,11 @@
#include <JGL/Colors.h>
namespace Fonts {
inline int Jupiteroid = -1;
inline int ModeSeven = -1;
inline JGL::Font Jupiteroid;
inline JGL::Font ModeSeven;
inline void initFonts() {
Jupiteroid = JGL::LoadFont("assets/fonts/Jupiteroid/JupiteroidRegular.ttf");
ModeSeven = JGL::LoadFont("assets/fonts/modeseven.ttf");
Jupiteroid = JGL::Font("assets/fonts/Jupiteroid/JupiteroidRegular.ttf");
ModeSeven = JGL::Font("assets/fonts/modeseven.ttf");
}
}

View File

@@ -1,5 +1,5 @@
#pragma once
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
#include <fonts.h>
class FreeCam : public Camera {

View File

@@ -10,6 +10,7 @@ int main()
engine->window = new ReWindow::RWindow("Re3D Test Application", 1152, 864, RenderingAPI::OPENGL);
engine->world = new(World);
Engine::init();
JGL::InitTextEngine();
JGL::Update(engine->window->getSize());
Fonts::initFonts();
engine->window->setVsyncEnabled(false);

View File

@@ -43,17 +43,19 @@ Vector3 textAngle = {0,0,0};
void FreeCam::jglRenderPass() {
textAngle.x = textAngle.x - (96.f * engine->frameDelta);
using namespace JGL;
J3D::Begin();
J3D::DrawString(JGL::Colors::Red, "Text", {0, -2, 0}, textAngle, 4.f, 32, Fonts::Jupiteroid);
J3D::End();
J3D::Begin();
glDisable(GL_CULL_FACE);
J3D::DrawString(JGL::Colors::Red, "Text", {0, -2, 0}, textAngle, 4.f, 32, Fonts::Jupiteroid);
glEnable(GL_CULL_FACE);
J3D::End();
J2D::Begin();
J2D::FillRect({255,0,0,128}, {0, 72}, {100, 100});
J2D::FillCircle(JGL::Colors::White, {16, 128}, 12, 16);
J2D::DrawString(JGL::Colors::White, "Framerate: " + std::to_string((int) engine->framerate()), 0, -16, 1, 16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "Framecount: " + std::to_string(engine->frameCount), 0, -33, 1,16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "Position: " + std::to_string(position.x) + " " + std::to_string(position.y) + " " + std::to_string(position.z), 0, -50, 1,16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "ViewAngle: " + std::to_string(getAngle().x) + " " + std::to_string(getAngle().y) + " " + std::to_string(getAngle().z), 0, -67, 1,16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "Framerate: " + std::to_string((int) engine->framerate()), 0, 0, 1, 16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "Framecount: " + std::to_string(engine->frameCount), 0, 17, 1,16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "Position: " + std::to_string(position.x) + " " + std::to_string(position.y) + " " + std::to_string(position.z), 0, 33, 1,16, Fonts::Jupiteroid);
J2D::DrawString(JGL::Colors::White, "ViewAngle: " + std::to_string(getAngle().x) + " " + std::to_string(getAngle().y) + " " + std::to_string(getAngle().z), 0, 50, 1,16, Fonts::Jupiteroid);
J2D::End();
}

View File

@@ -2,7 +2,7 @@
#include <thread>
#include <JGL/JGL.h>
#include <Redacted3D/engine/engine.h>
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
#include <jlog/jlog.hpp>
using namespace J3ML;

View File

@@ -1,5 +1,5 @@
#include <Redacted3D/engine/occlusion.h>
#include <Redacted3D/types/entity/entity.h>
#include <Redacted3D/types/entity/3D/entity.h>
bool Occlusion::frustumCull(Camera* camera, Entity* entity) { return false; }

View File

@@ -1,5 +1,5 @@
#include <Redacted3D/engine/world.h>
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
int DataModel::getEntityCount() const {
@@ -14,108 +14,6 @@ int DataModel::getMobyCount() const {
return count;
}
void Entity::SetParent(Entity *parent) {
// hold a reference to this so it doesn't get collected as we're working with it
Entity *oldParent = this->parent;
if (parent == oldParent)
return;
// Don't allow for an instance to be parented to itself
if (this == parent)
throw std::runtime_error("Cannot parent a widget to itself");
if (this->IsAncestorOf(parent))
throw std::runtime_error("Cannot create circular object reference");
for (Entity *ancestor: this->GetAncestors()) {
if (oldParent && !ancestor->IsAncestorOf(parent) && parent != ancestor) {
ancestor->DescendantRemoved(this);
for (Entity *descendant: this->GetDescendants()) {
ancestor->DescendantRemoved(descendant);
}
}
}
// Remove ourselves from our parent (if we have one)
if (this->parent) {
parent->children.erase(std::remove(parent->children.begin(), parent->children.end(), this),
parent->children.end());
}
// Update our old parent to the new one
this->parent = parent;
// If our parent is set to nullptr, we can't update it's vector of children
if (!parent) { return; }
parent->children.emplace_back(this);
for (Entity* ancestor: this->GetAncestors()) {
if (!oldParent || !(oldParent->IsDescendantOf(parent) && oldParent != ancestor)) {
ancestor->DescendantAdded(this);
for (auto* descendant : this->GetDescendants()) {
ancestor->DescendantAdded(descendant);
}
}
}
}
bool Entity::IsDescendantOf(Entity *ancestor) {
if (ancestor == nullptr)
return false;
Entity *instance = this;
while (instance->GetParent()) {
instance = instance->GetParent();
if (instance == ancestor)
return true;
}
return false;
}
bool Entity::IsAncestorOf(Entity *descendant) {
if (descendant == nullptr)
return false;
Entity *instance = descendant;
while (instance->GetParent()) {
instance = instance->GetParent();
if (instance == this)
return true;
}
return false;
}
std::vector<Entity *> Entity::GetChildren() {
return this->children;
}
std::vector<Entity *> Entity::GetAncestors() {
std::vector<Entity *> ancestors;
for (Entity *ancestor = this->parent; ancestor; ancestor = ancestor->parent) {
ancestors.push_back(ancestor);
}
return ancestors;
}
std::vector<Entity *> Entity::GetDescendants() {
std::vector<Entity *> descendants;
for (auto& child: this->children) {
descendants.push_back(child);
std::vector<Entity *> recursiveDescendants = child->GetDescendants();
descendants.insert(descendants.end(), recursiveDescendants.begin(), recursiveDescendants.end());
}
return descendants;
}
Entity *Entity::Add(Entity *newChild) {
newChild->SetParent(this);
return newChild;
}
Entity *Entity::GetFamilyTreeRoot() const {
//if (JUI::Scene* scene = dynamic_cast<JUI::Scene*>(parent); scene != nullptr)
// This is retarded, Fix ASAP!
auto parent = this->GetParent();
if (parent->GetParent() == nullptr)
return parent;
return parent->GetFamilyTreeRoot();
}
void World::setAmbientLightColor(GLfloat red, GLfloat green, GLfloat blue) {
GLfloat ambient[4] = {red, green, blue, 0.0f};
globalLightColor.x = red; globalLightColor.y = green; globalLightColor.z = blue;

View File

@@ -1,5 +1,5 @@
#include <array>
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
std::array<GLfloat, 16> lookAt(const Vector3& eye, const Vector3& center, const Vector3& up) {
Vector3 f = Vector3::Normalized((center - eye));

View File

@@ -1,6 +1,6 @@
#include <Redacted3D/types/entity/entity.h>
#include <Redacted3D/types/entity/3D/entity.h>
#include <Redacted3D/engine/occlusion.h>
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
#include <Redacted3D/engine/engine.h>
#include <Redacted3D/engine/utils/instanceOf.h>
#include <jlog/jlog.hpp>
@@ -40,7 +40,7 @@ void Entity::SetPos(const Vector3 &rhs) {
Entity::Entity() {
position = {0,0,0};
ticksAlive = 0;
children = std::vector<Entity*> ();
children = std::vector<BaseEntity*> ();
parent = nullptr;
scale = {1.0f, 1.0f, 1.0f};
@@ -58,18 +58,30 @@ Vector3 Entity::getScale() const {
}
void Entity::loadTexture(const std::string& file) {
for (const auto* e : engine->world->GetChildren())
if (instanceOf(this, e))
return;
Texture texture(this, file.c_str(), true);
}
void Entity::loadMultiTexture(const std::vector<std::string>& files) {
for (const auto* e : engine->world->GetChildren())
if (instanceOf(this, e))
return;
MultiTexture texture(this, files, true);
}
void Entity::loadMotionTexture(const std::vector<std::string>& files, u16 frameDelta, bool doAnim) {
for (const auto* e : engine->world->GetChildren())
if (instanceOf(this, e))
return;
MotionTexture(this, files, frameDelta, true, doAnim);
}
void Entity::loadGeometry(const std::string& file) {
for (const auto& e : engine->world->GetChildren())
if (instanceOf(this, e))
return;
VertexArray vArray(this, file, true);
}

View File

@@ -1,4 +1,4 @@
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
#include <Redacted3D/engine/engine.h>
using namespace J3ML;

View File

@@ -1,6 +1,6 @@
#include <Redacted3D/types/entity/skybox.h>
#include <Redacted3D/types/entity/3D/skybox.h>
#include <Redacted3D/engine/engine.h>
#include <Redacted3D/types/entity/camera.h>
#include <Redacted3D/types/entity/3D/camera.h>
void Skybox::pre_render() {
if (engine->world->getActiveCamera() != nullptr)

View File

@@ -0,0 +1,108 @@
#include <Redacted3D/types/entity/baseEntity.h>
#include <stdexcept>
void BaseEntity::SetParent(BaseEntity* parent) {
// hold a reference to this so it doesn't get collected as we're working with it
BaseEntity* oldParent = this->parent;
if (parent == oldParent)
return;
// Don't allow for an instance to be parented to itself
if (this == parent)
throw std::runtime_error("Cannot parent a widget to itself");
if (this->IsAncestorOf(parent))
throw std::runtime_error("Cannot create circular object reference");
for (BaseEntity* ancestor: this->GetAncestors()) {
if (oldParent && !ancestor->IsAncestorOf(parent) && parent != ancestor) {
ancestor->DescendantRemoved(this);
for (BaseEntity* descendant: this->GetDescendants()) {
ancestor->DescendantRemoved(descendant);
}
}
}
// Remove ourselves from our parent (if we have one)
if (this->parent) {
for (auto it = parent->children.begin(); it != parent->children.end(); ++it) {
if (*it == this) {
parent->children.erase(it);
break;
}
}
}
// Update our old parent to the new one
this->parent = parent;
// If our parent is set to nullptr, we can't update it's vector of children
if (!parent) { return; }
parent->children.emplace_back(this);
for (BaseEntity* ancestor: this->GetAncestors()) {
if (!oldParent || !(oldParent->IsDescendantOf(parent) && oldParent != ancestor)) {
ancestor->DescendantAdded(this);
for (auto* descendant : this->GetDescendants()) {
ancestor->DescendantAdded(descendant);
}
}
}
}
bool BaseEntity::IsDescendantOf(BaseEntity* ancestor) {
if (ancestor == nullptr)
return false;
BaseEntity* instance = this;
while (instance->GetParent()) {
instance = instance->GetParent();
if (instance == ancestor)
return true;
}
return false;
}
bool BaseEntity::IsAncestorOf(BaseEntity* descendant) {
if (descendant == nullptr)
return false;
BaseEntity* instance = descendant;
while (instance->GetParent()) {
instance = instance->GetParent();
if (instance == this)
return true;
}
return false;
}
std::vector<BaseEntity* > BaseEntity::GetChildren() {
return this->children;
}
std::vector<BaseEntity* > BaseEntity::GetAncestors() {
std::vector<BaseEntity* > ancestors;
for (BaseEntity* ancestor = this->parent; ancestor; ancestor = ancestor->parent) {
ancestors.push_back(ancestor);
}
return ancestors;
}
std::vector<BaseEntity* > BaseEntity::GetDescendants() {
std::vector<BaseEntity* > descendants;
for (auto& child: this->children) {
descendants.push_back(child);
std::vector<BaseEntity* > recursiveDescendants = child->GetDescendants();
descendants.insert(descendants.end(), recursiveDescendants.begin(), recursiveDescendants.end());
}
return descendants;
}
BaseEntity* BaseEntity::Add(BaseEntity* newChild) {
newChild->SetParent(this);
return newChild;
}
BaseEntity* BaseEntity::GetFamilyTreeRoot() const {
//if (JUI::Scene* scene = dynamic_cast<JUI::Scene*>(parent); scene != nullptr)
// This is retarded, Fix ASAP!
auto parent = this->GetParent();
if (parent->GetParent() == nullptr)
return parent;
return parent->GetFamilyTreeRoot();
}

View File

@@ -1,7 +1,7 @@
#include <fstream>
#include <Redacted3D/types/track.h>
#include <Redacted3D/engine/engine.h>
#include <Redacted3D/types/entity/moby.h>
#include <Redacted3D/types/entity/3D/moby.h>
#include <jlog/jlog.hpp>
Track::Track(const std::string &file, Moby* moby) {