Refactor to make Scene unique and also Voxel World

This commit is contained in:
Arnau Alier Torres 2025-05-07 00:26:34 +02:00
parent 5d7025e141
commit d29fabffb9
113 changed files with 2407 additions and 2460 deletions

View File

@ -5,17 +5,18 @@
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Path.h"
#include "Deer/Memory.h"
// File to manage Assets
// TODO: Delete Assets and set a custom method of loading
namespace Deer {
template <typename T>
class Asset {
struct Asset {
public:
Asset() : m_assetID(0), m_assetLocation("null") {}
Asset() : id(0), name("null") {}
Asset(uint32_t id, const std::filesystem::path& assetLocation)
: m_assetID(id), m_assetLocation(assetLocation) {
: id(id), name(assetLocation) {
try {
uint32_t size;
uint8_t* data = DataStore::readFile(assetLocation, &size);
@ -30,31 +31,32 @@ namespace Deer {
}
}
inline uint32_t getAssetID() const { return m_assetID; }
inline Path& getAssetLocation() { return m_assetLocation; }
Ref<T> value;
inline uint32_t getAssetID() const { return id; }
inline Path& getAssetLocation() { return name; }
inline T& getValue() { return value; }
private:
uint32_t m_assetID;
Path m_assetLocation;
Path name;
uint32_t id;
Scope<T> value;
};
template <>
class Asset<void> {
public:
Asset() : m_assetID(0), m_assetLocation("null") {}
Asset() : id(0), name("null") {}
Asset(uint32_t id, const std::filesystem::path& assetLocation)
: m_assetID(id), m_assetLocation(assetLocation) {}
: id(id), name(assetLocation) {}
inline uint32_t getAssetID() const { return m_assetID; }
inline Path& getAssetLocation() { return m_assetLocation; }
inline uint32_t getAssetID() const { return id; }
inline Path& getAssetLocation() { return name; }
Ref<void> value;
private:
uint32_t m_assetID;
Path m_assetLocation;
uint32_t id;
Path name;
};
namespace AssetManager {

View File

@ -35,7 +35,7 @@ namespace Deer {
ComponentScriptInstance() = default;
~ComponentScriptInstance();
void updateInternalVars();
void tick();
void start();
asIScriptObject* m_object;

View File

@ -137,7 +137,7 @@ namespace Deer {
Entity& getParent() const;
inline uint16_t getParentId() const { return m_parentID; }
// TODO, enable transfer entitys from difrent enviroments
// TODO, enable transfer entitys from difrent environments
void setParent(Entity& parent);
bool isDescendantOf(Entity& parent) const;
@ -147,7 +147,7 @@ namespace Deer {
glm::mat4 getWorldMatrix();
glm::mat4 getRelativeMatrix();
void updateInternalVars();
void tick();
inline bool isValid() const { return m_exists; }

View File

@ -9,63 +9,41 @@
#include <string>
#include <vector>
#include <array>
namespace Deer {
class VoxelWorld;
class VoxelWorldProps;
class Environment;
class GizmoRenderer;
// A scene is a 3d simulation with its environment and voxel world in case
// of initialized, here things can be simulated
class Scene {
public:
Scene();
~Scene();
Scene(const Scene&) = delete;
Scene operator=(Scene&) = delete;
void createVoxelWorld(const VoxelWorldProps&);
void deleteVoxelWorld();
namespace Scene {
// Resets all scene to 0 but conserving the memory making it much faster
// than creating another instance
void clear();
// This is the cycle to execution
void beginExecution();
void updateInternalVars();
void tick();
void endExecution();
inline Environment& getMainEnviroment() { return *m_enviroment; }
inline VoxelWorld& getVoxelWorld() { return *m_voxelWorld; }
inline bool isVoxelWorldInitialized() {
return m_voxelWorld != nullptr;
}
inline bool getExecutingState() { return m_isExecuting; }
bool getExecutingState();
#ifdef DEER_RENDER
public:
// This function renders with the default camera in the environment
void render();
void render(SceneCamera);
inline GizmoRenderer& getMainGizmoRenderer() { return m_gizmoRenderer; }
private:
GizmoRenderer m_gizmoRenderer;
extern GizmoRenderer gizmoRenderer;
#endif
private:
Scope<Environment> m_enviroment;
Scope<VoxelWorld> m_voxelWorld;
bool m_isExecuting = false;
};
extern Environment environment;
}
// Namespace to manage scenes in memory
namespace DataStore {
void loadScene(Scene& scene, const Path& name);
void exportScene(const Scene& scene, const Path& name);
void loadScene(const Path& name);
void exportScene(const Path& name);
void exportRuntimeScene(const Scene& scene);
void importRuntimeScene(Scene& scene);
void exportRuntimeScene();
void importRuntimeScene();
} // namespace DataStore
} // namespace Deer

View File

@ -14,7 +14,6 @@ class asIScriptFunction;
class asITypeInfo;
namespace Deer {
class Scene;
class Entity;
class ComponentScript;
@ -24,12 +23,11 @@ namespace Deer {
extern asIScriptContext* m_context;
extern bool m_isCompilationValid;
extern ComponentScriptMap m_componentScripts;
extern Scene* m_scene;
void compileScriptEngine(const std::filesystem::path& scriptPath);
void shutdownScriptEngine();
void beginExecutionContext(Scene* executingScene);
void beginExecutionContext();
void endExecutionContext();
inline asIScriptContext* getExecutionContext() { return m_context; }

View File

@ -143,56 +143,43 @@ namespace Deer {
};
// Class to manage the voxels
class VoxelWorld {
public:
// Warning: Do not change the voxel data content since that could make
// undefined behaviour
VoxelWorld(const VoxelWorldProps &props);
~VoxelWorld();
// This class can not be copyed
// TODO: Make a function to duplicate a voxel World
VoxelWorld(const VoxelWorld &) = delete;
VoxelWorld &operator=(VoxelWorld &) = delete;
namespace VoxelWorld {
void initialize(const VoxelWorldProps&);
void clear();
// Returns the voxel in a voxel coordinates
Voxel readVoxel(VoxelCordinates);
// Sets the voxel in the coordinates to the value
void setVoxel(VoxelCordinates, Voxel value);
// Fills a space with the voxel value inside the 2 coordinates
// Note that you don't have to give then ordeered by min and max
void fillVoxels(VoxelCordinates, VoxelCordinates, Voxel value);
// Remplaces the ref voxel with the value of a space inside the 2
// coordinates
// Remplaces the ref voxel with the value of a space inside the 2 coordinates
// Note that you don't have to give then ordeered by min and max
void remplaceVoxels(VoxelCordinates, VoxelCordinates, Voxel ref,
Voxel value);
void remplaceVoxels(VoxelCordinates, VoxelCordinates, Voxel ref, Voxel value);
// Returns the layer data of a woorld coordinates
// Note out of bounds will return a default Layer Voxel
LayerVoxel readLayerVoxel(int x, int z);
// Calculates the max height of a layer in a space
// Note out of bounds will return a 0 of height
// Tip: this will calculate, you should use the cached height in a layer
// voxel
// Tip: this will calculate, you should use the cached height in a layer voxel
uint16_t calculateLayerVoxelHeight(int x, int z);
// Raycast a ray from a source and dir
VoxelRayResult rayCast(glm::vec3 position, glm::vec3 dir,
float maxDistance = 10.0f);
// Raycast a ray from a source and dir ignoring if the ray stats inside
// a voxel
float maxDistance = 10.0f);
// Raycast a ray from a source and dir ignoring if the ray stats inside a voxel
VoxelRayResult rayCast_editor(glm::vec3 position, glm::vec3 dir,
float maxDistance = 10.0f);
float maxDistance = 10.0f);
bool isInitialized();
// Returns the voxel world props used in the voxel world
// Note that you can't change the world size unless you create a new
// Voxel World
inline const VoxelWorldProps &getVoxelWorldProps() const {
return m_worldProps;
}
#ifdef DEER_RENDER
public:
// Note that you can't change the world size unless you create a new Voxel World
const VoxelWorldProps& getWorldProps();
#ifdef DEER_RENDER
// Renders the current voxel world with a specified scene camera
void render(const SceneCamera &);
// Generates the next chunk mesh
@ -202,9 +189,6 @@ namespace Deer {
VoxelLight readLight(VoxelCordinates);
VoxelLight &modLight(VoxelCordinates);
private:
Scope<VoxelWorldRenderData> m_renderData;
// Chunk vertex creation
void genSolidVoxel(ChunkID chunkID, ChunkVoxelID chunkVoxelID);
@ -215,16 +199,11 @@ namespace Deer {
void bakeVoxelLightFromPoint(VoxelCordinates);
void bakeAmbientLight(int minX, int maxX, int minZ, int maxZ);
void bakeAmbientLightFromPoint(int x, int z);
void resolveNextAmbientLightPropagation();
void resolveNextVoxelLightPropagation();
#endif
private:
VoxelWorldProps m_worldProps;
Scope<Chunk[]> m_chunks;
Scope<Layer[]> m_layers;
#endif
LayerVoxel &modLayerVoxel(int x, int z);
};
}
} // namespace Deer

View File

@ -11,7 +11,7 @@ namespace Deer {
void Entity::setParent(Entity& parent) {
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
DEER_CORE_ASSERT(parent.m_environment == m_environment,
"Can not set parent from diferent enviroments");
"Can not set parent from diferent environments");
DEER_CORE_ASSERT(parent.isValid(), "Parent is not valid");
if (parent.getId() == getId()) return;

View File

@ -9,55 +9,62 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/Layer.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "Deer/Enviroment.h"
#include "Deer/Scene/SceneData.h"
#ifdef DEER_RENDER
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
#endif
namespace Deer {
Scene::Scene() {
m_enviroment = MakeScope<Environment>();
m_voxelWorld = nullptr;
void Scene::clear() {
environment.clear();
VoxelWorld::clear();
}
bool Scene::getExecutingState() {
return isExecuting;
}
void Scene::beginExecution() {
DEER_CORE_ASSERT(!m_isExecuting, "Deer scene is already executing");
m_isExecuting = true;
DEER_CORE_ASSERT(!isExecuting, "Deer scene is already executing");
isExecuting = true;
DEER_CORE_INFO("Executing Scene...");
ScriptEngine::beginExecutionContext(this);
ScriptEngine::beginExecutionContext();
// Instantiate all the scripts
auto view =
m_enviroment->m_registry.view<ScriptComponent, TagComponent>();
auto view = environment.m_registry.view<ScriptComponent, TagComponent>();
for (auto& entID : view) {
auto& tagComponent = view.get<TagComponent>(entID);
auto& componentScript = view.get<ScriptComponent>(entID);
Entity& entity = m_enviroment->getEntity(tagComponent.entityUID);
componentScript.roeInstance =
ScriptEngine::createComponentScriptInstance(
componentScript.scriptID, entity);
Entity& entity = environment.getEntity(tagComponent.entityUID);
componentScript.roeInstance =
ScriptEngine::createComponentScriptInstance(componentScript.scriptID, entity);
componentScript.roeInstance->start();
}
}
void Scene::updateInternalVars() {
void Scene::tick() {
// Update all scripts
auto view = m_enviroment->m_registry.view<ScriptComponent>();
auto view = environment.m_registry.view<ScriptComponent>();
for (auto& entID : view) {
auto& componentScript = view.get<ScriptComponent>(entID);
componentScript.roeInstance->updateInternalVars();
componentScript.roeInstance->tick();
}
}
void Scene::endExecution() {
DEER_CORE_ASSERT(m_isExecuting, "Deer scene is not executing");
m_isExecuting = false;
DEER_CORE_ASSERT(isExecuting, "Deer scene is not executing");
isExecuting = false;
// Deatach all scripts
auto view = m_enviroment->m_registry.view<ScriptComponent>();
auto view = environment.m_registry.view<ScriptComponent>();
for (auto& entID : view) {
auto& componentScript = view.get<ScriptComponent>(entID);
componentScript.roeInstance.reset();
@ -66,14 +73,4 @@ namespace Deer {
DEER_CORE_INFO("Stoping Scene...");
}
void Scene::createVoxelWorld(const VoxelWorldProps& props) {
m_voxelWorld = MakeScope<VoxelWorld>(props);
}
void Scene::deleteVoxelWorld() { m_voxelWorld.reset(); }
void Scene::clear() {
m_enviroment->clear();
m_voxelWorld.reset();
}
} // namespace Deer

View File

@ -0,0 +1,18 @@
#include "Deer/Memory.h"
#include "Deer/Enviroment.h"
#ifdef DEER_RENDER
#include "DeerRender/GizmoRenderer.h"
#endif
namespace Deer {
namespace Scene {
Environment environment;
bool isExecuting = false;
#ifdef DEER_RENDER
GizmoRenderer gizmoRenderer;
#endif
}
} // namespace Deer

View File

@ -0,0 +1,20 @@
#pragma once
#include "Deer/Memory.h"
#ifdef DEER_RENDER
#include "DeerRender/GizmoRenderer.h"
#endif
namespace Deer {
class Environment;
namespace Scene {
extern Environment environment;
extern bool isExecuting;
#ifdef DEER_RENDER
extern GizmoRenderer gizmoRenderer;
#endif
}
} // namespace Deer

View File

@ -7,8 +7,10 @@
#include "cereal/archives/json.hpp"
#include "cereal/archives/portable_binary.hpp"
#include "Deer/Scene.h"
namespace Deer {
void DataStore::loadScene(Scene& scene, const Path& name) {
void DataStore::loadScene(const Path& name) {
Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
@ -20,40 +22,41 @@ namespace Deer {
{
cereal::JSONInputArchive archive(stream);
archive(cereal::make_nvp("scene", scene));
archive(cereal::make_nvp("environment", Scene::environment));
}
delete[] data;
}
void DataStore::exportScene(const Scene& scene, const Path& name) {
void DataStore::exportScene(const Path& name) {
Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
std::stringstream output;
{
cereal::JSONOutputArchive archive(output);
archive(cereal::make_nvp("scene", scene));
archive(cereal::make_nvp("environment", Scene::environment));
}
std::string_view view = output.view();
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
void DataStore::exportRuntimeScene(const Scene& scene) {
void DataStore::exportRuntimeScene() {
Path realName;
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");
std::stringstream output;
{
cereal::PortableBinaryOutputArchive archive(output);
archive(cereal::make_nvp("scene", scene));
archive(cereal::make_nvp("environment", Scene::environment));
}
std::string_view view = output.view();
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
void DataStore::importRuntimeScene(Scene& scene) {
void DataStore::importRuntimeScene() {
Path realName;
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");
@ -65,7 +68,7 @@ namespace Deer {
{
cereal::PortableBinaryInputArchive archive(stream);
archive(cereal::make_nvp("scene", scene));
archive(cereal::make_nvp("environment", Scene::environment));
}
delete[] data;

View File

@ -1,10 +0,0 @@
#pragma once
#include "Deer/Scene.h"
namespace Deer {
template <class Archive>
void serialize(Archive& archive, Scene& m_scene) {
archive(
cereal::make_nvp("main_environment", m_scene.getMainEnviroment()));
}
} // namespace Deer

View File

@ -1,6 +1,5 @@
#pragma once
#include "Deer/Asset.h"
#include "cereal/cereal.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
@ -15,7 +14,6 @@
// SCENE SPECIFIC
#include "Deer/Scene/Serialization/EntitySerialization.h"
#include "Deer/Scene/Serialization/EnvironmentSerialization.h"
#include "Deer/Scene/Serialization/SceneSerialization.h"
// COMPONENTS SPECIFIC
#include "Deer/Scene/Serialization/Components/RelationshipComponentSerialization.h"

View File

@ -17,7 +17,7 @@ namespace Deer {
m_object->Release();
}
void ComponentScriptInstance::updateInternalVars() {
void ComponentScriptInstance::tick() {
if (!m_updateFunction)
return;

View File

@ -18,7 +18,6 @@ namespace Deer {
namespace ScriptEngine {
asIScriptEngine* m_scriptEngine;
asIScriptModule* m_scriptModule;
Scene* m_scene;
bool m_isCompilationValid = false;
@ -32,8 +31,7 @@ namespace Deer {
void ScriptEngine::shutdownScriptEngine() { m_componentScripts.clear(); }
void ScriptEngine::beginExecutionContext(Scene* executingScene) {
m_scene = executingScene;
void ScriptEngine::beginExecutionContext() {
m_context = m_scriptEngine->CreateContext();
}

View File

@ -33,7 +33,7 @@ namespace Deer {
return glm::vec3();
}
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
return entt.getComponent<TransformComponent>().position;
@ -45,7 +45,7 @@ namespace Deer {
return;
}
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
entt.getComponent<TransformComponent>().position = position;
@ -57,7 +57,7 @@ namespace Deer {
return glm::vec3();
}
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
return entt.getComponent<TransformComponent>().scale;
@ -69,7 +69,7 @@ namespace Deer {
return;
}
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
entt.getComponent<TransformComponent>().scale = scale;
@ -81,7 +81,7 @@ namespace Deer {
return 0;
}
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
return entt.getParentId();
@ -90,7 +90,7 @@ namespace Deer {
bool isEntityValid(uint32_t& entityUID) {
if (entityUID == 0 || entityUID == 1) return false;
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
Environment& m_environment = Scene::environment;
Entity& entt = m_environment.getEntity(entityUID);
return entt.isValid();

View File

@ -1,4 +1,5 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "Deer/Log.h"
#include "Deer/Voxels/Chunk.h"
@ -14,28 +15,46 @@
#include <vector>
namespace Deer {
VoxelWorld::VoxelWorld(const VoxelWorldProps& props) : m_worldProps(props) {
m_chunks = MakeScope<Chunk[]>(m_worldProps.getChunkCount());
m_layers = MakeScope<Layer[]>(m_worldProps.getLayerCount());
void VoxelWorld::initialize(const VoxelWorldProps& props) {
clear();
worldProps = props;
chunks = MakeScope<Chunk[]>(worldProps.getChunkCount());
layers = MakeScope<Layer[]>(worldProps.getLayerCount());
#ifdef DEER_RENDER
m_renderData =
MakeScope<VoxelWorldRenderData>(m_worldProps.getChunkCount());
initializeRenderVars(props);
#endif
initialized = true;
}
void VoxelWorld::clear() {
chunks.reset();
layers.reset();
initialized = false;
#ifdef DEER_RENDER
clearRenderVars();
#endif
}
VoxelWorld::~VoxelWorld() {}
const VoxelWorldProps& VoxelWorld::getWorldProps() {
return worldProps;
}
uint16_t VoxelWorld::calculateLayerVoxelHeight(int x, int z) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
LayerVoxelID layerVoxelID;
LayerID layerID;
extractLayerCordinates(x, z, layerID, layerVoxelID);
ChunkID chunkID(layerID.x, 0, layerID.z);
for (int y = m_worldProps.chunkSizeY - 1; y >= 0; y--) {
for (int y = worldProps.chunkSizeY - 1; y >= 0; y--) {
chunkID.y = y;
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
uint8_t chunkVoxelHeight =
chunk.calculateLayerVoxelHeight(layerVoxelID);
@ -43,6 +62,7 @@ namespace Deer {
return chunkVoxelHeight + chunkID.y * CHUNK_SIZE_Y;
}
}
return 0;
}
} // namespace Deer

View File

@ -0,0 +1,18 @@
#include "Deer/Voxels/VoxelWorldData.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/Layer.h"
namespace Deer {
namespace VoxelWorld {
VoxelWorldProps worldProps;
Scope<Chunk[]> chunks;
Scope<Layer[]> layers;
bool initialized;
}
bool VoxelWorld::isInitialized() {
return initialized;
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Deer/VoxelWorld.h"
#include "Deer/Memory.h"
namespace Deer {
namespace VoxelWorld {
extern VoxelWorldProps worldProps;
extern Scope<Chunk[]> chunks;
extern Scope<Layer[]> layers;
extern bool initialized;
}
}

View File

@ -2,6 +2,7 @@
#include "Deer/Log.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/Layer.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include <math.h>
#include <cmath>
@ -9,6 +10,8 @@
namespace Deer {
VoxelRayResult VoxelWorld::rayCast(glm::vec3 position, glm::vec3 dir, float maxDistance) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
VoxelRayResult result;
result.hitPos.x = (int32_t)std::floor(position.x);
@ -78,6 +81,8 @@ namespace Deer {
}
VoxelRayResult VoxelWorld::rayCast_editor(glm::vec3 position, glm::vec3 dir, float maxDistance) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
VoxelRayResult result;
result.hitPos.x = (int32_t)std::floor(position.x);

View File

@ -3,6 +3,8 @@
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/Layer.h"
#include "Deer/Voxels/VoxelWorldData.h"
#ifdef DEER_RENDER
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
#endif
@ -14,24 +16,28 @@
namespace Deer {
Voxel VoxelWorld::readVoxel(VoxelCordinates coords) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID chunkID;
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID)) return emptyVoxel;
if (!worldProps.isValid(chunkID)) return emptyVoxel;
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
return chunk.readVoxel(chunkVoxelID);
}
void VoxelWorld::setVoxel(VoxelCordinates coords, Voxel info) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID chunkID;
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID)) return;
if (!worldProps.isValid(chunkID)) return;
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
chunk.modVoxel(chunkVoxelID) = info;
LayerID layerID;
@ -39,7 +45,7 @@ namespace Deer {
extractLayerCordinates(coords.x, coords.z, layerID, layerVoxelID);
Layer& layer = m_layers[m_worldProps.getWorldLayerID(layerID)];
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
LayerVoxel& layerVoxel = layer.modLayerVoxel(layerVoxelID);
if (!info.isVoxelType())
@ -48,20 +54,20 @@ namespace Deer {
layerVoxel.height = coords.y + 1;
#ifdef DEER_RENDER
m_renderData->chunkQueue.addChunk(chunkID);
chunkQueue.addChunk(chunkID);
// For every axis, X & Y & Z
for (int i = 0; i < 3; i++) {
if (chunkVoxelID[i] == 0 && chunkID[i] != 0) {
ChunkID nextChunk = chunkID;
nextChunk[i]--;
m_renderData->chunkQueue.addChunk(nextChunk);
chunkQueue.addChunk(nextChunk);
}
if (chunkVoxelID[i] == CHUNK_SIZE(i) &&
chunkID[i] != m_worldProps[i] - 1) {
chunkID[i] != worldProps[i] - 1) {
ChunkID nextChunk = chunkID;
nextChunk[i]++;
m_renderData->chunkQueue.addChunk(nextChunk);
chunkQueue.addChunk(nextChunk);
}
}
@ -71,14 +77,15 @@ namespace Deer {
#endif
}
void VoxelWorld::fillVoxels(VoxelCordinates min, VoxelCordinates max,
Voxel info) {
void VoxelWorld::fillVoxels(VoxelCordinates min, VoxelCordinates max, Voxel info) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID minChunkID;
ChunkID maxChunkID;
ChunkVoxelID minChunkVoxelID;
ChunkVoxelID maxChunkVoxelID;
m_worldProps.clampAndSetMinMax(min, max);
worldProps.clampAndSetMinMax(min, max);
extractChunkCordinates(min, minChunkID, minChunkVoxelID);
extractChunkCordinates(max, maxChunkID, maxChunkVoxelID);
@ -89,9 +96,9 @@ namespace Deer {
ChunkID workingChunkID(chunkX, chunkY, chunkZ);
LayerID workingLayerID(chunkX, chunkZ);
Chunk& workingChunk =
m_chunks[m_worldProps.getWorldChunkID(workingChunkID)];
chunks[worldProps.getWorldChunkID(workingChunkID)];
Layer& workingLayer =
m_layers[m_worldProps.getWorldLayerID(workingLayerID)];
layers[worldProps.getWorldLayerID(workingLayerID)];
ChunkVoxelID workingMin(0, 0, 0);
ChunkVoxelID workingMax(CHUNK_SIZE_X - 1, CHUNK_SIZE_Y - 1,
@ -119,7 +126,7 @@ namespace Deer {
workingMinLayer, workingMaxLayer, max.y);
#ifdef DEER_RENDER
m_renderData->chunkQueue.addChunk(workingChunkID);
chunkQueue.addChunk(workingChunkID);
#endif
}
}
@ -134,8 +141,8 @@ namespace Deer {
maxLightModification[i] += 16;
}
m_worldProps.clampCordinates(minLightModification);
m_worldProps.clampCordinates(maxLightModification);
worldProps.clampCordinates(minLightModification);
worldProps.clampCordinates(maxLightModification);
bakeAmbientLight(minLightModification.x, maxLightModification.x,
minLightModification.z, maxLightModification.z);
@ -145,12 +152,14 @@ namespace Deer {
void VoxelWorld::remplaceVoxels(VoxelCordinates min, VoxelCordinates max,
Voxel ref, Voxel value) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID minChunkID;
ChunkID maxChunkID;
ChunkVoxelID minChunkVoxelID;
ChunkVoxelID maxChunkVoxelID;
m_worldProps.clampAndSetMinMax(min, max);
worldProps.clampAndSetMinMax(min, max);
extractChunkCordinates(min, minChunkID, minChunkVoxelID);
extractChunkCordinates(max, maxChunkID, maxChunkVoxelID);
@ -160,7 +169,7 @@ namespace Deer {
chunkZ++) {
ChunkID workingChunkID(chunkX, chunkY, chunkZ);
Chunk& workingChunk =
m_chunks[m_worldProps.getWorldChunkID(workingChunkID)];
chunks[worldProps.getWorldChunkID(workingChunkID)];
ChunkVoxelID workingMin(0, 0, 0);
ChunkVoxelID workingMax(CHUNK_SIZE_X - 1, CHUNK_SIZE_Y - 1,
@ -184,7 +193,7 @@ namespace Deer {
value);
#ifdef DEER_RENDER
m_renderData->chunkQueue.addChunk(workingChunkID);
chunkQueue.addChunk(workingChunkID);
#endif
}
}
@ -196,9 +205,9 @@ namespace Deer {
LayerVoxelID layerVoxelID;
extractLayerCordinates(xPos, zPos, layerID, layerVoxelID);
int worldLayerID = m_worldProps.getWorldLayerID(layerID);
int worldLayerID = worldProps.getWorldLayerID(layerID);
m_layers[worldLayerID].modLayerVoxel(layerVoxelID).height =
layers[worldLayerID].modLayerVoxel(layerVoxelID).height =
calculateLayerVoxelHeight(xPos, zPos);
}
}
@ -212,8 +221,8 @@ namespace Deer {
maxLightModification[i] += 16;
}
m_worldProps.clampCordinates(minLightModification);
m_worldProps.clampCordinates(maxLightModification);
worldProps.clampCordinates(minLightModification);
worldProps.clampCordinates(maxLightModification);
bakeAmbientLight(minLightModification.x, maxLightModification.x,
minLightModification.z, maxLightModification.z);
@ -226,9 +235,9 @@ namespace Deer {
LayerVoxelID layerVoxelID;
extractLayerCordinates(x, z, layerID, layerVoxelID);
if (!m_worldProps.isValid(layerID)) return LayerVoxel();
if (!worldProps.isValid(layerID)) return LayerVoxel();
Layer& layer = m_layers[m_worldProps.getWorldLayerID(layerID)];
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
return layer.readLayerVoxel(layerVoxelID);
}
@ -237,9 +246,9 @@ namespace Deer {
LayerVoxelID layerVoxelID;
extractLayerCordinates(x, z, layerID, layerVoxelID);
if (!m_worldProps.isValid(layerID)) return nullLayerVoxel;
if (!worldProps.isValid(layerID)) return nullLayerVoxel;
Layer& layer = m_layers[m_worldProps.getWorldLayerID(layerID)];
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
return layer.modLayerVoxel(layerVoxelID);
}

View File

@ -33,18 +33,6 @@ namespace Deer {
auto& tag = view.get<TagComponent>(entityId);
Entity& entity = getEntity(tag.entityUID);
if (entity.hasComponent<TextureBindingComponent>()) {
TextureBindingComponent& textureBinding = entity.getComponent<TextureBindingComponent>();
for (int x = 0; x < MAX_TEXTURE_BINDINGS; x++) {
if (textureBinding.textureAssetID[x] == 0)
continue;
Asset<Texture2D>& textureAsset = AssetManager::getAsset<Texture2D>(textureBinding.textureAssetID[x]);
textureAsset.value->bind(textureBinding.textureBindID[x]);
}
}
glm::mat4 matrix = entity.getWorldMatrix();
//Asset<Shader>& shaderAsset = AssetManager::getAsset<Shader>(meshRender.shaderAssetID);

View File

@ -6,13 +6,11 @@
#include "DeerRender/Render/RenderCommand.h"
namespace Deer {
Scene::~Scene() {}
void Scene::render() {
uint32_t mainCamera = m_enviroment->tryGetMainCamera();
uint32_t mainCamera = environment.tryGetMainCamera();
if (mainCamera == 0) return;
Entity& m_cameraEntity = m_enviroment->getEntity(mainCamera);
Entity& m_cameraEntity = environment.getEntity(mainCamera);
SceneCamera sceneCamera;
sceneCamera.camera = m_cameraEntity.getComponent<CameraComponent>();
sceneCamera.transform =
@ -23,10 +21,13 @@ namespace Deer {
void Scene::render(SceneCamera sceneCamera) {
RenderCommand::setDepthBuffer(true);
m_enviroment->render(sceneCamera);
if (m_voxelWorld) m_voxelWorld->render(sceneCamera);
environment.render(sceneCamera);
if (VoxelWorld::isInitialized())
VoxelWorld::render(sceneCamera);
RenderCommand::setDepthBuffer(false);
m_gizmoRenderer.render(sceneCamera);
gizmoRenderer.render(sceneCamera);
}
} // namespace Deer

View File

@ -1,22 +1,26 @@
#pragma once
#include "Deer/Components.h"
#include "Deer/Asset.h"
namespace Deer{
template<class Archive>
void save(Archive& archive,
MeshRenderComponent const& meshRender) {
// TO IMPLEMENT
/*
std::string meshLocation = AssetManager::getAssetLocation(meshRender.meshAssetID).generic_string();
archive(cereal::make_nvp("mesh", meshLocation));
std::string shaderLocation = AssetManager::getAssetLocation(meshRender.shaderAssetID).generic_string();
archive(cereal::make_nvp("shader", shaderLocation));
*/
}
template<class Archive>
void load(Archive& archive,
MeshRenderComponent& meshRender) {
// TO IMPLEMENT
/*
std::string meshLocation;
archive(cereal::make_nvp("mesh", meshLocation));
std::string shaderLocation;
@ -24,5 +28,6 @@ namespace Deer{
meshRender.meshAssetID = AssetManager::loadAsset<VertexArray>(std::filesystem::path(meshLocation));
meshRender.shaderAssetID = AssetManager::loadAsset<Shader>(std::filesystem::path(shaderLocation));
*/
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "Deer/Components.h"
#include "DeerRender/Render/Texture.h"
#include <string>
#include <vector>
@ -26,6 +27,9 @@ namespace Deer {
TextureBindingComponent& textureBinding) {
std::vector<TextureBinding> bindings;
// TO IMPLEMENT
/*
archive(cereal::make_nvp("bindings", bindings));
int id = 0;
@ -37,6 +41,8 @@ namespace Deer {
std::filesystem::path(binding.texturePath));
textureBinding.textureBindID[id] = binding.bindingID;
}
*/
}
template<class Archive>
@ -44,6 +50,8 @@ namespace Deer {
TextureBindingComponent const& textureBinding) {
std::vector<TextureBinding> bindings;
// TO IMPLEMENT
/*
for (int x = 0; x < MAX_TEXTURE_BINDINGS; x++) {
if (textureBinding.textureAssetID[x] != 0) {
bindings.push_back(TextureBinding(
@ -57,5 +65,6 @@ namespace Deer {
return a.bindingID < b.bindingID; });
archive(cereal::make_nvp("bindings", bindings));
*/
}
}

View File

@ -16,6 +16,14 @@ namespace Deer {
return chunkID;
}
void ChunkUpdateQueue::reset() {
while (!m_updateOrder.empty()) {
m_updateOrder.pop();
}
m_containingChunks.clear();
}
bool ChunkUpdateQueue::hasChunk() {
return m_updateOrder.size() > 0;
}

View File

@ -7,6 +7,8 @@
#include "Deer/Memory.h"
#include "Deer/Voxel.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
@ -18,30 +20,36 @@
namespace Deer {
VoxelLight VoxelWorld::readLight(VoxelCordinates coords) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID chunkID;
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID)) return lightVoxel;
if (!worldProps.isValid(chunkID)) return lightVoxel;
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
return chunk.readLight(chunkVoxelID);
}
VoxelLight& VoxelWorld::modLight(VoxelCordinates coords) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
ChunkID chunkID;
ChunkVoxelID chunkVoxelID;
extractChunkCordinates(coords, chunkID, chunkVoxelID);
if (!m_worldProps.isValid(chunkID)) return lightVoxel;
if (!worldProps.isValid(chunkID)) return lightVoxel;
m_renderData->chunkQueue.addChunk(chunkID);
chunkQueue.addChunk(chunkID);
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
return chunk.modLight(chunkVoxelID);
}
void VoxelWorld::render(const SceneCamera& camera) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
glm::mat4 camMatrix = glm::inverse(camera.transform.getMatrix());
glm::mat4 projectionMatrix = camera.camera.getMatrix();
glm::mat4 invertZ = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
@ -61,11 +69,11 @@ namespace Deer {
shader->uploadUniformInt("u_textureSize",
DataStore::getVoxelTextureAtlasSize());
for (int x = 0; x < m_worldProps.getChunkCount(); x++) {
ChunkRender& chunkRender = m_renderData->chunksRender[x];
for (int x = 0; x < worldProps.getChunkCount(); x++) {
ChunkRender& chunkRender = chunksRender[x];
if (!chunkRender.hasData) continue;
ChunkID chunkID = m_worldProps.getChunkID(x);
ChunkID chunkID = worldProps.getChunkID(x);
chunkRender.solidVoxel->bind();
shader->uploadUniformInt("u_chunkID_x", chunkID.x);

View File

@ -0,0 +1,39 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
namespace Deer {
namespace VoxelWorld {
// Chunk render data
Scope<ChunkRender[]> chunksRender;
ChunkUpdateQueue chunkQueue;
// Voxel creation data
std::vector<uint32_t> indices;
std::vector<SolidVoxelVertexData> vertexData;
std::queue<VoxelCordinates> ambientLightPropagation;
std::queue<VoxelCordinates> voxelLightPropagation;
std::vector<VoxelCordinates> tmp_voxelLightSource;
}
void VoxelWorld::clearRenderVars() {
chunksRender.reset();
chunkQueue.reset();
indices.clear();
vertexData.clear();
while (!ambientLightPropagation.empty()) {
ambientLightPropagation.pop();
}
while (!voxelLightPropagation.empty()) {
voxelLightPropagation.pop();
}
tmp_voxelLightSource.clear();
}
void VoxelWorld::initializeRenderVars(const VoxelWorldProps& props) {
chunksRender = MakeScope<ChunkRender[]>(props.getChunkCount());
}
} // namespace Deer

View File

@ -6,6 +6,7 @@
#include "Deer/Memory.h"
#include "Deer/Voxel.h"
#include "DeerRender/Render/VertexArray.h"
#include "Deer/VoxelWorld.h"
namespace Deer {
struct ChunkRender {
@ -38,6 +39,7 @@ namespace Deer {
public:
// TODO: Add priority
void addChunk(ChunkID);
void reset();
ChunkID pullChunk();
bool hasChunk();
@ -46,20 +48,21 @@ namespace Deer {
std::unordered_set<ChunkID, ChunkIDHash> m_containingChunks;
};
struct VoxelWorldRenderData {
VoxelWorldRenderData(size_t chunkCount) {
chunksRender = MakeScope<ChunkRender[]>(chunkCount);
}
namespace VoxelWorld {
// Chunk render data
extern Scope<ChunkRender[]> chunksRender;
extern ChunkUpdateQueue chunkQueue;
// Voxel creation data
extern std::vector<uint32_t> indices;
extern std::vector<SolidVoxelVertexData> vertexData;
// Chunk render data
Scope<ChunkRender[]> chunksRender;
ChunkUpdateQueue chunkQueue;
// Voxel temp light variables
extern std::queue<VoxelCordinates> ambientLightPropagation;
extern std::queue<VoxelCordinates> voxelLightPropagation;
extern std::vector<VoxelCordinates> tmp_voxelLightSource;
// Voxel creation data
std::vector<uint32_t> indices;
std::vector<SolidVoxelVertexData> vertexData;
std::queue<VoxelCordinates> ambientLightPropagation;
std::queue<VoxelCordinates> voxelLightPropagation;
std::vector<VoxelCordinates> tmp_voxelLightSource;
};
void clearRenderVars();
void initializeRenderVars(const VoxelWorldProps& props);
}
} // namespace Deer

View File

@ -4,6 +4,8 @@
#include "Deer/Asset.h"
#include "Deer/Components.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
@ -38,8 +40,8 @@ namespace Deer {
}
maxHeightSorroundings++;
if (maxHeightSorroundings >= CHUNK_SIZE_Y * m_worldProps.chunkSizeY)
maxHeightSorroundings = CHUNK_SIZE_Y * m_worldProps.chunkSizeY - 1;
if (maxHeightSorroundings >= CHUNK_SIZE_Y * worldProps.chunkSizeY)
maxHeightSorroundings = CHUNK_SIZE_Y * worldProps.chunkSizeY - 1;
ChunkID chunkID;
ChunkVoxelID chunkVoxelID;
@ -49,8 +51,8 @@ namespace Deer {
(xPos == minX) || (xPos == maxX) ||
(zPos == minZ) || (zPos == maxZ);
if (xPos == 0 || zPos == 0 || xPos == CHUNK_SIZE_X * m_worldProps.chunkSizeX - 1
|| zPos == CHUNK_SIZE_Z * m_worldProps.chunkSizeZ - 1)
if (xPos == 0 || zPos == 0 || xPos == CHUNK_SIZE_X * worldProps.chunkSizeX - 1
|| zPos == CHUNK_SIZE_Z * worldProps.chunkSizeZ - 1)
isPositionEdge = false;
// All light voxelsInfo under the max height must be put to 0 ambient light and above to 255
@ -61,7 +63,7 @@ namespace Deer {
// Empty the ilumination
for (; yPos < maxHeight; yPos++) {
extractChunkCordinates(xPos, yPos, zPos, chunkID, chunkVoxelID);
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
VoxelLight& voxelLight = chunk.modLight(chunkVoxelID);
voxelLight.ambient_light = 0;
@ -70,30 +72,30 @@ namespace Deer {
// Add to queue
for (; yPos < maxHeight; yPos++) {
extractChunkCordinates(xPos, yPos, zPos, chunkID, chunkVoxelID);
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
VoxelLight voxelLight = chunk.readLight(chunkVoxelID);
if (voxelLight.ambient_light > 0)
m_renderData->ambientLightPropagation.push(VoxelCordinates(xPos, yPos, zPos));
ambientLightPropagation.push(VoxelCordinates(xPos, yPos, zPos));
}
}
// Fill with light voxelsInfo and add queue to update light propagation
for (; yPos < maxHeightSorroundings; yPos++) {
extractChunkCordinates(xPos, yPos, zPos, chunkID, chunkVoxelID);
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
VoxelLight& voxelLight = chunk.modLight(chunkVoxelID);
voxelLight.ambient_light = 255;
m_renderData->ambientLightPropagation.push(VoxelCordinates(xPos, yPos, zPos));
ambientLightPropagation.push(VoxelCordinates(xPos, yPos, zPos));
}
modLayerVoxel(xPos, zPos).ambient_light_height = CHUNK_SIZE_Y * m_worldProps.chunkSizeY;
modLayerVoxel(xPos, zPos).ambient_light_height = CHUNK_SIZE_Y * worldProps.chunkSizeY;
}
}
//Resolve ambient light propagation
while (!m_renderData->ambientLightPropagation.empty()) {
while (!ambientLightPropagation.empty()) {
resolveNextAmbientLightPropagation();
}
}
@ -106,17 +108,17 @@ namespace Deer {
int maxZ = z + 16;
minX = (minX < 0) ? 0 : minX;
maxX = (maxX >= m_worldProps.chunkSizeX * CHUNK_SIZE_X) ? m_worldProps.chunkSizeX * CHUNK_SIZE_X - 1 : maxX;
maxX = (maxX >= worldProps.chunkSizeX * CHUNK_SIZE_X) ? worldProps.chunkSizeX * CHUNK_SIZE_X - 1 : maxX;
minZ = (minZ < 0) ? 0 : minZ;
maxZ = (maxZ >= m_worldProps.chunkSizeZ * CHUNK_SIZE_Z) ? m_worldProps.chunkSizeZ * CHUNK_SIZE_Z - 1 : maxZ;
maxZ = (maxZ >= worldProps.chunkSizeZ * CHUNK_SIZE_Z) ? worldProps.chunkSizeZ * CHUNK_SIZE_Z - 1 : maxZ;
bakeAmbientLight(minX, maxX, minZ, maxZ);
}
void VoxelWorld::resolveNextAmbientLightPropagation() {
VoxelCordinates position = m_renderData->ambientLightPropagation.front();
m_renderData->ambientLightPropagation.pop();
VoxelCordinates position = ambientLightPropagation.front();
ambientLightPropagation.pop();
LayerVoxel& layerVoxel = modLayerVoxel(position.x, position.z);
@ -143,7 +145,7 @@ namespace Deer {
if (nextLight.ambient_light < nextLightMinValue) {
nextLight.ambient_light = nextLightMinValue;
m_renderData->ambientLightPropagation.push(next);
ambientLightPropagation.push(next);
}
}
@ -172,7 +174,7 @@ namespace Deer {
if (nextLight.ambient_light < nextLightMinValue) {
nextLight.ambient_light = nextLightMinValue;
m_renderData->ambientLightPropagation.push(next);
ambientLightPropagation.push(next);
}
}
}

View File

@ -3,6 +3,8 @@
#include "Deer/Components.h"
#include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h"
@ -13,12 +15,14 @@
namespace Deer {
void VoxelWorld::bakeNextChunk() {
if (!m_renderData->chunkQueue.hasChunk()) return;
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
if (!chunkQueue.hasChunk()) return;
// Pull the next chunk to render
ChunkID nextChunk = m_renderData->chunkQueue.pullChunk();
m_renderData->vertexData.clear();
m_renderData->indices.clear();
ChunkID nextChunk = chunkQueue.pullChunk();
vertexData.clear();
indices.clear();
// For each voxel
for (int x = 0; x < CHUNK_SIZE_X; x++) {
@ -33,11 +37,11 @@ namespace Deer {
Ref<VertexArray> va = VertexArray::create();
va->bind();
Ref<VertexBuffer> vb = VertexBuffer::create(
m_renderData->vertexData.data(),
m_renderData->vertexData.size() * sizeof(SolidVoxelVertexData));
vertexData.data(),
vertexData.size() * sizeof(SolidVoxelVertexData));
Ref<IndexBuffer> ib =
IndexBuffer::create(m_renderData->indices.data(),
m_renderData->indices.size() * sizeof(uint32_t),
IndexBuffer::create(indices.data(),
indices.size() * sizeof(uint32_t),
IndexDataType::Unsigned_Int);
BufferLayout layout(
@ -81,14 +85,14 @@ namespace Deer {
va->setIndexBuffer(ib);
// Update the data to the chunk render
int id = m_worldProps.getWorldChunkID(nextChunk);
ChunkRender& chunkRender = m_renderData->chunksRender[id];
int id = worldProps.getWorldChunkID(nextChunk);
ChunkRender& chunkRender = chunksRender[id];
chunkRender.solidVoxel = va;
chunkRender.hasData = true;
}
void VoxelWorld::genSolidVoxel(ChunkID chunkID, ChunkVoxelID chunkVoxelID) {
Chunk& workingChunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
Chunk& workingChunk = chunks[worldProps.getWorldChunkID(chunkID)];
Voxel voxel = workingChunk.readVoxel(chunkVoxelID);
if (!voxel.isVoxelType()) return;
@ -127,7 +131,7 @@ namespace Deer {
front2VoxelLight.ambient_light);
// Save the vertex id for later
int vertexID = m_renderData->vertexData.size();
int vertexID = vertexData.size();
int voxel_count[4];
@ -230,26 +234,26 @@ namespace Deer {
vertex_data.u = VERTEX_UV(X_AXIS, v);
vertex_data.v = VERTEX_UV(Y_AXIS, v);
m_renderData->vertexData.push_back(vertex_data);
vertexData.push_back(vertex_data);
}
if (voxel_count[0] + voxel_count[3] >
voxel_count[1] + voxel_count[2]) {
m_renderData->indices.push_back(vertexID);
m_renderData->indices.push_back(vertexID + 2);
m_renderData->indices.push_back(vertexID + 1);
indices.push_back(vertexID);
indices.push_back(vertexID + 2);
indices.push_back(vertexID + 1);
m_renderData->indices.push_back(vertexID + 1);
m_renderData->indices.push_back(vertexID + 2);
m_renderData->indices.push_back(vertexID + 3);
indices.push_back(vertexID + 1);
indices.push_back(vertexID + 2);
indices.push_back(vertexID + 3);
} else {
m_renderData->indices.push_back(vertexID);
m_renderData->indices.push_back(vertexID + 3);
m_renderData->indices.push_back(vertexID + 1);
indices.push_back(vertexID);
indices.push_back(vertexID + 3);
indices.push_back(vertexID + 1);
m_renderData->indices.push_back(vertexID + 2);
m_renderData->indices.push_back(vertexID + 3);
m_renderData->indices.push_back(vertexID);
indices.push_back(vertexID + 2);
indices.push_back(vertexID + 3);
indices.push_back(vertexID);
}
}
}

View File

@ -1,21 +1,25 @@
#include "Deer/VoxelWorld.h"
#include "Deer/Log.h"
#include "Deer/Voxels/Chunk.h"
#include "Deer/Voxels/VoxelWorldData.h"
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
namespace Deer {
void VoxelWorld::bakeVoxelLightFromPoint(VoxelCordinates coords) {
VoxelCordinates min =
VoxelCordinates(coords.x - 16, coords.y - 16, coords.z - 16);
VoxelCordinates max =
VoxelCordinates(coords.x + 16, coords.y + 16, coords.z + 16);
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
m_worldProps.clampCordinates(min);
m_worldProps.clampCordinates(max);
VoxelCordinates min = VoxelCordinates(coords.x - 16, coords.y - 16, coords.z - 16);
VoxelCordinates max = VoxelCordinates(coords.x + 16, coords.y + 16, coords.z + 16);
worldProps.clampCordinates(min);
worldProps.clampCordinates(max);
bakeVoxelLight(min, max);
}
void VoxelWorld::bakeVoxelLight(VoxelCordinates min, VoxelCordinates max) {
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
// We want to make the box 1 layer smaller
// For every axis, X & Y & Z
for (int i = 0; i < 3; i++) {
@ -30,7 +34,7 @@ namespace Deer {
extractChunkCordinates(min, minChunkID, minChunkVoxelID);
extractChunkCordinates(max, maxChunkID, maxChunkVoxelID);
m_renderData->tmp_voxelLightSource.clear();
tmp_voxelLightSource.clear();
// We want to empty the voxel light of the section first
ChunkID workingChunkID;
@ -56,10 +60,10 @@ namespace Deer {
: CHUNK_SIZE_Z - 1);
Chunk& workingChunk =
m_chunks[m_worldProps.getWorldChunkID(workingChunkID)];
chunks[worldProps.getWorldChunkID(workingChunkID)];
workingChunk.clearVoxelLightAndSaveSources(
workingMinVoxelID, workingMaxVoxelID, workingChunkID,
m_renderData->tmp_voxelLightSource);
tmp_voxelLightSource);
}
}
}
@ -75,10 +79,10 @@ namespace Deer {
if (minZEdgeLight.b_light || minZEdgeLight.g_light ||
minZEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(minZEdge);
voxelLightPropagation.push(minZEdge);
if (maxZEdgeLight.b_light || maxZEdgeLight.g_light ||
maxZEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(maxZEdge);
voxelLightPropagation.push(maxZEdge);
}
}
@ -92,10 +96,10 @@ namespace Deer {
if (minYEdgeLight.b_light || minYEdgeLight.g_light ||
minYEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(minYEdge);
voxelLightPropagation.push(minYEdge);
if (maxYEdgeLight.b_light || maxYEdgeLight.g_light ||
maxYEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(maxYEdge);
voxelLightPropagation.push(maxYEdge);
}
}
@ -109,14 +113,14 @@ namespace Deer {
if (minXEdgeLight.b_light || minXEdgeLight.g_light ||
minXEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(minXEdge);
voxelLightPropagation.push(minXEdge);
if (maxXEdgeLight.b_light || maxXEdgeLight.g_light ||
maxXEdgeLight.b_light)
m_renderData->voxelLightPropagation.push(maxXEdge);
voxelLightPropagation.push(maxXEdge);
}
}
for (VoxelCordinates& cordinates : m_renderData->tmp_voxelLightSource) {
for (VoxelCordinates& cordinates : tmp_voxelLightSource) {
VoxelLight& voxelLight = modLight(cordinates);
Voxel voxel = readVoxel(cordinates);
@ -125,17 +129,19 @@ namespace Deer {
voxelLight.g_light = voxelAspect.definition.colorEmission.g_value;
voxelLight.b_light = voxelAspect.definition.colorEmission.b_value;
m_renderData->voxelLightPropagation.push(cordinates);
voxelLightPropagation.push(cordinates);
}
while (!m_renderData->voxelLightPropagation.empty()) {
while (!voxelLightPropagation.empty()) {
resolveNextVoxelLightPropagation();
}
}
void VoxelWorld::resolveNextVoxelLightPropagation() {
VoxelCordinates position = m_renderData->voxelLightPropagation.front();
m_renderData->voxelLightPropagation.pop();
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
VoxelCordinates position = voxelLightPropagation.front();
voxelLightPropagation.pop();
VoxelLight currentLight = readLight(position);
bool voxelCheck[6] = {false};
@ -188,7 +194,7 @@ namespace Deer {
}
if (nextVoxelModified)
m_renderData->voxelLightPropagation.push(next);
voxelLightPropagation.push(next);
}
return;
@ -235,7 +241,7 @@ namespace Deer {
}
if (nextVoxelModified)
m_renderData->voxelLightPropagation.push(next);
voxelLightPropagation.push(next);
}
}
} // namespace Deer

View File

@ -10,15 +10,11 @@
#include "DeerRender/Mesh.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/Editor/Fonts.h"
#include "DeerStudio/Fonts.h"
#include "DeerStudio/Editor/GamePanel.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Editor/PropertiesPanel.h"
#include "DeerStudio/Editor/SceneExplorer.h"
#include "DeerStudio/Editor/Terrain/TerrainEditor.h"
#include "DeerStudio/Editor/TreePanel.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "Style.h"
namespace Deer {
@ -51,13 +47,14 @@ namespace Deer {
io.IniFilename = filenameFLoc;
initializeFonts();
setNatureStyle();
SetupImGuiStyle();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
auto m_gamePanel = Ref<GamePanel>(new GamePanel());
Panels.push_back(m_gamePanel);
Environment& env = Project::m_scene.getMainEnviroment();
Environment& env = Scene::environment;
Entity& exampleObject = env.createEntity("Example");
MeshRenderComponent& renderComponent = exampleObject.addComponent<MeshRenderComponent>();
@ -72,8 +69,8 @@ namespace Deer {
}
void DeerStudioApplication::onShutdown() {
if (Project::m_scene.getExecutingState())
Project::m_scene.endExecution();
if (Scene::getExecutingState())
Scene::endExecution();
ScriptEngine::shutdownScriptEngine();
Panels.clear();
@ -90,10 +87,11 @@ namespace Deer {
}
void DeerStudioApplication::onUpdate(Timestep delta) {
if (Project::m_scene.getExecutingState())
Project::m_scene.updateInternalVars();
if (Project::m_scene.isVoxelWorldInitialized())
Project::m_scene.getVoxelWorld().bakeNextChunk();
if (Scene::getExecutingState())
Scene::tick();
if (VoxelWorld::isInitialized())
VoxelWorld::bakeNextChunk();
}
void DeerStudioApplication::onEvent(Event& e) {
@ -145,13 +143,10 @@ namespace Deer {
// ---- PanelS -----
EditorEngine::execute();
TreePanel::onImgui();
PropertiesPanel::onImgui();
TerrainEditor::onImGui();
viewport_onImGui();
// ---- PanelS -----
Project::m_scene.getMainGizmoRenderer().refresh();
Scene::gizmoRenderer.refresh();
ImGui::End();
}
@ -178,21 +173,21 @@ namespace Deer {
if (ImGui::BeginMenu("Scene")) {
if (ImGui::MenuItem("New scene")) {
// TODO
Project::m_scene.clear();
DataStore::exportScene(Project::m_scene, "new_scene");
Scene::clear();
DataStore::exportScene("new_scene");
}
// if (Project::m_sceneSerializer->getCurrentScenePath() !=
// "_NO_INITIALIZED_" && ImGui::MenuItem("Save scene")) {
// Project::m_sceneSerializer->serialize(Project::m_sceneSerializer->getCurrentScenePath());
// }
if (ImGui::MenuItem("Save scene")) {
DataStore::exportScene(Project::m_scene, "saved_scene");
DataStore::exportScene("saved_scene");
}
if (ImGui::MenuItem("Save scene as...")) {
// TODO
}
if (ImGui::MenuItem("Load scene")) {
// Project::m_scene.swap(DataStore::loadScene("new_scene"));
// Scene::swap(DataStore::loadScene("new_scene"));
// DataStore::exportScene(Project::m_scene,
// "new_scene");
}
@ -232,7 +227,7 @@ namespace Deer {
if (ImGui::BeginMenu("Scripts")) {
if (ImGui::MenuItem("Reload scripts") &&
!Project::m_scene.getExecutingState()) {
!Scene::getExecutingState()) {
ScriptEngine::shutdownScriptEngine();
ScriptEngine::compileScriptEngine(
std::filesystem::path("scripts"));

View File

@ -1,178 +0,0 @@
#include "AssetManagerPanel.h"
#include "DeerStudio/Project.h"
#include "Deer/Log.h"
#include "Deer/Asset.h"
#include "DeerRender/Render/Texture.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "imgui.h"
#include <string>
#ifdef WINDOWS
// WINDOWS SPECIFIC
#include <windows.h>
#include <shellapi.h>
#endif
namespace Deer {
void openFileExplorer(const std::string& relativePath) {
#ifdef WINDOWS
// Convert std::string to std::wstring
std::wstring widePath(relativePath.begin(), relativePath.end());
wchar_t buffer[MAX_PATH];
GetFullPathNameW(widePath.c_str(), MAX_PATH, buffer, nullptr);
// Open the file explorer at the given path
ShellExecuteW(nullptr, L"open", buffer, nullptr, nullptr, SW_SHOW);
#endif
}
namespace fs = std::filesystem;
AssetManagerPanel::AssetManagerPanel()
: m_currentPath(DataStore::rootPath / "assets"){
m_folderIcon = Texture2D::create("editor/icons/folder.png");
m_fileIcon = Texture2D::create("editor/icons/file.png");
m_scneIcon = Texture2D::create("editor/icons/scene.png");
m_objectIcon = Texture2D::create("editor/icons/object.png");
m_shaderIcon = Texture2D::create("editor/icons/shader.png");
}
void AssetManagerPanel::onImGui() {
m_clickHandled = false;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(30, 30));
ImGui::Begin("Assets");
ImGui::PopStyleVar();
float width = ImGui::GetWindowContentRegionWidth();
if (width < m_iconMinSize + 40) {
ImGui::Text("Window too small");
ImGui::End();
return;
}
int cols = (int)ceilf(width / (m_iconMinSize + 40));
float componentWidth = width / (float)cols;
if (m_currentPath != "assets") {
if (ImGui::Button(m_currentPath.parent_path().string().c_str()))
m_currentPath = m_currentPath.parent_path();
}
else
ImGui::Button("assets");
ImGui::SameLine();
if (ImGui::Button("Open File Explorer"))
openFileExplorer(m_currentPath.string());
try {
ImGui::Columns(cols, 0, false);
for (const auto& entry : fs::directory_iterator(m_currentPath)) {
if (entry.is_directory())
drawFolder(entry.path());
else
drawFile(entry.path());
float cursorOffset = (m_iconMinSize - ImGui::CalcTextSize(entry.path().filename().string().c_str()).x) / 2;
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x, ImGui::GetCursorPos().y));
ImGui::Text("%s",entry.path().filename().string().c_str());
ImGui::NextColumn();
}
ImGui::Columns();
}
catch (const fs::filesystem_error& err) {
DEER_CORE_ERROR("Asset manager filesystem error");
}
if (!m_clickHandled && ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
ImGui::IsMouseClicked(ImGuiMouseButton_Right) &&
!ImGui::IsAnyItemHovered()) {
ImGui::OpenPopup("AssetManagerPopUp");
}
updateContextMenu();
ImGui::End();
}
void AssetManagerPanel::drawFolder(const std::filesystem::path& path) {
ImGui::Image((void*)(uint64_t)m_folderIcon->getTextureID(), ImVec2(m_iconMinSize , m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
m_currentPath = path;
}
}
void AssetManagerPanel::updateContextMenu() {
if (ImGui::BeginPopup("AssetManagerPopUp")) {
if (ImGui::MenuItem("New Folder")) {
std::filesystem::path path = m_currentPath / "newFolder";
std::filesystem::create_directory(path);
}
ImGui::EndPopup();
}
}
void AssetManagerPanel::drawFile(const std::filesystem::path& path) {
std::string extension = path.filename().extension().string();
if (extension == ".dscn") {
ImGui::Image((void*)(uint64_t)m_scneIcon->getTextureID(), ImVec2(m_iconMinSize, m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
// Open scene
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
try {
m_currentScenePath = path;
}
catch ( ... ) {
DEER_CORE_ERROR("Error while loading scene {0}, file might be corrupt", path.string().c_str());
}
}
} else if (extension == ".obj") {
ImGui::Image((void*)(uint64_t)m_objectIcon->getTextureID(), ImVec2(m_iconMinSize, m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
std::string pathString = path.string();
ImGui::SetDragDropPayload("_MESH", pathString.c_str(), pathString.size() + 1);
ImGui::Text("%s", path.string().c_str());
ImGui::EndDragDropSource();
}
} else if (extension == ".glsl") {
ImGui::Image((void*)(uint64_t)m_shaderIcon->getTextureID(), ImVec2(m_iconMinSize, m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
std::string pathString = path.string();
ImGui::SetDragDropPayload("_SHADER", pathString.c_str(), pathString.size() + 1);
ImGui::Text("%s", path.string().c_str());
ImGui::EndDragDropSource();
}
} else if (extension == ".png" || extension == ".jpg" || extension == ".jpeg") {
uint32_t textureID = AssetManager::loadAsset<Texture2D>(path.string());
Asset<Texture2D>& textureAsset = AssetManager::getAsset<Texture2D>(textureID);
ImGui::Image((void*)(uint64_t)textureAsset.value->getTextureID(), ImVec2(m_iconMinSize, m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) {
std::string pathString = path.string();
ImGui::SetDragDropPayload("_TEXTURE2D", pathString.c_str(), pathString.size() + 1);
ImGui::Text("%s", path.string().c_str());
ImGui::EndDragDropSource();
}
} else {
ImGui::Image((void*)(uint64_t)m_fileIcon->getTextureID(), ImVec2(m_iconMinSize, m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0));
}
}
}

View File

@ -1,35 +0,0 @@
#pragma once
#include "DeerStudio/Editor/EditorPanel.h"
#include "Deer/Memory.h"
#include <filesystem>
namespace Deer {
class Texture2D;
class DeerStudioLayer;
class SceneSerializer;
class AssetManagerPanel : public EditorPanel{
public:
AssetManagerPanel();
void onImGui() override;
private:
void drawFolder(const std::filesystem::path&);
void drawFile(const std::filesystem::path&);
void updateContextMenu();
private:
std::filesystem::path m_currentScenePath;
std::filesystem::path m_currentPath; // Assets/path...
Ref<Texture2D> m_folderIcon;
Ref<Texture2D> m_fileIcon;
Ref<Texture2D> m_scneIcon;
Ref<Texture2D> m_objectIcon;
Ref<Texture2D> m_shaderIcon;
int m_iconMinSize = 110;
bool m_clickHandled = false;
};
}

View File

@ -5,7 +5,6 @@
#include "Deer/Enviroment.h"
#include "Deer/Scene.h"
#include "Deer/ScriptEngine.h"
#include "DeerStudio/Project.h"
#include "imgui.h"
namespace Deer {
@ -20,23 +19,23 @@ namespace Deer {
ImGui::Begin("Game Window");
ImGui::PopStyleVar();
Environment& environment = Project::m_scene.getMainEnviroment();
Environment& environment = Scene::environment;
uint32_t cameraUID = environment.tryGetMainCamera();
if (cameraUID == 0) {
ImGui::TextColored(ImVec4(.3f, .3f, .8f, 1.0f),
"There is no camera");
if (!Project::m_scene.getExecutingState()) {
if (!Scene::getExecutingState()) {
if (ScriptEngine::isCompilationValid() &&
ImGui::Button("Execute")) {
DataStore::exportRuntimeScene(Project::m_scene);
Project::m_scene.beginExecution();
DataStore::exportRuntimeScene();
Scene::beginExecution();
}
} else {
if (ImGui::Button("Stop")) {
Project::m_scene.endExecution();
DataStore::importRuntimeScene(Project::m_scene);
Scene::endExecution();
DataStore::importRuntimeScene();
}
}
@ -67,7 +66,7 @@ namespace Deer {
unsigned char clearColor[4]{0, 0, 0, 255};
m_frameBuffer->clearBuffer(0, &clearColor);
Project::m_scene.render();
Scene::render();
m_frameBuffer->unbind();
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0),
@ -75,16 +74,16 @@ namespace Deer {
ImGui::SetCursorPos(cursorPos);
if (!Project::m_scene.getExecutingState()) {
if (!Scene::getExecutingState()) {
if (ScriptEngine::isCompilationValid() &&
ImGui::Button("Execute")) {
DataStore::exportRuntimeScene(Project::m_scene);
Project::m_scene.beginExecution();
DataStore::exportRuntimeScene();
Scene::beginExecution();
}
} else {
if (ImGui::Button("Stop")) {
Project::m_scene.endExecution();
DataStore::importRuntimeScene(Project::m_scene);
Scene::endExecution();
DataStore::importRuntimeScene();
}
}

View File

@ -7,7 +7,6 @@
#include "glm/glm.hpp"
namespace Deer {
class Scene;
class FrameBuffer;
class GamePanel : public EditorPanel {

View File

@ -1,465 +0,0 @@
#include "PropertiesPanel.h"
#include "Deer/Asset.h"
#include "Deer/ScriptEngine.h"
#include "DeerRender/Input.h"
#include "DeerRender/Render/Texture.h"
#include "DeerStudio/Editor/Fonts.h"
#include "DeerStudio/Project.h"
#include "imgui.h"
namespace Deer {
namespace PropertiesPanel {
void addComponentContext();
template <typename T>
bool collapsingComponentHeader(const std::string& componentName,
bool canDelete = true);
template <typename T>
void addComponentButton(const std::string& componentName);
void addScriptButton(const std::string& scriptID);
void drawMagicSlider(const std::string& text, float* value);
void drawMagicSlider3f(const std::string& text, float* value,
float defaultValue = 0);
} // namespace PropertiesPanel
bool* getIsEditingState(ImGuiID id) {
ImGuiStorage* storage = ImGui::GetStateStorage();
void* ptr = storage->GetVoidPtr(id);
if (ptr) return (bool*)ptr;
// If state doesn't exist, initialize it
bool* state = new bool(false);
storage->SetVoidPtr(id, state);
return state;
}
void PropertiesPanel::onImgui() {
ImGui::Begin("Properties");
if (ActiveEntity::count() == 0) {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1),
"No entity selected");
ImGui::End();
return;
}
Entity& activeEntity = ActiveEntity::getEntity(0);
ImGui::PushFont(titleText);
auto& tag = activeEntity.getComponent<TagComponent>();
if (tag.tag == "")
ImGui::Text("-");
else
ImGui::Text("%s", tag.tag.c_str());
ImGui::PopFont();
ImGui::Separator();
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1), "Id : %u",
tag.entityUID);
if (activeEntity.isRoot()) {
ImGui::End();
return;
}
ImGui::SameLine();
addComponentContext();
ImGui::Dummy(ImVec2(0.0f, 10.0f));
if (collapsingComponentHeader<TransformComponent>("Transform Component",
false)) {
auto& transform = activeEntity.getComponent<TransformComponent>();
drawMagicSlider3f("Position", &transform.position.x, 0);
glm::vec3 rotation = transform.getEulerAngles();
glm::vec3 lastRotation = rotation;
drawMagicSlider3f("Rotation", &rotation.x, 0);
if (rotation != lastRotation) transform.setEulerAngles(rotation);
drawMagicSlider3f("Scale", &transform.scale.x, 1);
if (rotation != lastRotation) transform.setEulerAngles(rotation);
ImGui::Dummy(ImVec2(0.0f, 5.0f));
}
if (collapsingComponentHeader<ScriptComponent>("Script Component")) {
auto& script = activeEntity.getComponent<ScriptComponent>();
// ------ MESH -----
std::string scriptName;
if (script.scriptID == "")
scriptName = " null ";
else
scriptName = script.scriptID;
ImGui::Text("Script : ");
ImGui::SameLine();
ImGui::Button(scriptName.c_str());
ImGui::Dummy(ImVec2(0.0f, 5.0f));
}
if (collapsingComponentHeader<MeshRenderComponent>(
"Mesh Render Component")) {
auto& mesh = activeEntity.getComponent<MeshRenderComponent>();
// ------ MESH -----
std::string meshName;
if (mesh.meshAssetID == 0)
meshName = " null ";
else
meshName = AssetManager::getAssetLocation(mesh.meshAssetID)
.generic_string();
ImGui::Text("Mesh : ");
ImGui::SameLine();
ImGui::Button(meshName.c_str());
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("_MESH")) {
std::string receivedData =
std::string((const char*)payload->Data);
mesh.meshAssetID =
AssetManager::loadAsset<VertexArray>(receivedData);
}
ImGui::EndDragDropTarget();
}
// ------ Shader -----
std::string shaderName;
if (mesh.shaderAssetID == 0)
shaderName = " null ";
else
shaderName = AssetManager::getAssetLocation(mesh.shaderAssetID)
.generic_string();
ImGui::Text("Shader : ");
ImGui::SameLine();
ImGui::Button(shaderName.c_str());
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("_SHADER")) {
std::string receivedData =
std::string((const char*)payload->Data);
mesh.shaderAssetID =
AssetManager::loadAsset<Shader>(receivedData);
}
ImGui::EndDragDropTarget();
}
ImGui::Dummy(ImVec2(0.0f, 5.0f));
}
if (collapsingComponentHeader<TextureBindingComponent>(
"Texture Binding Component")) {
TextureBindingComponent& textureBinding =
activeEntity.getComponent<TextureBindingComponent>();
int textureBindingCount = 0;
for (int x = 0; x < MAX_TEXTURE_BINDINGS; x++) {
if (textureBinding.textureAssetID[x] == 0) continue;
ImGui::PushID(x);
textureBindingCount++;
std::string textureBindingName =
AssetManager::getAssetLocation(
textureBinding.textureAssetID[x])
.generic_string();
int currentID = textureBinding.textureBindID[x];
ImGui::Text("Texture : ");
ImGui::SameLine();
ImGui::Button(textureBindingName.c_str());
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("_TEXTURE2D")) {
std::string receivedData =
std::string((const char*)payload->Data);
textureBinding.textureAssetID[x] =
AssetManager::loadAsset<Texture2D>(
std::filesystem::path(receivedData));
}
ImGui::EndDragDropTarget();
}
ImGui::Text("Binding location");
ImGui::SameLine();
ImGui::InputInt("#bindingInputID", &currentID, 0);
currentID = (currentID < 0) ? 0
: (currentID > 12) ? 12
: currentID;
textureBinding.textureBindID[x] = currentID;
if (ImGui::Button("Delete texture binding"))
textureBinding.textureAssetID[x] = 0;
ImGui::Spacing();
ImGui::PopID();
}
ImGui::Spacing();
if (textureBindingCount < 4) {
ImGui::Button("Add texture binding");
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("_TEXTURE2D")) {
std::string receivedData =
std::string((const char*)payload->Data);
for (int x = 0; x < 4; x++) {
if (textureBinding.textureAssetID[x] != 0) continue;
textureBinding.textureAssetID[x] =
AssetManager::loadAsset<Texture2D>(
std::filesystem::path(receivedData));
textureBinding.textureBindID[x] = 0;
break;
}
}
ImGui::EndDragDropTarget();
}
}
ImGui::Unindent();
ImGui::Dummy(ImVec2(0.0f, 10.0f));
}
if (collapsingComponentHeader<CameraComponent>("Camera Component")) {
ImGui::Dummy(ImVec2(0.0f, 10.0f));
ImGui::Indent();
auto& camera = activeEntity.getComponent<CameraComponent>();
uint32_t currentMainCamera =
activeEntity.getEnvironment()->tryGetMainCamera();
if (currentMainCamera == activeEntity.getId())
ImGui::Button("This is the main camera");
else if (ImGui::Button("Set main camera")) {
activeEntity.getEnvironment()->setMainCamera(activeEntity);
}
float fov = glm::degrees(camera.fov);
ImGui::SliderFloat("Fov", &fov, 1, 180);
camera.fov = glm::radians(fov);
ImGui::InputFloat("Z Near", &camera.nearZ, 0, 1000);
ImGui::InputFloat("Z Far", &camera.farZ, 1, 10000);
ImGui::Unindent();
ImGui::Dummy(ImVec2(0.0f, 10.0f));
}
ImGui::End();
}
void PropertiesPanel::drawMagicSlider(const std::string& text,
float* value) {
ImGuiID id = ImGui::GetID(text.c_str());
bool* isEditing = getIsEditingState(id);
if (*isEditing) {
if (ImGui::InputFloat(text.c_str(), value, 0.0f, 0.0f, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue))
*isEditing = false;
if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0))
*isEditing = false;
return;
}
ImGui::DragFloat(text.c_str(), value, 0.05f, 0.0f, 0.0f, "%.3f",
ImGuiSliderFlags_NoRoundToFormat);
if (ImGui::IsItemHovered() &&
ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
*isEditing = true;
}
void PropertiesPanel::drawMagicSlider3f(const std::string& text,
float* value, float defaultValue) {
ImGui::Columns(4, 0, false);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2());
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding,
0.0f); // Set FrameRounding to 0 for hard edges
ImGui::Text("%s", text.c_str());
ImGui::NextColumn();
ImGui::PushStyleColor(
ImGuiCol_Button, ImVec4(0.7f, 0.2f, 0.2f, 1.0f)); // Red background
ImGui::PushStyleColor(
ImGuiCol_ButtonHovered,
ImVec4(0.6f, 0.2f, 0.2f, 1.0f)); // Darker red when hovered
ImGui::PushStyleColor(
ImGuiCol_ButtonActive,
ImVec4(0.4f, 0.2f, 0.2f, 1.0f)); // Even darker red when active
if (ImGui::Button((" X ##" + text).c_str())) *value = defaultValue;
ImGui::SameLine();
ImGui::PopStyleColor(3); // Restore original style
drawMagicSlider("##" + text + "_x", value);
ImGui::PushStyleColor(
ImGuiCol_Button,
ImVec4(0.2f, 0.7f, 0.2f, 1.0f)); // Green background
ImGui::PushStyleColor(
ImGuiCol_ButtonHovered,
ImVec4(0.2f, 0.6f, 0.2f, 1.0f)); // Darker green when hovered
ImGui::PushStyleColor(
ImGuiCol_ButtonActive,
ImVec4(0.2f, 0.4f, 0.2f, 1.0f)); // Even darker green when active
ImGui::NextColumn();
if (ImGui::Button((" Y ##" + text).c_str())) value[1] = defaultValue;
ImGui::SameLine();
ImGui::PopStyleColor(3); // Restore original style
drawMagicSlider("##" + text + "_y", &value[1]);
ImGui::PushStyleColor(
ImGuiCol_Button,
ImVec4(0.2f, 0.2f, 0.7f, 1.0f)); // Blue background
ImGui::PushStyleColor(
ImGuiCol_ButtonHovered,
ImVec4(0.2f, 0.2f, 0.6f, 1.0f)); // Darker blue when hovered
ImGui::PushStyleColor(
ImGuiCol_ButtonActive,
ImVec4(0.2f, 0.2f, 0.4f, 1.0f)); // Even darker blue when active
ImGui::NextColumn();
if (ImGui::Button((" Z ##" + text).c_str())) value[2] = defaultValue;
ImGui::SameLine();
ImGui::PopStyleColor(3); // Restore original style
drawMagicSlider("##" + text + "_z", &value[2]);
ImGui::Columns();
ImGui::PopStyleVar(2);
}
void PropertiesPanel::addComponentContext() {
float buttonWidth =
ImGui::CalcTextSize(" + add Component ").x; // Example button width
float windowWidth = ImGui::GetWindowSize().x;
float availableWidth = windowWidth - ImGui::GetCursorPosX();
// Place button at the right, with some padding (e.g., 10px)
ImGui::SetCursorPosX(windowWidth - buttonWidth - 20);
if (ImGui::Button(
" + add Component ")) { //,
// ImVec2(ImGui::GetWindowContentRegionWidth(),
// 40)
// Opens a popup window when the button is clicked
ImGui::OpenPopup("Add Component Popup");
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
ImGui::SetNextWindowSize(ImVec2(240, 200));
// Create the popup window
if (ImGui::BeginPopup("Add Component Popup")) {
addComponentButton<MeshRenderComponent>("Mesh Render Component");
addComponentButton<TextureBindingComponent>(
"Texture Binding Component");
addComponentButton<CameraComponent>("Camera Component");
if (ImGui::BeginMenu("Scripts")) {
for (auto& script : ScriptEngine::getComponentScripts())
addScriptButton(script.first.c_str());
ImGui::EndMenu();
}
ImGui::EndPopup(); // End the popup
}
ImGui::PopStyleVar();
}
template <typename T>
inline bool PropertiesPanel::collapsingComponentHeader(
const std::string& componentName, bool canDelete) {
if (!ActiveEntity::shareComponent<T>()) return false;
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_CollapsingHeader |
ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_OpenOnArrow;
bool collapsingHeader = ActiveEntity::shareComponent<T>() &&
ImGui::TreeNodeEx(componentName.c_str(), flags);
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::OpenPopup(componentName.c_str());
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopup(componentName.c_str())) {
if (ImGui::Selectable("reset")) {
for (auto& entity : ActiveEntity::entities)
entity->getComponent<T>() = T();
ImGui::CloseCurrentPopup();
}
if (canDelete && ImGui::Selectable("delete")) {
for (auto& entity : ActiveEntity::entities)
entity->removeComponent<T>();
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return false;
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
return collapsingHeader;
}
void PropertiesPanel::addScriptButton(const std::string& scriptID) {
ImGuiSelectableFlags selectableFlag =
(ActiveEntity::shareComponent<ScriptComponent>())
? ImGuiSelectableFlags_Disabled
: ImGuiSelectableFlags_None;
if (ImGui::Selectable(scriptID.c_str(), false, selectableFlag)) {
for (auto& entity : ActiveEntity::entities) {
if (!entity->hasComponent<ScriptComponent>())
entity->addComponent<ScriptComponent>(scriptID);
}
ImGui::CloseCurrentPopup();
}
}
template <typename T>
void PropertiesPanel::addComponentButton(
const std::string& componentName) {
ImGuiSelectableFlags selectableFlag =
(ActiveEntity::shareComponent<T>()) ? ImGuiSelectableFlags_Disabled
: ImGuiSelectableFlags_None;
if (ImGui::Selectable(componentName.c_str(), false, selectableFlag)) {
for (auto& entity : ActiveEntity::entities) {
if (!entity->hasComponent<T>()) entity->addComponent<T>();
}
ImGui::CloseCurrentPopup();
}
}
} // namespace Deer

View File

@ -1,10 +0,0 @@
#pragma once
#include "Deer/Memory.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Editor/EditorPanel.h"
namespace Deer {
namespace PropertiesPanel {
void onImgui();
} // namespace PropertiesPanel
} // namespace Deer

View File

@ -1,294 +0,0 @@
#include "SceneExplorer.h"
#include <regex>
#include <string>
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Path.h"
#include "Deer/Scene.h"
#include "DeerRender/Render/Texture.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Project.h"
#include "EditorUtils.h"
#include "Icons.h"
#include "imgui.h"
namespace Deer {
Path m_currentScenePath("null");
Path m_currentSceneName;
Path m_loadSceneName;
Path m_deleteSceneName;
Path m_dialogSceneName;
void drawSceneExplorerFolder(const Path& path);
void drawSceneExplorerScene(const Path& path);
void saveSceneBeforeLoadingPopup();
void sceneDialogPopup();
void saveSceneName(const std::string&);
void createFolderName(const std::string& name);
void saveBeforeCreatingNew(bool save);
void saveSceneNameBeforeCreatingNew(const std::string& name);
void deleteScene();
void openFileExplorer(const std::string& relativePath);
void sceneExplorer_onImGUI() {
if (m_currentScenePath == "null")
m_currentScenePath = DataStore::rootPath / DEER_SCENE_PATH;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 10));
ImGui::Begin("Scene Explorer", (bool*)0, ImGuiWindowFlags_MenuBar);
ImGui::PopStyleVar();
if (ImGui::BeginMenuBar()) {
if (ImGui::MenuItem("Save")) {
if (m_currentSceneName == "")
ImGui::OpenPopup("SAVE_SCENE_NAME");
else
DataStore::exportScene(Project::m_scene,
m_currentSceneName);
}
if (ImGui::MenuItem("Save as")) {
ImGui::OpenPopup("SAVE_SCENE_NAME");
}
if (ImGui::MenuItem("New Scene")) {
ImGui::OpenPopup("SAVE_SCENE_BEFORE_CREATING_NEW");
}
if (ImGui::MenuItem("New folder")) {
ImGui::OpenPopup("CREATE_SCENE_FOLDER");
}
if (ImGui::MenuItem("Explorer")) {
openFileExplorer(m_currentScenePath.generic_string());
}
stringInputPopup<saveSceneName>("SAVE_SCENE_NAME", "Scene name");
stringInputPopup<createFolderName>("CREATE_SCENE_FOLDER",
"Folder name");
saveInputPopup<saveBeforeCreatingNew>(
"SAVE_SCENE_BEFORE_CREATING_NEW",
"Do you want to save the scene before creating new?");
stringInputPopup<saveSceneNameBeforeCreatingNew>(
"SAVE_SCENE_NAME_CREATE_NEW", "Scene name");
ImGui::EndMenuBar();
}
ImGui::Text("%s", m_currentScenePath.generic_string().c_str());
ImGui::TextDisabled("Active Scene : ");
ImGui::SameLine();
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.7f, 1), "%s",
m_currentSceneName.generic_string().c_str());
setupColumns(ICON_MIN_SIZE + 80);
if (m_currentScenePath != DEER_SCENE_PATH) {
drawSceneExplorerFolder("..");
float cursorOffset =
(ICON_MIN_SIZE - ImGui::CalcTextSize("..").x) / 2;
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x,
ImGui::GetCursorPos().y));
ImGui::Text("..");
ImGui::NextColumn();
}
for (const auto& entry :
std::filesystem::directory_iterator(m_currentScenePath)) {
if (entry.is_directory())
drawSceneExplorerFolder(entry.path());
else {
std::string extension =
entry.path().filename().extension().string();
if (extension != ".dscn") continue;
Path sceneName = entry.path().parent_path().lexically_relative(
DEER_SCENE_PATH) /
entry.path().stem();
drawSceneExplorerScene(sceneName);
}
float cursorOffset =
(ICON_MIN_SIZE -
ImGui::CalcTextSize(entry.path().stem().string().c_str()).x) /
2;
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x,
ImGui::GetCursorPos().y));
ImGui::Text("%s", entry.path().stem().string().c_str());
ImGui::NextColumn();
}
ImGui::Columns();
saveSceneBeforeLoadingPopup();
sceneDialogPopup();
deleteInputPopup<deleteScene>(
"DELETE_SCENE", "Are you sure you want to delete the scene?");
ImGui::End();
}
void drawSceneExplorerFolder(const Path& path) {
ImGui::Image((void*)(uint64_t)Icons::folder_icon->getTextureID(),
ImVec2(ICON_MIN_SIZE, ICON_MIN_SIZE), ImVec2(0, 1),
ImVec2(1, 0));
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
if (path == "..")
m_currentScenePath = m_currentScenePath.parent_path();
else
m_currentScenePath = path;
}
}
void drawSceneExplorerScene(const Path& path) {
ImGui::Image((void*)(uint64_t)Icons::scene_icon->getTextureID(),
ImVec2(ICON_MIN_SIZE, ICON_MIN_SIZE), ImVec2(0, 1),
ImVec2(1, 0));
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
ImGui::OpenPopup("SAVE_SCENE_BEFORE_LOADING");
m_loadSceneName = path;
}
if (ImGui::IsItemClicked(1)) {
ImGui::OpenPopup("SCENE_DIALOG");
m_dialogSceneName = path;
}
}
std::string sanitizeInput(const std::string& input) {
std::string sanitized;
for (char c : input) {
if (isalnum(c) || c == '_') {
sanitized += c;
}
}
return sanitized;
}
void saveSceneBeforeLoadingPopup() {
if (ImGui::BeginPopup("SAVE_SCENE_BEFORE_LOADING")) {
if (m_currentSceneName == "") {
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
}
ImGui::Text("Do you want to save the current scene?");
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(100, 255, 120, 255));
bool save = ImGui::Button("Save");
ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 100, 120, 255));
ImGui::SameLine();
bool dont_save = ImGui::Button("Don't save");
ImGui::PopStyleColor();
ImGui::SameLine();
bool cancel = ImGui::Button("Cancel");
if (save) {
ActiveEntity::clear();
DataStore::exportScene(Project::m_scene, m_currentSceneName);
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
} else if (dont_save) {
ActiveEntity::clear();
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
}
if (cancel) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void sceneDialogPopup() {
if (ImGui::BeginPopup("SCENE_DIALOG")) {
if (ImGui::MenuItem("Rename Scene")) {
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Delete Scene")) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::OpenPopup("DELETE_SCENE");
m_deleteSceneName = m_dialogSceneName;
return;
}
ImGui::EndPopup();
}
}
// Implement delete scene
void deleteScene() {}
void createFolderName(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
DataStore::createFolder(m_currentScenePath / correctInput);
}
}
void saveSceneName(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
Path fullName;
if (m_currentScenePath == DEER_SCENE_PATH)
fullName = correctInput;
else
fullName =
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
correctInput;
m_currentSceneName = fullName;
DataStore::exportScene(Project::m_scene, fullName);
}
}
void saveBeforeCreatingNew(bool save) {
if (save) {
if (m_currentSceneName == "") {
ImGui::OpenPopup("SAVE_SCENE_NAME_CREATE_NEW");
return;
} else {
ActiveEntity::clear();
DataStore::exportScene(Project::m_scene, m_currentSceneName);
Project::m_scene.clear();
m_currentSceneName = Path();
}
} else {
ActiveEntity::clear();
Project::m_scene.clear();
m_currentSceneName = Path();
}
}
void saveSceneNameBeforeCreatingNew(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
Path fullName;
if (m_currentScenePath == DEER_SCENE_PATH)
fullName = correctInput;
else
fullName =
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
correctInput;
DataStore::exportScene(Project::m_scene, fullName);
ActiveEntity::clear();
Project::m_scene.clear();
m_currentSceneName = Path();
}
}
} // namespace Deer

View File

@ -1,5 +0,0 @@
#pragma once
namespace Deer {
void sceneExplorer_onImGUI();
}

View File

@ -10,7 +10,6 @@
#include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "imgui.h"
@ -24,7 +23,7 @@ namespace Deer {
void TerrainEditor::onImGui() {
ImGui::Begin("Terrain Editor");
if (!Project::m_scene.isVoxelWorldInitialized()) {
if (!VoxelWorld::isInitialized()) {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1),
"No voxel world created");
ImGui::Separator();
@ -38,7 +37,6 @@ namespace Deer {
return;
}
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
ImGui::Text("Edit mode: ");
setupColumns(ICON_BTN_MIN_SIZE + 16);

View File

@ -7,7 +7,6 @@
#include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "imgui.h"
namespace Deer {
@ -59,8 +58,7 @@ namespace Deer {
} else {
selectedVoxelEnd = voxelRayCoords;
}
Project::m_scene.getVoxelWorld()
.getVoxelWorldProps()
VoxelWorld::getWorldProps()
.clampCordinates(selectedVoxelEnd);
}
@ -75,8 +73,7 @@ namespace Deer {
}
void TerrainEditor::boxSelect_Visuals() {
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
GizmoRenderer& gizmo = Project::m_scene.getMainGizmoRenderer();
GizmoRenderer& gizmo = Scene::gizmoRenderer;
if (!selectedVoxelStart.isNull() && !selectedVoxelEnd.isNull()) {
VoxelCordinates min;

View File

@ -4,7 +4,6 @@
#include "Deer/Voxel.h"
#include "Deer/VoxelWorld.h"
#include "DeerRender/LightVoxel.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "imgui.h"
@ -83,8 +82,8 @@ namespace Deer {
props.chunkSizeY = values[1];
props.chunkSizeZ = values[2];
Project::m_scene.createVoxelWorld(props);
Project::m_scene.getVoxelWorld().fillVoxels(
VoxelWorld::initialize(props);
VoxelWorld::fillVoxels(
VoxelCordinates(0, 0, 0), VoxelCordinates(31, 8, 31),
Voxel(DataStore::getVoxelID("wood")));

View File

@ -5,7 +5,6 @@
#include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "imgui.h"
@ -18,7 +17,7 @@ namespace Deer {
selectVoxel = voxelRayCoords;
clampedCordinates = selectVoxel;
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampCordinates(
VoxelWorld::getWorldProps().clampCordinates(
clampedCordinates);
if (clampedCordinates != selectVoxel) return;
@ -32,8 +31,7 @@ namespace Deer {
max = VoxelCordinates(selectVoxel.x + 15, selectVoxel.y + 15,
selectVoxel.z + 15);
}
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampAndSetMinMax(
min, max);
VoxelWorld::getWorldProps().clampAndSetMinMax(min, max);
if (selectVoxel.x < min.x || selectVoxel.x > max.x ||
selectVoxel.y < min.y || selectVoxel.y > max.y ||
@ -41,15 +39,15 @@ namespace Deer {
return;
for (int i = 0; i < 6; i++) {
Project::m_scene.getMainGizmoRenderer().drawVoxelFace(
Scene::gizmoRenderer.drawVoxelFace(
clampedCordinates.x, clampedCordinates.y, clampedCordinates.z,
DataStore::getVoxelID("debug"), i, 0);
}
if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) {
Voxel voxel =
Project::m_scene.getVoxelWorld().readVoxel(selectVoxel);
Project::m_scene.getVoxelWorld().remplaceVoxels(min, max, voxel,
VoxelWorld::readVoxel(selectVoxel);
VoxelWorld::remplaceVoxels(min, max, voxel,
Voxel(0));
}
}

View File

@ -5,7 +5,6 @@
#include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "imgui.h"
@ -52,7 +51,7 @@ namespace Deer {
}
clampedCordinates = selectVoxel;
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampCordinates(
VoxelWorld::getWorldProps().clampCordinates(
clampedCordinates);
if (clampedCordinates != selectVoxel) return;
@ -66,7 +65,7 @@ namespace Deer {
max = VoxelCordinates(selectVoxel.x + 15, selectVoxel.y + 15,
selectVoxel.z + 15);
}
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampAndSetMinMax(
VoxelWorld::getWorldProps().clampAndSetMinMax(
min, max);
if (selectVoxel.x < min.x || selectVoxel.x > max.x ||
@ -75,15 +74,15 @@ namespace Deer {
return;
for (int i = 0; i < 6; i++) {
Project::m_scene.getMainGizmoRenderer().drawVoxelFace(
Scene::gizmoRenderer.drawVoxelFace(
clampedCordinates.x, clampedCordinates.y, clampedCordinates.z,
selectedVoxelID, i, 0);
}
if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) {
Voxel voxel =
Project::m_scene.getVoxelWorld().readVoxel(selectVoxel);
Project::m_scene.getVoxelWorld().remplaceVoxels(
VoxelWorld::readVoxel(selectVoxel);
VoxelWorld::remplaceVoxels(
min, max, voxel, Voxel(selectedVoxelID));
}
}

View File

@ -5,7 +5,6 @@
#include "Deer/VoxelWorld.h"
#include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "imgui.h"
@ -15,8 +14,7 @@ namespace Deer {
}
void TerrainEditor::info() {
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
VoxelWorldProps worldProps = voxelWorld.getVoxelWorldProps();
VoxelWorldProps worldProps = VoxelWorld::getWorldProps();
ImGui::Text("Voxel world chunk and voxel size:");
ImGui::Text(
@ -75,13 +73,13 @@ namespace Deer {
// TEMP
if (ImGui::Button("Create Ceiling")) {
Project::m_scene.getVoxelWorld().fillVoxels(
VoxelWorld::fillVoxels(
VoxelCordinates(),
VoxelCordinates(32 * worldProps.chunkSizeX - 1, 16,
32 * worldProps.chunkSizeZ - 1),
Voxel(DataStore::getVoxelID("wood")));
Project::m_scene.getVoxelWorld().fillVoxels(
VoxelWorld::fillVoxels(
VoxelCordinates(1, 8, 1),
VoxelCordinates(32 * worldProps.chunkSizeX - 2, 15,
32 * worldProps.chunkSizeZ - 2),
@ -94,6 +92,6 @@ namespace Deer {
}
void TerrainEditor::deleteVoxelWorld() {
Project::m_scene.deleteVoxelWorld();
VoxelWorld::clear();
}
} // namespace Deer

View File

@ -3,7 +3,6 @@
#include "Deer/VoxelWorld.h"
#include "DeerRender/SceneCamera.h"
#include "DeerStudio/Editor/Viewport.h"
#include "DeerStudio/Project.h"
#include "TerrainEditor.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
@ -42,7 +41,7 @@ namespace Deer {
glm::vec3 rayDir = farPoint - nearPoint;
rayDir = glm::normalize(rayDir);
VoxelRayResult res = Project::m_scene.getVoxelWorld().rayCast_editor(
VoxelRayResult res = VoxelWorld::rayCast_editor(
viewport_sceneCamera.transform.position, rayDir, 50);
voxelRayCoords.makeNull();
@ -53,13 +52,13 @@ namespace Deer {
VoxelCordinates(res.hitPos.x + NORMAL_DIR(0, res.face),
res.hitPos.y + NORMAL_DIR(1, res.face),
res.hitPos.z + NORMAL_DIR(2, res.face));
Project::m_scene.getMainGizmoRenderer().drawVoxelLineFace(
Scene::gizmoRenderer.drawVoxelLineFace(
res.hitPos.x, res.hitPos.y, res.hitPos.z, res.face);
if (viewport_isActive && ImGui::GetMouseClickedCount(0) > 0) {
if (terrainEditMode == TerrainEditMode_Substract) {
if (res.hitPos.y >= 0) {
Project::m_scene.getVoxelWorld().setVoxel(res.hitPos,
VoxelWorld::setVoxel(res.hitPos,
emptyVoxel);
}
} else if (terrainEditMode == TerrainEditMode_Add) {
@ -68,7 +67,7 @@ namespace Deer {
res.hitPos.y + NORMAL_DIR(1, res.face),
res.hitPos.z + NORMAL_DIR(2, res.face));
Project::m_scene.getVoxelWorld().setVoxel(
VoxelWorld::setVoxel(
position, Voxel(selectedVoxelID));
}
}

View File

@ -1,260 +0,0 @@
#include "TreePanel.h"
#include "Deer/Enviroment.h"
#include "Deer/Scene.h"
#include "DeerRender/Input.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Project.h"
#include "imgui.h"
namespace Deer {
namespace TreePanel {
void updateEntity(Entity& entity);
void updateReciveDragPayload(Entity& entity);
bool updateDragPayload(Entity* entity, const std::string& name);
void updateContextMenu();
void clickEntity(Entity& entity);
bool m_isRightClickHandled;
Entity* m_contextMenuEntity = nullptr;
} // namespace TreePanel
void TreePanel::onImgui() {
ImGui::Begin("Tree Panel", (bool*)0, ImGuiWindowFlags_MenuBar);
m_isRightClickHandled = false;
Entity& root = Project::m_scene.getMainEnviroment().getRoot();
if (!m_contextMenuEntity) m_contextMenuEntity = &root;
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("New")) {
if (ImGui::MenuItem("Entity")) {
Entity& entity =
Project::m_scene.getMainEnviroment().createEntity(
"new entity");
entity.setParent(root);
}
if (ImGui::MenuItem("Camera")) {
Entity& entity =
Project::m_scene.getMainEnviroment().createEntity(
"new camera");
entity.addComponent<CameraComponent>();
entity.setParent(root);
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
RelationshipComponent& relation =
Project::m_scene.getMainEnviroment()
.getRoot()
.getComponent<RelationshipComponent>();
updateEntity(Project::m_scene.getMainEnviroment().getRoot());
// for (int i = 0; i < relation.childCount; i++) {
// Entity& childEntity =
// Project::m_scene.getMainEnviroment().getEntity(
// relation.getChildrenId(i));
// }
ImGui::PopStyleVar();
updateContextMenu();
ImGui::Spacing();
ImVec2 spaceSize(ImGui::GetWindowContentRegionWidth(), 80);
ImGui::InvisibleButton("DragDropSpace", spaceSize);
updateReciveDragPayload(root);
if (!m_isRightClickHandled &&
ImGui::IsWindowHovered(
ImGuiHoveredFlags_AllowWhenBlockedByPopup |
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
ImGui::IsMouseClicked(ImGuiMouseButton_Right) &&
!ImGui::IsAnyItemHovered()) {
m_contextMenuEntity = &root;
ImGui::OpenPopup("Entity Context Menu");
}
updateReciveDragPayload(root);
ImGui::End();
}
void TreePanel::updateEntity(Entity& entity) {
auto& tag = entity.getComponent<TagComponent>();
auto& relationship = entity.getComponent<RelationshipComponent>();
std::string name = (tag.tag == "") ? "-" : tag.tag;
const void* entityID = reinterpret_cast<const void*>(
static_cast<uintptr_t>(entity.getId()));
ImGui::Spacing();
// End of the tree
if (relationship.childCount == 0 && !entity.isRoot()) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth;
if (ActiveEntity::contains(entity))
flags |= ImGuiTreeNodeFlags_Selected;
ImGui::TreeNodeEx(entityID, flags, "%s", name.c_str());
if (!updateDragPayload(&entity, tag.tag))
updateReciveDragPayload(entity);
clickEntity(entity);
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
m_contextMenuEntity = &entity;
m_isRightClickHandled = true;
ImGui::OpenPopup("Entity Context Menu");
}
return;
}
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth;
if (ActiveEntity::contains(entity))
flags |= ImGuiTreeNodeFlags_Selected;
// for the moment i prefer to default open all
flags |= ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(entityID, flags, "%s", name.c_str())) {
if (!entity.isRoot()) updateDragPayload(&entity, tag.tag);
updateReciveDragPayload(entity);
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
m_contextMenuEntity = &entity;
m_isRightClickHandled = true;
ImGui::OpenPopup("Entity Context Menu");
}
clickEntity(entity);
RelationshipComponent& rc =
entity.getComponent<RelationshipComponent>();
for (int i = 0; i < rc.childCount; i++) {
uint16_t childID = rc.getChildrenId(i);
Entity& childEntity =
m_contextMenuEntity->getEnvironment()->getEntity(childID);
updateEntity(childEntity);
}
updateContextMenu();
ImGui::TreePop();
} else {
clickEntity(entity);
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
m_contextMenuEntity = &entity;
m_isRightClickHandled = true;
ImGui::OpenPopup("Entity Context Menu");
}
if (!entity.isRoot()) updateDragPayload(&entity, tag.tag);
updateReciveDragPayload(entity);
}
}
void TreePanel::updateReciveDragPayload(Entity& entity) {
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("_ENTITY")) {
Entity* receivedData = *(Entity**)payload->Data;
if (!entity.isDescendantOf(*receivedData))
receivedData->setParent(entity);
}
ImGui::EndDragDropTarget();
}
}
bool TreePanel::updateDragPayload(Entity* entity,
const std::string& name) {
if (!ImGui::BeginDragDropSource()) return false;
ImGui::SetDragDropPayload("_ENTITY", &entity, sizeof(Entity*));
ImGui::Text("%s", name.c_str());
ImGui::EndDragDropSource();
return true;
}
void TreePanel::clickEntity(Entity& entity) {
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) ||
Input::isKeyPressed(DEER_KEY_LEFT_ALT)))
ActiveEntity::clear();
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT))
ActiveEntity::removeEntity(entity);
else
ActiveEntity::addEntity(entity);
}
}
void TreePanel::updateContextMenu() {
bool callRename = false;
if (ImGui::BeginPopup("Entity Context Menu")) {
if (ImGui::MenuItem("New Entity")) {
Entity& entity =
Project::m_scene.getMainEnviroment().createEntity(
"new entity");
entity.setParent(*m_contextMenuEntity);
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("New Camera")) {
Entity& entity =
Project::m_scene.getMainEnviroment().createEntity(
"new camera");
entity.addComponent<CameraComponent>();
entity.setParent(*m_contextMenuEntity);
ImGui::CloseCurrentPopup();
}
if (!m_contextMenuEntity->isRoot() && ImGui::MenuItem("Delete")) {
m_contextMenuEntity->destroy();
ActiveEntity::clear();
ImGui::CloseCurrentPopup();
}
if (!m_contextMenuEntity->isRoot() && ImGui::MenuItem("Rename")) {
callRename = true;
ImGui::CloseCurrentPopup();
}
if (!m_contextMenuEntity->isRoot() &&
ImGui::MenuItem("Duplicate")) {
m_contextMenuEntity->duplicate();
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
if (callRename) ImGui::OpenPopup("Rename Entity Menu");
if (ImGui::BeginPopup("Rename Entity Menu")) {
std::string& name =
m_contextMenuEntity->getComponent<TagComponent>().tag;
char nameBuffer[256];
std::strncpy(nameBuffer, name.c_str(), sizeof(nameBuffer) - 1);
ImGui::Text("Rename");
if (ImGui::InputText("##", nameBuffer, 256,
ImGuiInputTextFlags_EnterReturnsTrue)) {
m_contextMenuEntity->getComponent<TagComponent>().tag =
nameBuffer;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
} // namespace Deer

View File

@ -1,7 +0,0 @@
#pragma once
namespace Deer {
namespace TreePanel {
void onImgui();
}
}

View File

@ -11,7 +11,6 @@
#include "DeerRender/Input.h"
#include "DeerRender/Render/FrameBuffer.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Project.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
@ -94,7 +93,7 @@ namespace Deer {
viewport_relativeXMouse = (mPos.x - wPos.x) / windowSize.x;
viewport_relativeYMouse = 1 - (mPos.y - wPos.y) / windowSize.y;
Project::m_scene.render(viewport_sceneCamera);
Scene::render(viewport_sceneCamera);
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0),
windowSize, ImVec2(0, 1), ImVec2(1, 0));
@ -119,7 +118,7 @@ namespace Deer {
if (id >= 0) {
Entity& selectedEntity =
Project::m_scene.getMainEnviroment().getEntity(
Scene::environment.getEntity(
(uint32_t)id);
ActiveEntity::addEntity(selectedEntity);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "DeerStudio/EditorEngine/API/Debug.h"
#include "DeerStudio/EditorEngine/API/Entity.h"
#include "DeerStudio/EditorEngine/API/Layout.h"
#include "DeerStudio/EditorEngine/API/Menu.h"
#include "DeerStudio/EditorEngine/API/Resource.h"
#include "DeerStudio/EditorEngine/API/UI.h"
#include "DeerStudio/EditorEngine/API/Math.h"

View File

@ -1,4 +1,4 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine/API/Debug.h"
#include "Deer/Log.h"
#include "angelscript.h"
@ -12,6 +12,8 @@ namespace Deer {
DEER_UI_ENGINE_WARN("{0}:{1}:{2}) : {3}", msg->section, msg->row, msg->col, msg->message);
} else if( msg->type == asMSGTYPE_INFORMATION ) {
DEER_UI_ENGINE_ERROR("{0}:{1}:{2}) : {3}", msg->section, msg->row, msg->col, msg->message);
} else if (msg->type == asMSGTYPE_INFORMATION){
DEER_UI_ENGINE_TRACE("{0}:{1}:{2}) : {3}", msg->section, msg->row, msg->col, msg->message);
}
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <string>
class asSMessageInfo;
namespace Deer {
namespace EditorEngine {
void errorCallback(const asSMessageInfo *msg, void *param);
// Prints in console a mesage
void print(std::string& msg);
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <string>
namespace Deer {
namespace EditorEngine {
// TO IMPLEMENT
bool button(std::string&);
}
}

View File

@ -1,12 +0,0 @@
#pragma once
namespace Deer {
namespace EditorEngine {
// Set up the colums to fit the pixelSize elements
void setupAutomaticColumns(int pixelSize);
// Iterates to the next column
void nextColumn();
// Ends the columns made with setupColumns
void endColumns();
}
}

View File

@ -1,24 +0,0 @@
#pragma once
#include <stdint.h>
#include <string>
namespace Deer {
namespace EditorEngine {
struct EntityStruct {
EntityStruct(uint16_t entId) : entityId(entId) { }
uint16_t entityId;
int getChildCount();
EntityStruct getChild(int);
std::string getName();
int getId();
};
EntityStruct getRoot();
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);
}
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "DeerStudio/EditorEngine/API/EditorEngine_Button.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Column.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Directory.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Icon.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Input.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Text.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_MenuBar.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h"
#include <string>
class asSMessageInfo;
namespace Deer {
namespace EditorEngine {
void errorCallback(const asSMessageInfo *msg, void *param);
// Prints in console a mesage
void print(std::string& msg);
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <string>
namespace Deer {
namespace EditorEngine {
void drawIcon(std::string& iconId, int size);
void drawIconCentered(std::string& iconId, int size);
}
}

View File

@ -1,11 +0,0 @@
#pragma once
namespace Deer {
namespace EditorEngine {
// Returns if the specified mouse button is clicked on the last element
bool isMouseClicked(int mouse);
// Returns if the specified mouse button is double clicked
bool isMouseDoubleClicked(int mouse);
}
}

View File

@ -1,8 +0,0 @@
#pragma once
#include <string>
namespace Deer {
namespace EditorEngine {
bool menuItem(std::string&);
}
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <string>
namespace Deer {
namespace EditorEngine {
}
}

View File

@ -1,17 +0,0 @@
#pragma once
#include <string>
namespace Deer {
namespace EditorEngine {
// Renders a text with the defined rgb values from range [0.0, 1.0]
void textColor(float r, float g, float b, std::string& msg);
// Renders a text
void text(std::string& msg);
// Renders a text
void textCentered(std::string& msg);
}
}

View File

@ -1,12 +0,0 @@
#pragma once
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace EditorEngine {
void treeNode(std::string&, int);
void treeNodeRecursive(std::string&, int, CScriptAny*, asIScriptFunction&);
}
}

View File

@ -0,0 +1,141 @@
#include "DeerStudio/EditorEngine/API/Entity.h"
#include "Deer/Enviroment.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "Deer/Scene.h"
#define GET_ENTITY(id) Scene::environment.getEntity(id)
namespace Deer {
namespace EditorEngine {
EntityStruct activeEntity;
EntityStruct getRoot() {
return EntityStruct(0);
}
void constructEntityStruct(int id, void* memory) {
new (memory)EntityStruct(id);
}
int EntityStruct::getId() {
return entityId;
}
std::string EntityStruct::getName() {
return GET_ENTITY(entityId)
.getComponent<TagComponent>()
.tag;
}
void EntityStruct::setName(std::string& name) {
GET_ENTITY(entityId)
.getComponent<TagComponent>()
.tag = name;
}
void EntityStruct::destroy() {
GET_ENTITY(entityId)
.destroy();
}
bool EntityStruct::isRoot() {
return entityId == 0;
}
bool EntityStruct::exists() {
return Scene::environment
.entityExists(entityId);
}
void EntityStruct::setParent(EntityStruct parent_struct) {
Entity& parent = GET_ENTITY(parent_struct.entityId);
GET_ENTITY(entityId)
.setParent(parent);
}
EntityStruct EntityStruct::getParent() {
Entity& self = GET_ENTITY(entityId);
if (self.isRoot())
return *this;
return EntityStruct(self.getParentId());
}
EntityStruct getParent();
bool EntityStruct::isDescendantOf(EntityStruct parent_struct) {
Entity& parent = GET_ENTITY(parent_struct.entityId);
return GET_ENTITY(entityId)
.isDescendantOf(parent);
}
bool EntityStruct::opEquals(const EntityStruct& other) {
return entityId == other.entityId;
}
EntityStruct EntityStruct::getSelf() {
return *this;
}
glm::vec3 TransformComponentStruct::getPosition() {
return GET_ENTITY(entityId).getComponent<TransformComponent>().position;
}
glm::vec3 TransformComponentStruct::getScale() {
return GET_ENTITY(entityId).getComponent<TransformComponent>().scale;
}
glm::vec3 TransformComponentStruct::getRotation() {
return GET_ENTITY(entityId).getComponent<TransformComponent>().getEulerAngles();
}
void TransformComponentStruct::setPosition(glm::vec3 value) {
GET_ENTITY(entityId).getComponent<TransformComponent>().position = value;
}
void TransformComponentStruct::setScale(glm::vec3 value) {
GET_ENTITY(entityId).getComponent<TransformComponent>().scale = value;
}
void TransformComponentStruct::setRotation(glm::vec3 value) {
GET_ENTITY(entityId).getComponent<TransformComponent>().setEulerAngles(value);
}
int EntityChildArrayStruct::getChildCount() {
return GET_ENTITY(entityId)
.getComponent<RelationshipComponent>()
.childCount;
}
EntityStruct EntityChildArrayStruct::getChild(int i) {
RelationshipComponent& rc = GET_ENTITY(entityId)
.getComponent<RelationshipComponent>();
if (i < 0 || i >= rc.childCount) {
DEER_UI_ENGINE_ERROR("Error while executing EntityChild.getChild(..), id {0} is invalid for child count of {1}", i, rc.childCount);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return EntityStruct(0);
}
return EntityStruct(rc.getChildrenId(i));
}
EntityStruct EntityStruct::createChild(std::string& name) {
Entity& me = GET_ENTITY(entityId);
Entity& newEnt = Scene::environment
.createEntity(name);
newEnt.setParent(me);
return EntityStruct(newEnt.getId());
}
}
}

View File

@ -0,0 +1,75 @@
#pragma once
#include <stdint.h>
#include <string>
#include "glm/glm.hpp"
namespace Deer {
namespace EditorEngine {
struct EntityStruct;
extern EntityStruct activeEntity;
// IN ANGEL SCRIPT IT LOOKS LIKE THIS
//class Entity {
// int id;
// string name;
//
// int childCount;
// bool isRoot;
//
// Entity parent;
// Entiy getChild(int);
// Entity createChild(int);
//
// void destroy();
// bool isDescendantOf
//
// bool ==
//}
struct EntityStruct {
EntityStruct(uint16_t entId = 0) : entityId(entId) { }
uint16_t entityId;
std::string getName();
void setName(std::string&);
int getId();
bool exists();
bool isRoot();
void destroy();
EntityStruct createChild(std::string&);
void setParent(EntityStruct parent);
EntityStruct getParent();
bool isDescendantOf(EntityStruct parent);
bool opEquals(const EntityStruct& other);
// This function can be adapted to get a specific transform since the data is the same
EntityStruct getSelf();
};
struct EntityChildArrayStruct : EntityStruct{
int getChildCount();
EntityStruct getChild(int);
};
struct TransformComponentStruct : EntityStruct {
glm::vec3 getPosition();
glm::vec3 getScale();
glm::vec3 getRotation();
void setPosition(glm::vec3);
void setScale(glm::vec3);
void setRotation(glm::vec3);
};
EntityStruct getRoot();
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);
void registerEntityStructs();
void registerEntityFunctions();
}
}

View File

@ -0,0 +1,200 @@
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/API.h"
#include "scripthandle.h"
#include "scriptany.h"
#include "angelscript.h"
namespace Deer {
namespace EditorEngine {
void registerEntityStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | 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(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectType("TransformComponent", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
}
void registerEntityFunctions() {
// ENTITY
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"string get_name() const property",
asMETHOD(EntityStruct, getName),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"void set_name(string& in) property",
asMETHOD(EntityStruct, setName),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"int get_id() const property",
asMETHOD(EntityStruct, getId),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"Entity createChild(const string& in)",
asMETHOD(EntityStruct, createChild),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"bool get_isRoot() const property",
asMETHOD(EntityStruct, isRoot),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"void destroy()",
asMETHOD(EntityStruct, destroy),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"bool get_exists() const property",
asMETHOD(EntityStruct, exists),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"Entity get_parent() property",
asMETHOD(EntityStruct, getParent),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"void set_parent(Entity) property",
asMETHOD(EntityStruct, setParent),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"bool isDescendantOf(Entity)",
asMETHOD(EntityStruct, isDescendantOf),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"bool opEquals(const Entity &in) const",
asMETHOD(EntityStruct, opEquals),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"EntityChilds get_childs() const property",
asMETHOD(EntityStruct, getSelf),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"TransformComponent get_transform() const property",
asMETHOD(EntityStruct, getSelf),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"Entity getRoot()",
asFUNCTION(getRoot),
asCALL_CDECL
));
// ENTITY CHILD
AS_CHECK(scriptEngine->RegisterObjectMethod(
"EntityChilds",
"int get_count() const property",
asMETHOD(EntityChildArrayStruct, getChildCount),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"EntityChilds",
"Entity opIndex(int) const",
asMETHOD(EntityChildArrayStruct, getChild),
asCALL_THISCALL
));
// TRANSFORM COMPONENT
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"vec3 get_position() const property",
asMETHOD(TransformComponentStruct, getPosition),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"vec3 get_scale() const property",
asMETHOD(TransformComponentStruct, getScale),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"vec3 get_rotation() const property",
asMETHOD(TransformComponentStruct, getRotation),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"void set_position(const vec3) property",
asMETHOD(TransformComponentStruct, setPosition),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"void set_scale(const vec3) property",
asMETHOD(TransformComponentStruct, setScale),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"TransformComponent",
"void set_rotation(const vec3) property",
asMETHOD(TransformComponentStruct, setRotation),
asCALL_THISCALL
));
}
void registerTransformComponent() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour(
"Entity", asBEHAVE_CONSTRUCT, "void f(int)",
asFunctionPtr(constructEntityStruct),
asCALL_CDECL_OBJLAST
));
}
}
}

View File

@ -0,0 +1,137 @@
#include "DeerStudio/EditorEngine/API/Layout.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine.h"
#include "angelscript.h"
#include "scriptany.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void treeNode(std::string& txt, bool active) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
ImGui::TreeNodeEx(txt.c_str(), flags);
}
bool treeNodeRecursive(std::string& txt, bool active, CScriptAny *data, asIScriptFunction& func) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth |
ImGuiTreeNodeFlags_DefaultOpen;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::PushID(txt.c_str());
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Prepare(&func),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->SetArgObject(0, data),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Execute(),
func.GetDeclaration()
);
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar();
return true;
}
ImGui::PopStyleVar();
return false;
}
bool componentNode(std::string& txt, CScriptAny* data, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_AllowItemOverlap |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(txt.c_str(), flags)){
ImGui::Dummy(ImVec2(0, 10));
ImGui::PushID(txt.c_str());
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK( scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, data));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar(2);
return true;
}
ImGui::PopStyleVar(2);
return false;
}
void setupColumns(int i) {
ImGui::Columns(i, nullptr, false);
}
void setupAutomaticColumns(int pixelSize) {
float width = ImGui::GetWindowContentRegionWidth();
if (width < pixelSize) {
ImGui::Columns();
return;
}
int cols = (int)(width / (pixelSize));
float componentWidth = width / (float)cols;
ImGui::Columns(cols, 0, false);
}
void endColumns() {
ImGui::Columns();
}
void nextColumn() {
ImGui::NextColumn();
}
void space() {
ImGui::Dummy(ImVec2(10, 10));
}
}
}

View File

@ -0,0 +1,27 @@
#pragma once
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace EditorEngine {
// Set up the colums to fit the pixelSize elements
void setupAutomaticColumns(int pixelSize);
// Set up the colums to the number
void setupColumns(int);
// Iterates to the next column
void nextColumn();
// Ends the columns made with setupColumns
void endColumns();
// Renders a component node
bool componentNode(std::string&, CScriptAny*, asIScriptFunction*);
// Renders a tree leaf
void treeNode(std::string&, bool);
// Renders a tree node with its sub nodes
bool treeNodeRecursive(std::string&, bool, CScriptAny*, asIScriptFunction&);
void space();
}
}

View File

@ -0,0 +1,26 @@
#include "glm/glm.hpp"
#include "DeerStudio/EditorEngine/API/Math.h"
namespace Deer {
namespace EditorEngine {
void vec3_constructor(void* mem) {
new (mem) glm::vec3(0, 0, 0);
}
void vec3_constructor_params(float x, float y, float z, void* mem) {
new (mem) glm::vec3(x, y, z);
}
glm::vec3 vec3_add(glm::vec3& value, glm::vec3& self) {
return self + value;
}
glm::vec3 vec3_sub(const glm::vec3& value, glm::vec3& self) {
return self - value;
}
glm::vec3 vec3_neg(glm::vec3& self) {
return -self;
}
glm::vec3 vec3_mult(float value, glm::vec3& self) {
return self * value;
}
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "glm/glm.hpp"
namespace Deer {
namespace EditorEngine {
void vec3_constructor(void*);
void vec3_constructor_params(float, float, float, void*);
glm::vec3 vec3_add(glm::vec3&, glm::vec3&);
glm::vec3 vec3_sub(const glm::vec3&, glm::vec3&);
glm::vec3 vec3_neg(glm::vec3&);
glm::vec3 vec3_mult(float, glm::vec3&);
void registerMathStructs();
void registerMathFunctions();
}
}

View File

@ -0,0 +1,58 @@
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/API.h"
#include "scripthandle.h"
#include "scriptany.h"
#include "angelscript.h"
#include "glm/glm.hpp"
namespace Deer {
namespace EditorEngine {
void registerMathStructs() {
AS_CHECK(scriptEngine->RegisterObjectType(
"vec3",
sizeof(glm::vec3),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::vec3>() | asOBJ_APP_CLASS_ALLFLOATS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT,
"void f()", asFUNCTION(vec3_constructor), asCALL_CDECL_OBJLAST));
AS_CHECK(scriptEngine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT,
"void f(float, float = 0, float = 0)", asFUNCTION(vec3_constructor_params), asCALL_CDECL_OBJLAST));
AS_CHECK(scriptEngine->RegisterObjectProperty("vec3", "float x", asOFFSET(glm::vec3, x)));
AS_CHECK(scriptEngine->RegisterObjectProperty("vec3", "float y", asOFFSET(glm::vec3, y)));
AS_CHECK(scriptEngine->RegisterObjectProperty("vec3", "float z", asOFFSET(glm::vec3, z)));
}
void registerMathFunctions() {
AS_CHECK(scriptEngine->RegisterObjectMethod(
"vec3",
"vec3 opAdds(const vec3 &in)",
asFUNCTION(vec3_add),
asCALL_CDECL_OBJLAST
));
AS_CHECK(scriptEngine->RegisterObjectMethod("vec3",
"vec3 opSub(const vec3 &in) const",
asFUNCTION(vec3_sub),
asCALL_CDECL_OBJLAST
));
AS_CHECK(scriptEngine->RegisterObjectMethod("vec3",
"vec3 opNeg() const",
asFUNCTION(vec3_neg),
asCALL_CDECL_OBJLAST
));
AS_CHECK(scriptEngine->RegisterObjectMethod("vec3",
"vec3 opMul(float) const",
asFUNCTION(vec3_mult),
asCALL_CDECL_OBJLAST
));
}
}
}

View File

@ -0,0 +1,160 @@
#include "DeerStudio/EditorEngine/API/Menu.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine.h"
#include "angelscript.h"
#include "scriptany.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
namespace MenuContext {
CScriptAny* payload = nullptr;
std::string menuId;
}
void contextItemPopup(std::string& menu_id, CScriptAny* data, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextItem(menu_id.c_str())) {
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, data));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void contextMenuPopup(std::string& menu_id, CScriptAny* data, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextWindow(menu_id.c_str())) {
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, data));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void closePopup() {
if (MenuContext::payload) {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
MenuContext::menuId = "";
ImGui::CloseCurrentPopup();
}
void openPopup(std::string& menu_id, CScriptAny* data) {
if (MenuContext::payload) {
MenuContext::payload->Release();
}
data->AddRef();
MenuContext::payload = data;
MenuContext::menuId = menu_id;
}
void modalPopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup) && MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupModal(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, MenuContext::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void simplePopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup)) {
if (MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
ImVec2 mouse_pos = ImGui::GetMousePos();
ImVec2 popup_size = ImVec2(200, 0);
ImVec2 popup_pos = ImVec2(mouse_pos.x - popup_size.x * 0.5f, mouse_pos.y);
ImGui::SetNextWindowSize(popup_size);
ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing);
// In the case a payload is loaded we unload it
} else if (MenuContext::payload && MenuContext::menuId == "") {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopup(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, MenuContext::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace EditorEngine {
void contextItemPopup(std::string&, CScriptAny*, asIScriptFunction*);
void contextMenuPopup(std::string&, CScriptAny*, asIScriptFunction*);
void modalPopup(std::string&, asIScriptFunction*);
void simplePopup(std::string&, asIScriptFunction*);
void openPopup(std::string&, CScriptAny*);
void closePopup();
}
}

View File

@ -1,4 +1,4 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Directory.h"
#include "DeerStudio/EditorEngine/API/Resource.h"
#include "DeerStudio/EditorEngine.h"
#include "Deer/DataStore.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"

View File

@ -0,0 +1,345 @@
#include "DeerStudio/EditorEngine/API/UI.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine.h"
#include "Deer/Log.h"
#include "imgui.h"
#include "angelscript.h"
#include "scriptany.h"
#include "DeerStudio/Fonts.h"
#include <string>
namespace Deer {
namespace EditorEngine {
namespace DragDropPayload{
CScriptAny* payload;
}
void separator() {
ImGui::Separator();
}
void title(std::string& txt) {
ImGui::PushFont(titleText);
ImGui::Text("%s", txt.c_str());
ImGui::PopFont();
}
void titleEnd(std::string& txt) {
ImGui::PushFont(titleText);
textEnd(txt);
ImGui::PopFont();
}
void titleCenter(std::string& txt) {
ImGui::PushFont(titleText);
textCenter(txt);
ImGui::PopFont();
}
void sameLine() {
ImGui::SameLine();
}
bool button(std::string& txt) {
return ImGui::Button(txt.c_str());
}
bool buttonCenter(std::string& txt) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(txt.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth - ImGui::GetStyle().FramePadding.x * 2) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
return ImGui::Button(txt.c_str());
}
bool buttonEnd(std::string& txt) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(txt.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth - ImGui::GetStyle().FramePadding.x * 2);
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
return ImGui::Button(txt.c_str());
}
void textColor(float r, float g, float b, std::string& msg) {
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "%s", msg.c_str());
}
void text(std::string& msg) {
ImGui::Text("%s", msg.c_str());
}
void textEnd(std::string& msg) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(msg.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth);
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
ImGui::Text("%s", msg.c_str());
}
void textCenter(std::string& msg) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(msg.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
ImGui::Text("%s", msg.c_str());
}
void drawIcon(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
ImGui::Image((void*)(uint64_t)iconId,
ImVec2(size, size), ImVec2(0, 1),
ImVec2(1, 0));
}
void drawIconCentered(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float iconWidth = size;
float padding = (sizeX - iconWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
drawIcon(name, size);
}
bool isItemClicked(int mouse) {
return ImGui::IsItemClicked(mouse);
}
bool isMouseDoubleClicked(int mouse) {
return ImGui::IsMouseDoubleClicked(mouse);
}
bool menuItem(std::string& txt) {
return ImGui::MenuItem(txt.c_str());
}
void dragDropSource(std::string& id, CScriptAny* data, std::string& debugText) {
if (DragDropPayload::payload && !ImGui::GetDragDropPayload()) {
DragDropPayload::payload->Release();
DragDropPayload::payload = nullptr;
}
data->AddRef();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginDragDropSource()) {
if (DragDropPayload::payload)
DragDropPayload::payload->Release();
DragDropPayload::payload = data;
ImGui::SetDragDropPayload(id.c_str(), nullptr, 0);
ImGui::Text("%s", debugText.c_str());
ImGui::EndDragDropSource();
}
ImGui::PopStyleVar();
}
void dragDropTarget(std::string& id, CScriptAny* data, asIScriptFunction* func) {
if (ImGui::BeginDragDropTarget()) {
if (ImGui::AcceptDragDropPayload(id.c_str()) && DragDropPayload::payload) {
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, data));
AS_CHECK(scriptContext->SetArgObject(1, DragDropPayload::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
}
DragDropPayload::payload->Release();
DragDropPayload::payload = nullptr;
}
ImGui::EndDragDropTarget();
}
}
bool inputText(std::string& id, std::string& in, std::string& text) {
static char buffer[256];
strncpy(buffer, in.c_str(), sizeof(buffer));
buffer[sizeof(buffer) - 1] = '\0';
bool edited = ImGui::InputText(id.c_str(), buffer, sizeof(buffer));
if (edited) {
text = buffer;
}
return edited;
}
#include "imgui.h"
float magicSlider(std::string& txt, float value, float speed) {
ImGui::PushID(txt.c_str());
static ImGuiID id = 0;
float tmp = value;
bool value_changed = false;
ImGui::Text("%s", txt.c_str());
ImGui::SameLine();
if (id == ImGui::GetID(txt.c_str()))
{
// — Input mode —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputFloat("##input", &tmp, 0.0f, 0.0f, "%.2f",
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll))
{
value_changed = true;
id = 0;
}
// Cancel if click away or Esc
if (!ImGui::IsItemActive() && !ImGui::IsItemHovered()){
value_changed = true;
id = 0;
}
}
else
{
// — Drag mode (unbounded) —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::DragFloat("##input", &tmp, speed, 0.0f, 0.0f, "%.2f");
if (ImGui::IsItemActive())
value_changed = true;
// Click to enter edit mode
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
id = ImGui::GetID(txt.c_str());
ImGui::SetKeyboardFocusHere(0);
}
}
if (value_changed)
value = tmp;
ImGui::PopID();
return value;
}
glm::vec3 magicSlider3(std::string& txt, glm::vec3 value, float speed) {
static ImGuiID id = 0;
glm::vec3 tmp = value;
bool value_changed = false;
ImGui::Columns(4, nullptr, false);
ImGui::PushID(txt.c_str());
ImGui::Text("%s", txt.c_str());
ImGui::NextColumn();
for (int i = 0; i < 3; i++) {
ImGui::PushID(i);
if (id == ImGui::GetID("##input"))
{
// — Input mode —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputFloat("##input", &tmp[i], 0.0f, 0.0f, "%.2f",
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll))
{
value_changed = true;
id = 0;
}
// Cancel if click away or Esc
if (!ImGui::IsItemActive() && !ImGui::IsItemHovered()){
value_changed = true;
id = 0;
}
}
else
{
// — Drag mode (unbounded) —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::DragFloat("##input", &tmp[i], speed, 0.0f, 0.0f, "%.2f");
if (ImGui::IsItemActive())
value_changed = true;
// Click to enter edit mode
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
id = ImGui::GetID("##input");
ImGui::SetKeyboardFocusHere(-1);
}
}
ImGui::PopID();
ImGui::NextColumn();
}
ImGui::Columns();
ImGui::PopID();
if (value_changed)
value = tmp;
return value;
}
}
}

View File

@ -0,0 +1,65 @@
#pragma once
#include <string>
#include "glm/glm.hpp"
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace EditorEngine {
namespace DragDropPayload {
extern CScriptAny* payload;
}
// Renders the ui elements in the same line
void sameLine();
// Renders a line separator
void separator();
// Renders a button
bool button(std::string&);
// Renders a button at the end
bool buttonCenter(std::string&);
// Renders a button at the end
bool buttonEnd(std::string&);
// Renders a text
void text(std::string&);
// Renders a text
void textCenter(std::string&);
// Renders a text
void textEnd(std::string&);
// Renders a text with the defined rgb values from range [0.0, 1.0]
void textColor(float r, float g, float b, std::string& msg);
// Renders a big text
void title(std::string&);
// Renders a big text
void titleCenter(std::string&);
// Renders a big text
void titleEnd(std::string&);
// Renders a icon in the specified size in pixels
void drawIcon(std::string& iconId, int size);
// Renders a icon in the specified size in pixels at the center
void drawIconCentered(std::string& iconId, int size);
// Returns if the specified mouse button is clicked on the last element
bool isItemClicked(int mouse);
// Returns if the specified mouse button is double clicked
bool isMouseDoubleClicked(int mouse);
// Draws a button for a popup menu
bool menuItem(std::string&);
// Initializes the drag drop source with the id and the data you want to pass
void dragDropSource(std::string&, CScriptAny*, std::string&);
// Prepares the function to accept payload with the id and calls the function with the data
void dragDropTarget(std::string&, CScriptAny*, asIScriptFunction*);
bool inputText(std::string& label, std::string&, std::string&);
float magicSlider(std::string&, float, float);
glm::vec3 magicSlider3(std::string&, glm::vec3, float);
}
}

View File

@ -1,11 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Button.h"
#include "imgui.h"
#include <string>
namespace Deer {
namespace EditorEngine {
bool button(std::string& txt) {
return ImGui::Button(txt.c_str());
}
}
}

View File

@ -1,28 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Column.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void setupAutomaticColumns(int pixelSize) {
float width = ImGui::GetWindowContentRegionWidth();
if (width < pixelSize) {
ImGui::Columns();
return;
}
int cols = (int)(width / (pixelSize));
float componentWidth = width / (float)cols;
ImGui::Columns(cols, 0, false);
}
void endColumns() {
ImGui::Columns();
}
void nextColumn() {
ImGui::NextColumn();
}
}
}

View File

@ -1,55 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/Project.h"
#include "Deer/Enviroment.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "Deer/Scene.h"
namespace Deer {
namespace EditorEngine {
EntityStruct getRoot() {
return EntityStruct(0);
}
int EntityStruct::getChildCount() {
return Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<RelationshipComponent>()
.childCount;
}
EntityStruct EntityStruct::getChild(int i) {
RelationshipComponent& rc = Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<RelationshipComponent>();
if (i < 0 || i >= rc.childCount) {
DEER_UI_ENGINE_ERROR("Error while executing Entity.getChild(..), id {0} is invalid for child count of {1}", i, rc.childCount);
if (currentDockPanelExecution)
currentDockPanelExecution->invalidate();
return EntityStruct(0);
}
return EntityStruct(rc.getChildrenId(i));
}
void constructEntityStruct(int id, void* memory) {
new (memory)EntityStruct(id);
}
int EntityStruct::getId() {
return entityId;
}
std::string EntityStruct::getName() {
return Project::m_scene
.getMainEnviroment()
.getEntity(entityId)
.getComponent<TagComponent>()
.tag;
}
}
}

View File

@ -1,51 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Icon.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "Deer/Log.h"
#include "Deer/DataStore.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void drawIcon(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
ImGui::Image((void*)(uint64_t)iconId,
ImVec2(size, size), ImVec2(0, 1),
ImVec2(1, 0));
}
void drawIconCentered(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float iconWidth = size;
float padding = (sizeX - iconWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
drawIcon(name, size);
}
}
}

View File

@ -1,14 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Input.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
bool isMouseClicked(int mouse) {
return ImGui::IsItemClicked(mouse);
}
bool isMouseDoubleClicked(int mouse) {
return ImGui::IsMouseDoubleClicked(mouse);
}
}
}

View File

@ -1,10 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_MenuBar.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
bool menuItem(std::string& txt) {
return ImGui::MenuItem(txt.c_str());
}
}
}

View File

@ -1,8 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
namespace Deer {
namespace EditorEngine {
}
}

View File

@ -1,30 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Text.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void textColor(float r, float g, float b, std::string& msg) {
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "%s", msg.c_str());
}
void text(std::string& msg) {
ImGui::Text("%s", msg.c_str());
}
void textCentered(std::string& msg) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(msg.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
ImGui::Text("%s", msg.c_str());
}
}
}

View File

@ -1,52 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_TreeNode.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine.h"
#include "angelscript.h"
#include "scriptany.h"
#include "imgui.h"
namespace Deer {
namespace EditorEngine {
void treeNode(std::string& txt, int id) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth;
ImGui::TreeNodeEx((void*)(long long)id, flags, "%s", txt.c_str());
}
void treeNodeRecursive(std::string& txt, int id, CScriptAny *data, asIScriptFunction& func) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth;
if (ImGui::TreeNodeEx((void*)(long long)id, flags, "%s", txt.c_str())) {
ImGui::PushID(id);
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Prepare(&func),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->SetArgObject(0, data),
func.GetDeclaration()
);
AS_CHECK_ADDITIONAL_INFO(
scriptContext->Execute(),
func.GetDeclaration()
);
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::PopID();
ImGui::TreePop();
}
}
}
}

View File

@ -1,5 +1,5 @@
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine.h"
#include "Deer/Log.h"

View File

@ -1,6 +1,7 @@
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/API.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine.h"
@ -34,9 +35,11 @@ namespace Deer {
AS_RET_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::EditorEngine::errorCallback), 0, asCALL_CDECL));
DEER_CORE_TRACE("Registering Editor Engine interface");
registerEditorEngineStructs();
registerEditorEngineFunctions();
registerDockPanel();
loadScripts();
scriptModule = scriptEngine->GetModule("DeerModule");

View File

@ -1,171 +0,0 @@
#include "DeerStudio/EditorEngine/API/EditorEngine_Functions.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "angelscript.h"
namespace Deer {
void EditorEngine::registerEditorEngineFunctions() {
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool menuItem(const string& in)",
asFUNCTION(menuItem),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textColor(float, float, float, const string& in)",
asFUNCTION(textColor),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void text(const string& in)",
asFUNCTION(text),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIcon(const string& in, int)",
asFUNCTION(drawIcon),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool isMouseClicked(int)",
asFUNCTION(
isMouseClicked
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool isMouseDoubleClicked(int)",
asFUNCTION(
isMouseDoubleClicked
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void setupAutomaticColumns(int)",
asFUNCTION(
setupAutomaticColumns
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void endColumns()",
asFUNCTION(endColumns),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void nextColumn()",
asFUNCTION(nextColumn),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void print(const string& in)",
asFUNCTION (print),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textCentered(const string& in)",
asFUNCTION(textCentered),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIconCentered(const string& in, int)",
asFUNCTION(drawIconCentered),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getResourceCount(ResourceType, const string& in)",
asFUNCTION(getResourceCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourceNameById(ResourceType, const string& in, int)",
asFUNCTION(getResourceNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourcePathById(ResourceType, const string& in, int)",
asFUNCTION(getResourcePathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getDirCount(ResourceType, const string& in)",
asFUNCTION(getDirCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirPathById(ResourceType, const string& in, int)",
asFUNCTION(getDirPathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirNameById(ResourceType, const string& in, int)",
asFUNCTION(getDirNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void treeNode(const string& in, int)",
asFUNCTION(treeNode),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterFuncdef("void CallbackFunc(any@)"));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void treeNode(const string& in, int, any@+, CallbackFunc@+)",
asFUNCTION(treeNodeRecursive),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"Entity getRoot()",
asFUNCTION(getRoot),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"int getChildCount()",
asMETHOD(EntityStruct, getChildCount),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"Entity getChild(int)",
asMETHOD(EntityStruct, getChild),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"string getName()",
asMETHOD(EntityStruct, getName),
asCALL_THISCALL
));
AS_CHECK(scriptEngine->RegisterObjectMethod(
"Entity",
"int getId()",
asMETHOD(EntityStruct, getId),
asCALL_THISCALL
));
}
}

View File

@ -1,39 +0,0 @@
#include "DeerStudio/EditorEngine.h"
#include "scripthandle.h"
#include "scriptany.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Mesh.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Environment.h"
#include "DeerStudio/EditorEngine/API/EditorEngine_Directory.h"
#include "angelscript.h"
namespace Deer {
namespace EditorEngine {
void registerResourceTypeEnum() {
AS_RET_CHECK(scriptEngine->RegisterEnum("ResourceType"));
AS_CHECK(scriptEngine->RegisterEnumValue("ResourceType", "Mesh", (int)ResourceType::MESH));
}
void registerEntityStruct() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityStruct),
asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<EntityStruct>() | asOBJ_APP_CLASS_ALLINTS));
AS_CHECK(scriptEngine->RegisterObjectBehaviour(
"Entity",
asBEHAVE_CONSTRUCT,
"void f(int)",
asFunctionPtr(constructEntityStruct),
asCALL_CDECL_OBJLAST
));
}
void registerEditorEngineStructs() {
RegisterScriptHandle(scriptEngine);
RegisterScriptAny(scriptEngine);
registerResourceTypeEnum();
registerEntityStruct();
}
}
}

View File

@ -1,4 +1,4 @@
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "angelscript.h"

View File

@ -1,7 +1,7 @@
#include "angelscript.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
namespace Deer {
void EditorEngine::registerDockPanel() {

View File

@ -1,5 +1,5 @@
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/EditorEngine_ErrorHandle.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "Deer/Path.h"
#include "Deer/DataStore.h"

View File

@ -0,0 +1,279 @@
#include "DeerStudio/EditorEngine/API.h"
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "angelscript.h"
namespace Deer {
void EditorEngine::registerEditorEngineFunctions() {
registerEntityFunctions();
registerMathFunctions();
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textColor(float, float, float, const string& in)",
asFUNCTION(textColor),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void text(const string& in)",
asFUNCTION(text),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textCenter(const string& in)",
asFUNCTION(textCenter),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void textEnd(const string& in)",
asFUNCTION(textEnd),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIcon(const string& in, int)",
asFUNCTION(drawIcon),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool isItemClicked(int)",
asFUNCTION(
isItemClicked
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool isMouseDoubleClicked(int)",
asFUNCTION(
isMouseDoubleClicked
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void setupAutomaticColumns(int)",
asFUNCTION(
setupAutomaticColumns
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void setupColumns(int)",
asFUNCTION(
setupColumns
),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void endColumns()",
asFUNCTION(endColumns),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void nextColumn()",
asFUNCTION(nextColumn),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void print(const string& in)",
asFUNCTION (print),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void drawIconCentered(const string& in, int)",
asFUNCTION(drawIconCentered),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getResourceCount(ResourceType, const string& in)",
asFUNCTION(getResourceCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourceNameById(ResourceType, const string& in, int)",
asFUNCTION(getResourceNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getResourcePathById(ResourceType, const string& in, int)",
asFUNCTION(getResourcePathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"int getDirCount(ResourceType, const string& in)",
asFUNCTION(getDirCount),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirPathById(ResourceType, const string& in, int)",
asFUNCTION(getDirPathById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"string getDirNameById(ResourceType, const string& in, int)",
asFUNCTION(getDirNameById),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void treeNodeLeaf(const string& in, bool)",
asFUNCTION(treeNode),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool treeNode(const string& in, bool, any@+, ReciverFunc@+)",
asFUNCTION(treeNodeRecursive),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool componentNode(const string& in, any@+, ReciverFunc@+)",
asFUNCTION(componentNode),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void space()",
asFUNCTION(space),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void contextItemPopup(const string& in, any@+, ReciverFunc@+)",
asFUNCTION(contextItemPopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void contextMenuPopup(const string& in, any@+, ReciverFunc@+)",
asFUNCTION(contextMenuPopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void modalPopup(const string& in, ReciverFunc@+)",
asFUNCTION(modalPopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void simplePopup(const string& in, ReciverFunc@+)",
asFUNCTION(simplePopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void openPopup(const string& in, any@)",
asFUNCTION(openPopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void closePopup()",
asFUNCTION(closePopup),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool menuItem(const string& in)",
asFUNCTION(menuItem),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void dragDropSource(const string& in, any@, const string& in)",
asFUNCTION(dragDropSource),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void dragDropTarget(const string& in, any@+, TransferFunc@+)",
asFUNCTION(dragDropTarget),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool button(const string& in)",
asFUNCTION(button),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool buttonCenter(const string&in)",
asFUNCTION(buttonCenter),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool buttonEnd(const string&in)",
asFUNCTION(buttonEnd),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"bool inputText(const string& in, const string& in, string& out)",
asFUNCTION(inputText),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"float magicSlider(const string& in, float, float)",
asFUNCTION(magicSlider),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"vec3 magicSlider3(const string& in, vec3, float)",
asFUNCTION(magicSlider3),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void sameLine()",
asFUNCTION(sameLine),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void separator()",
asFUNCTION(separator),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void title(const string&in)",
asFUNCTION(title),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void titleEnd(const string&in)",
asFUNCTION(titleEnd),
asCALL_CDECL
));
AS_CHECK(scriptEngine->RegisterGlobalFunction(
"void titleCenter(const string&in)",
asFUNCTION(titleCenter),
asCALL_CDECL
));
}
}

View File

@ -0,0 +1,28 @@
#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/API.h"
#include "scripthandle.h"
#include "scriptany.h"
#include "angelscript.h"
namespace Deer {
namespace EditorEngine {
void registerResourceTypeEnum() {
AS_RET_CHECK(scriptEngine->RegisterEnum("ResourceType"));
AS_CHECK(scriptEngine->RegisterEnumValue("ResourceType", "Mesh", (int)ResourceType::MESH));
}
void registerEditorEngineStructs() {
RegisterScriptHandle(scriptEngine);
RegisterScriptAny(scriptEngine);
AS_CHECK(scriptEngine->RegisterFuncdef("void ReciverFunc(any@)"));
AS_CHECK(scriptEngine->RegisterFuncdef("void TransferFunc(any@, any@)"));
registerResourceTypeEnum();
registerEntityStructs();
registerMathStructs();
}
}
}

View File

@ -1,5 +1,4 @@
#include "Fonts.h"
#include "Deer/DataStore.h"
namespace Deer {

Some files were not shown because too many files have changed in this diff Show More