Improved tree pannel

This commit is contained in:
Arnau Alier Torres 2025-05-10 20:49:17 +02:00
parent b3884b6bd5
commit c5ca30dcfb
22 changed files with 319 additions and 83 deletions

View File

@ -0,0 +1,21 @@
#pragma once
#include "DeerRender/Render/FrameBuffer.h"
#include <cstring>
#include <stdint.h>
namespace Deer {
// TODO: Add safety
namespace FrameBufferManager {
uint16_t createRGBA8FrameBuffer(std::string& name, int, int);
void resizeFrameBuffer(uint16_t frameBufferId, int, int);
int getFrameBufferWidth(uint16_t frameBufferId);
int getFrameBufferHeight(uint16_t frameBufferId);
const std::string& getFrameBufferName(uint16_t);
uint16_t getFrameBufferId(std::string& name);
void unloadAllFrameBuffer();
}
}

View File

@ -38,7 +38,7 @@ namespace Deer {
virtual int getTextureBufferPixel(int id, unsigned int x, unsigned int y) = 0;
static Ref<FrameBuffer> create(const FrameBufferSpecification& spec);
static FrameBuffer* create(const FrameBufferSpecification& spec);
};
}

View File

@ -18,6 +18,8 @@
#ifdef DEER_RENDER
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/FrameBuffer.h"
#endif
namespace Deer {
@ -26,6 +28,8 @@ namespace Deer {
VoxelWorld::clear();
#ifdef DEER_RENDER
MeshManager::unloadAllModels();
ShaderManager::unloadAllShaders();
FrameBufferManager::unloadAllFrameBuffer();
#endif
}

View File

@ -0,0 +1,76 @@
#include "DeerRender/FrameBuffer.h"
#include <unordered_map>
#define FRAME_BUFFER_MAX_COUNT 256
namespace Deer {
namespace FrameBufferManager {
struct FrameBufferContainer {
FrameBuffer* frameBuffer_data = nullptr;
std::string frameBuffer_name;
};
uint16_t maxFrameBufferId = 1;
FrameBufferContainer frameBuffers[FRAME_BUFFER_MAX_COUNT]{};
std::unordered_map<std::string, uint16_t> frameBuffers_name_id_map;
}
uint16_t FrameBufferManager::createRGBA8FrameBuffer(std::string& name, int x, int y) {
FrameBufferSpecification specs(
x, y,
{TextureBufferType::RGBA8}, 4,
false);
FrameBuffer* frameBuffer = FrameBuffer::create(specs);
uint16_t frameBufferId = maxFrameBufferId;
maxFrameBufferId++;
frameBuffers[frameBufferId].frameBuffer_data = frameBuffer;
frameBuffers[frameBufferId].frameBuffer_name = name;
frameBuffers_name_id_map[name] = frameBufferId;
return frameBufferId;
}
void FrameBufferManager::resizeFrameBuffer(uint16_t frameBufferId, int x, int y) {
FrameBuffer* frameBuffer = frameBuffers[frameBufferId].frameBuffer_data;
frameBuffer->resize(x, y);
}
int FrameBufferManager::getFrameBufferWidth(uint16_t frameBufferId) {
FrameBuffer* frameBuffer = frameBuffers[frameBufferId].frameBuffer_data;
return frameBuffer->getSpecification().width;
}
int FrameBufferManager::getFrameBufferHeight(uint16_t frameBufferId) {
FrameBuffer* frameBuffer = frameBuffers[frameBufferId].frameBuffer_data;
return frameBuffer->getSpecification().height;
}
const std::string& FrameBufferManager::getFrameBufferName(uint16_t id) {
DEER_CORE_ASSERT(id >= 0 && id < maxFrameBufferId, "Invalid frame buffer id {0}", id);
return frameBuffers[id].frameBuffer_name;
}
uint16_t FrameBufferManager::getFrameBufferId(std::string& name) {
return frameBuffers_name_id_map[name];
}
void FrameBufferManager::unloadAllFrameBuffer() {
for (int x = 1; x < maxFrameBufferId; x++) {
delete frameBuffers[x].frameBuffer_data;
frameBuffers[x].frameBuffer_data = nullptr;
}
frameBuffers_name_id_map.clear();
maxFrameBufferId = 1;
frameBuffers[0].frameBuffer_data = nullptr;
frameBuffers[0].frameBuffer_name = "NULL";
frameBuffers_name_id_map["NULL"] = 0;
}
}

View File

@ -5,8 +5,8 @@
#include "glad/glad.h"
namespace Deer {
Ref<FrameBuffer> FrameBuffer::create(const FrameBufferSpecification& spec) {
return Ref<FrameBuffer>(new OpenGLFrameBuffer(spec));
FrameBuffer* FrameBuffer::create(const FrameBufferSpecification& spec) {
return new OpenGLFrameBuffer(spec);
}
OpenGLFrameBuffer::OpenGLFrameBuffer(const FrameBufferSpecification& frameBufferSpecification)

View File

@ -11,7 +11,7 @@ namespace Deer {
GamePanel::GamePanel() {
FrameBufferSpecification fbSpecs = FrameBufferSpecification(
100, 100, {TextureBufferType::RGBA8}, 1, false);
m_frameBuffer = FrameBuffer::create(fbSpecs);
m_frameBuffer = Scope<FrameBuffer>(FrameBuffer::create(fbSpecs));
}
void GamePanel::onImGui() {

View File

@ -15,7 +15,7 @@ namespace Deer {
void onImGui() override;
private:
Ref<FrameBuffer> m_frameBuffer;
Scope<FrameBuffer> m_frameBuffer;
glm::vec2 m_lastWindowSize;
};

View File

@ -51,10 +51,10 @@ namespace Deer {
processMovment();
if (!m_frameBuffer) {
m_frameBuffer = FrameBuffer::create(FrameBufferSpecification(
m_frameBuffer = Scope<FrameBuffer>(FrameBuffer::create(FrameBufferSpecification(
100, 100,
{TextureBufferType::RGBA8, TextureBufferType::RED_INTEGER}, 4,
false));
false)));
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));

View File

@ -6,4 +6,5 @@
#include "DeerStudio/EditorEngine/API/Menu.h"
#include "DeerStudio/EditorEngine/API/Resource.h"
#include "DeerStudio/EditorEngine/API/UI.h"
#include "DeerStudio/EditorEngine/API/Math.h"
#include "DeerStudio/EditorEngine/API/Math.h"
#include "DeerStudio/EditorEngine/API/FrameBuffer.h"

View File

@ -1,4 +1,6 @@
#pragma once
#include "DeerStudio/EditorEngine/API/GenericRefStructs.h"
#include <stdint.h>
#include <string>
#include "glm/glm.hpp"
@ -25,9 +27,8 @@ namespace Deer {
//
// bool ==
//}
struct EntityStruct {
EntityStruct(uint16_t entId = 0) : entityId(entId) { }
uint16_t entityId;
struct EntityStruct : EntityRefStruct {
EntityStruct(uint16_t entId = 0) { entityId = entId; }
std::string getName();
void setName(std::string&);
@ -38,36 +39,33 @@ namespace Deer {
bool isRoot();
void destroy();
EntityStruct createChild(std::string&);
EntityRefStruct createChild(std::string&);
void setParent(EntityStruct parent);
EntityStruct getParent();
void setParent(EntityRefStruct parent);
EntityRefStruct getParent();
bool isDescendantOf(EntityStruct parent);
bool opEquals(const EntityStruct& other);
bool isDescendantOf(EntityRefStruct parent);
bool opEquals(const EntityRefStruct& other);
//COMPONENTS
EntityStruct getMeshComponent();
EntityRefStruct getMeshComponent();
bool hasMeshComponent();
void removeMeshComponent();
EntityStruct getShaderComponent();
EntityRefStruct getShaderComponent();
bool hasShaderComponent();
void removeShaderComponent();
// This is an internal function to avoid undefined behaviour from angelscript and avoid problems
bool assertEntity(const char* funcName);
// This function can be adapted to get a specific transform since the data is the same
EntityStruct getSelf();
EntityRefStruct getSelf();
};
struct EntityChildArrayStruct : EntityStruct{
struct EntityChildArrayStruct : EntityRefStruct {
int getChildCount();
EntityStruct getChild(int);
EntityRefStruct getChild(int);
};
struct TransformComponentStruct : EntityStruct {
struct TransformComponentStruct : EntityRefStruct {
glm::vec3 getPosition();
glm::vec3 getScale();
glm::vec3 getRotation();
@ -77,7 +75,7 @@ namespace Deer {
void setRotation(glm::vec3);
};
struct MeshComponentStruct : EntityStruct {
struct MeshComponentStruct : EntityRefStruct {
bool isActive();
void setActive(bool);
@ -90,7 +88,7 @@ namespace Deer {
bool assertMeshComponent(const char* funcName);
};
struct ShaderComponentStruct : EntityStruct {
struct ShaderComponentStruct : EntityRefStruct {
bool hasShader();
void clear();
@ -100,7 +98,7 @@ namespace Deer {
bool assertShaderComponent(const char* funcName);
};
EntityStruct getRoot();
EntityRefStruct getRoot();
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);

View File

@ -0,0 +1,19 @@
#pragma once
#include "GenericRefStructs.h"
#include <string>
namespace Deer {
namespace EditorEngine {
struct EnvironmentStruct : EnvironmentRefStruct {
void render(EntityRefStruct cameraEntity, FrameBufferRefStruct);
EntityRefStruct getRootEntity();
EntityRefStruct getEntity(int);
};
EnvironmentRefStruct getMainEnvironment();
EnvironmentRefStruct createEnvironment(std::string&);
EnvironmentRefStruct getEnvironment(std::string&);
}
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <string>
namespace Deer {
namespace EditorEngine {
struct FrameBufferStruct : FrameBufferRefStruct{
FrameBufferStruct(uint16_t _id) { frameBufferId = _id; }
int getWidth();
int getHeight();
void resize(int, int);
std::string getName();
};
FrameBufferStruct createRGBA8FrameBuffer(std::string& name, int, int);
FrameBufferStruct getFrameBuffer(std::string& name);
void registerFrameBufferStructs();
void registerFrameBufferFunctions();
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
namespace Deer {
namespace EditorEngine {
struct EntityRefStruct {
uint16_t entityId;
uint16_t environmentId;
// This is an internal function to avoid undefined behaviour from angelscript and avoid problems
bool assertEntity(const char* funcName);
};
struct EnvironmentRefStruct {
uint16_t environmentId;
};
struct FrameBufferRefStruct {
uint16_t frameBufferId;
};
}
}

View File

@ -15,9 +15,7 @@
namespace Deer {
namespace EditorEngine {
EntityStruct activeEntity;
EntityStruct getRoot() {
EntityRefStruct getRoot() {
return EntityStruct(0);
}
@ -29,7 +27,7 @@ namespace Deer {
return entityId;
}
bool EntityStruct::assertEntity(const char* funcName) {
bool EntityRefStruct::assertEntity(const char* funcName) {
if (!Scene::environment.entityExists(entityId)) {
DEER_UI_ENGINE_ERROR("Error, invalid entity calling {0}, entityId : {1}", funcName, entityId);
if (currentDockPanelExecution)
@ -76,7 +74,7 @@ namespace Deer {
.entityExists(entityId);
}
void EntityStruct::setParent(EntityStruct parent_struct) {
void EntityStruct::setParent(EntityRefStruct parent_struct) {
ASSERT_ENTITY("setParent()", return);
Entity& parent = GET_ENTITY(parent_struct.entityId);
@ -85,7 +83,7 @@ namespace Deer {
.setParent(parent);
}
EntityStruct EntityStruct::getParent() {
EntityRefStruct EntityStruct::getParent() {
ASSERT_ENTITY("getParent()", return *this);
Entity& self = GET_ENTITY(entityId);
@ -95,7 +93,7 @@ namespace Deer {
return EntityStruct(self.getParentId());
}
bool EntityStruct::isDescendantOf(EntityStruct parent_struct) {
bool EntityStruct::isDescendantOf(EntityRefStruct parent_struct) {
ASSERT_ENTITY("isDescendantOf()", return false);
Entity& parent = GET_ENTITY(parent_struct.entityId);
@ -104,13 +102,13 @@ namespace Deer {
.isDescendantOf(parent);
}
bool EntityStruct::opEquals(const EntityStruct& other) {
bool EntityStruct::opEquals(const EntityRefStruct& other) {
ASSERT_ENTITY("opEquals()", return false);
return entityId == other.entityId;
}
EntityStruct EntityStruct::getSelf() {
EntityRefStruct EntityStruct::getSelf() {
ASSERT_ENTITY("getSelf()", return *this);
return *this;
@ -179,7 +177,7 @@ namespace Deer {
return true;
}
EntityStruct EntityChildArrayStruct::getChild(int i) {
EntityRefStruct EntityChildArrayStruct::getChild(int i) {
ASSERT_ENTITY("getChild()", return *this);
RelationshipComponent& rc = GET_ENTITY(entityId)
@ -196,7 +194,7 @@ namespace Deer {
return EntityStruct(rc.getChildrenId(i));
}
EntityStruct EntityStruct::createChild(std::string& name) {
EntityRefStruct EntityStruct::createChild(std::string& name) {
ASSERT_ENTITY("createChild()", return *this);
Entity& me = GET_ENTITY(entityId);
@ -209,7 +207,7 @@ namespace Deer {
return EntityStruct(newEnt.getId());
}
EntityStruct EntityStruct::getMeshComponent() {
EntityRefStruct EntityStruct::getMeshComponent() {
ASSERT_ENTITY("getMeshComponent()", return *this);
Entity& self = GET_ENTITY(entityId);
@ -239,7 +237,7 @@ namespace Deer {
}
}
EntityStruct EntityStruct::getShaderComponent() {
EntityRefStruct EntityStruct::getShaderComponent() {
ASSERT_ENTITY("getShaderComponent()", return *this);
Entity& self = GET_ENTITY(entityId);

View File

@ -13,26 +13,20 @@ namespace Deer {
void registerShaderComponentFunctions();
void registerEntityStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityRefStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityRefStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour(
"Entity", asBEHAVE_CONSTRUCT, "void f(int)",
asFunctionPtr(constructEntityStruct),
asCALL_CDECL_OBJLAST
));
AS_CHECK(scriptEngine->RegisterObjectType("EntityChilds", sizeof(EntityRefStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityRefStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("EntityChilds", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("TransformComponent", sizeof(EntityRefStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityRefStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("TransformComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityRefStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityRefStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("ShaderComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("ShaderComponent", sizeof(EntityRefStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityRefStruct>() | asOBJ_APP_CLASS_ALLINTS));
}
void registerEntityFunctions() {

View File

@ -0,0 +1,32 @@
#include "DeerStudio/EditorEngine/API/FrameBuffer.h"
#include "DeerRender/FrameBuffer.h"
namespace Deer {
namespace EditorEngine {
int FrameBufferStruct::getWidth() {
return FrameBufferManager::getFrameBufferWidth(frameBufferId);
}
int FrameBufferStruct::getHeight() {
return FrameBufferManager::getFrameBufferWidth(frameBufferId);
}
void FrameBufferStruct::resize(int x, int y) {
FrameBufferManager::resizeFrameBuffer(frameBufferId, x, y);
}
std::string FrameBufferStruct::getName() {
return FrameBufferManager::getFrameBufferName(frameBufferId);
}
FrameBufferStruct createRGBA8FrameBuffer(std::string& name, int x, int y) {
uint16_t id = FrameBufferManager::createRGBA8FrameBuffer(name, x, y);
return FrameBufferStruct(id);
}
FrameBufferStruct getFrameBuffer(std::string& name) {
return FrameBufferManager::getFrameBufferId(name);
}
}
}

View File

@ -0,0 +1,48 @@
#include "DeerStudio/EditorEngine/API/FrameBuffer.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine.h"
#include "angelscript.h"
namespace Deer {
namespace EditorEngine {
void registerFrameBufferStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("FrameBuffer", sizeof(FrameBufferStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<FrameBufferStruct>() | asOBJ_APP_CLASS_ALLINTS));
}
void registerFrameBufferFunctions() {
AS_CHECK(scriptEngine->RegisterObjectMethod(
"FrameBuffer", "int get_width() const property",
asMETHOD(FrameBufferStruct, getWidth), asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"FrameBuffer", "int get_height() const property",
asMETHOD(FrameBufferStruct, getHeight), asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"FrameBuffer", "void resize(int, int)",
asMETHOD(FrameBufferStruct, resize), asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"FrameBuffer", "string get_name() const property",
asMETHOD(FrameBufferStruct, getName), asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"FrameBuffer createRGBA8FrameBuffer(const string&in, int, int)",
asFUNCTION(createRGBA8FrameBuffer),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"FrameBuffer getFrameBuffer(const string&in)",
asFUNCTION(getFrameBuffer),
asCALL_CDECL
));
}
}
}

View File

@ -9,6 +9,7 @@ namespace Deer {
registerEntityFunctions();
registerMathFunctions();
registerUIFunctions();
registerFrameBufferFunctions();
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void setupAutomaticColumns(int)",

View File

@ -24,6 +24,7 @@ namespace Deer {
registerResourceTypeEnum();
registerEntityStructs();
registerMathStructs();
registerFrameBufferStructs();
}
}
}

View File

@ -1 +1 @@
Entity activeEntity(0);
Entity activeEntity = getRoot();

View File

@ -2,11 +2,8 @@ class TreePannel : DockPanel {
void onRender() {
Entity root = getRoot();
contextMenuPopup("Window popup", any(root), ReciverFunc(this.entityContextMenu));
bool opened = treeNode(root.name, false, any(root), ReciverFunc(this.renderNode));
if (!opened) {
contextItemPopup("POP_ENTITY_" + root.id, any(root), ReciverFunc(this.entityContextMenu));
}
renderNode(any(root));
modalPopup("Rename entity", renameEntity);
}
@ -28,7 +25,8 @@ class TreePannel : DockPanel {
Entity entity;
data.retrieve(entity);
entityInteraction(entity);
if (!entity.isRoot)
entityInteraction(entity);
// Maybe we deleted the entity in the context menu
if (!entity.exists)

View File

@ -15,8 +15,8 @@ Collapsed=0
DockId=0x00000004,1
[Window][Game Window]
Pos=258,24
Size=499,490
Pos=365,24
Size=504,503
Collapsed=0
DockId=0x00000006,0
@ -27,14 +27,14 @@ Collapsed=0
DockId=0x00000001,0
[Window][Terrain Editor]
Pos=759,24
Size=521,490
Pos=871,24
Size=409,503
Collapsed=0
DockId=0x00000004,0
[Window][Viewport]
Pos=258,24
Size=499,490
Pos=365,24
Size=504,503
Collapsed=0
DockId=0x00000006,1
@ -57,14 +57,14 @@ Collapsed=0
DockId=0x00000008,1
[Window][MeshExplorer]
Pos=0,516
Size=1280,204
Pos=0,529
Size=1280,191
Collapsed=0
DockId=0x00000008,0
[Window][TreePannel]
Pos=0,24
Size=256,490
Size=363,503
Collapsed=0
DockId=0x00000005,0
@ -79,8 +79,8 @@ Size=351,75
Collapsed=0
[Window][PropertiesPannel]
Pos=759,24
Size=521,490
Pos=871,24
Size=409,503
Collapsed=0
DockId=0x00000004,1
@ -91,19 +91,19 @@ Collapsed=0
DockId=0x00000004,1
[Window][ShaderExplorer]
Pos=0,516
Size=1280,204
Pos=0,529
Size=1280,191
Collapsed=0
DockId=0x00000008,1
[Docking][Data]
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,490 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,503 Split=Y
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=757,338 Split=X Selected=0x13926F0B
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=256,446 Selected=0xE45B9F93
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=499,446 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=521,338 Selected=0xA35A27E3
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=869,338 Split=X Selected=0x13926F0B
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=363,446 Selected=0xE45B9F93
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=504,446 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=409,338 Selected=0x2A2C795E
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702
DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,204 Selected=0xD962995A
DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,191 Selected=0xD962995A