Refactor scene, environment, entity, and child entity saving for clear and faster execution
This commit is contained in:
parent
d1a99961b1
commit
fddb88a9b2
@ -4,12 +4,16 @@
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <stdint.h>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Deer/Log.h"
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/quaternion.hpp"
|
||||
|
||||
#define ENTITY_MAX_CHILDREN 64
|
||||
|
||||
namespace Deer {
|
||||
class ComponentScriptInstance;
|
||||
|
||||
@ -33,12 +37,44 @@ namespace Deer {
|
||||
};
|
||||
|
||||
struct RelationshipComponent {
|
||||
uint32_t parent_UID = 0;
|
||||
std::vector<uint32_t> children;
|
||||
uint16_t parent_id = 0;
|
||||
uint16_t childCount = 0;
|
||||
// Note: Since the root(id : 0) can't be a children, we will use 0 as
|
||||
// null or empty
|
||||
std::array<uint16_t, ENTITY_MAX_CHILDREN> childrens{};
|
||||
|
||||
inline uint16_t getChildrenId(size_t i) {
|
||||
DEER_CORE_ASSERT(i >= 0 && i < childCount && childrens[i] != 0,
|
||||
"Invalid child request {0}", i);
|
||||
return childrens[i];
|
||||
}
|
||||
inline bool addChildrenId(uint16_t childId) {
|
||||
if (childCount >= ENTITY_MAX_CHILDREN) return false;
|
||||
childrens[childCount] = childId;
|
||||
childCount++;
|
||||
return true;
|
||||
}
|
||||
inline void removeChildren(uint16_t childId) {
|
||||
uint16_t childPosition = 0;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
if (childrens[i] == childId) {
|
||||
childPosition = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Move all childs one position
|
||||
for (int i = childPosition + 1; i < childCount; i++) {
|
||||
childrens[i - 1] = childrens[i];
|
||||
}
|
||||
|
||||
childrens[childCount - 1] = 0;
|
||||
childCount--;
|
||||
}
|
||||
|
||||
RelationshipComponent() = default;
|
||||
RelationshipComponent(const RelationshipComponent&) = default;
|
||||
RelationshipComponent(uint32_t parent) : parent_UID(parent) {}
|
||||
RelationshipComponent(uint16_t _parent) : parent_id(_parent) {}
|
||||
};
|
||||
|
||||
struct TransformComponent {
|
||||
|
@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Memory.h"
|
||||
#include "entt/entt.hpp"
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
@ -13,54 +15,88 @@
|
||||
#include "DeerRender/SceneCamera.h"
|
||||
#endif
|
||||
|
||||
#define ENVIRONMENT_MAX_ENTITIES 2048
|
||||
|
||||
namespace Deer {
|
||||
class Entity;
|
||||
using EntityMap = std::unordered_map<uint32_t, Entity>;
|
||||
|
||||
class Environment {
|
||||
///////// NOTES ///////////
|
||||
// - The entity id means the position in a array defined in Environment
|
||||
// - The entity id is relative to a Environment so it can be a complete
|
||||
// diferent entity in other environments
|
||||
// - The entity number 0 is allways the root
|
||||
// - There is a limit defined by ENVIRONMENT_MAX_ENTITIES of how many
|
||||
// entities can be in an Environment
|
||||
///////// NOTES ///////////
|
||||
public:
|
||||
Environment();
|
||||
~Environment();
|
||||
// This class can not be copyed
|
||||
Environment(const Environment&) = delete;
|
||||
Environment& operator=(Environment&) = delete;
|
||||
|
||||
// Clears all entities
|
||||
void clear();
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
void render(SceneCamera& camera);
|
||||
#endif
|
||||
// Obtains the entity
|
||||
Entity& getEntity(uint16_t id) const;
|
||||
bool entityExists(uint16_t id) const;
|
||||
uint16_t getEntityCount() const { return m_entityCount; }
|
||||
|
||||
Entity& getEntity(uint32_t id);
|
||||
Entity& createEntity(const std::string& name = std::string());
|
||||
// Creates a entity child at root
|
||||
Entity& createEntity(const std::string& name = "");
|
||||
Entity& createEntityWithId(uint16_t id, const std::string& name = "");
|
||||
void destroyEntity(uint16_t id);
|
||||
|
||||
// Special behaviour
|
||||
Entity createEmptyEntity();
|
||||
|
||||
// FEO
|
||||
uint32_t tryGetMainCamera();
|
||||
uint16_t tryGetMainCamera();
|
||||
void setMainCamera(Entity& entity);
|
||||
|
||||
Entity& getRoot();
|
||||
|
||||
public:
|
||||
// Obtains the entity that is on the root of the environment
|
||||
inline Entity& getRoot() { return getEntity(0); }
|
||||
#ifdef DEER_RENDER
|
||||
void render(SceneCamera& camera);
|
||||
#endif
|
||||
entt::registry m_registry;
|
||||
EntityMap m_entities;
|
||||
|
||||
uint32_t m_rootEntity = 0;
|
||||
uint32_t m_mainCamera = 0;
|
||||
|
||||
private:
|
||||
uint32_t m_idCreationOffset = 0;
|
||||
inline uint32_t pullEntityID() {
|
||||
uint16_t m_mainCamera = 0;
|
||||
// To avoid inecessary loop we set this variable that means that smaller
|
||||
// id's than this numbers are not null, empty or used
|
||||
uint16_t m_idCreationOffset = 0;
|
||||
// Since we don't initialize Entity in the big array for performance we
|
||||
// want to keep track the ones we initialized defined by this value, it
|
||||
// the id is greater it means that any information that it has can't be
|
||||
// seen as valid
|
||||
uint16_t m_maxIdValue = 0;
|
||||
// Number of entities that exists inside
|
||||
uint16_t m_entityCount = 0;
|
||||
// This is where we save the entities, in a const list defined by
|
||||
// ENVIRONMENT_MAX_ENTITIES, we have to make sure this system is as fast
|
||||
// as possible
|
||||
Scope<std::array<Entity, ENVIRONMENT_MAX_ENTITIES>> entities;
|
||||
|
||||
inline uint16_t pullEntityID() {
|
||||
m_idCreationOffset++;
|
||||
if (m_idCreationOffset > m_maxIdValue)
|
||||
m_maxIdValue = m_idCreationOffset;
|
||||
return m_idCreationOffset;
|
||||
}
|
||||
|
||||
friend class Entity;
|
||||
};
|
||||
|
||||
// Warning: This calss does not initialize for performance
|
||||
class Entity {
|
||||
public:
|
||||
// This class can not be copied
|
||||
Entity(const Entity&) = delete;
|
||||
Entity() {}
|
||||
|
||||
static Entity nullEntity;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T& addComponent(Args&&... args) const {
|
||||
DEER_CORE_ASSERT(
|
||||
@ -97,45 +133,33 @@ namespace Deer {
|
||||
Entity& duplicate();
|
||||
void destroy();
|
||||
|
||||
Entity& getParent();
|
||||
inline uint32_t getParentUID() { return m_parentUID; }
|
||||
uint16_t getId() const { return m_entityID; }
|
||||
Entity& getParent() const;
|
||||
inline uint16_t getParentId() const { return m_parentID; }
|
||||
|
||||
// TODO, enable transfer entitys from difrent enviroments
|
||||
void setParent(Entity& parent);
|
||||
bool isDescendant(Entity& parent);
|
||||
|
||||
uint32_t getParentUID() const { return m_parentUID; }
|
||||
uint32_t getUID() const { return m_entityUID; }
|
||||
bool isDescendantOf(Entity& parent) const;
|
||||
|
||||
Environment* getEnvironment() const { return m_environment; }
|
||||
std::vector<uint32_t>& getChildren();
|
||||
|
||||
bool isRoot() { return m_isRoot; }
|
||||
bool isRoot() const { return m_entityID == 0; }
|
||||
glm::mat4 getWorldMatrix();
|
||||
glm::mat4 getRelativeMatrix();
|
||||
|
||||
void updateInternalVars();
|
||||
|
||||
inline bool isValid() const {
|
||||
return m_entityUID != 0 && m_environment != nullptr &&
|
||||
m_environment->m_registry.valid(m_entityHandle);
|
||||
}
|
||||
inline bool operator==(const Entity& b) const {
|
||||
return m_environment == b.m_environment &&
|
||||
m_entityUID == b.m_entityUID;
|
||||
}
|
||||
inline bool isValid() const { return m_exists; }
|
||||
|
||||
private:
|
||||
Entity(entt::entity handle, Environment* scene);
|
||||
bool removeChild(Entity& child);
|
||||
|
||||
entt::entity m_entityHandle = entt::null;
|
||||
Environment* m_environment = nullptr;
|
||||
uint32_t m_entityUID = 0;
|
||||
uint32_t m_parentUID = 0;
|
||||
bool m_isRoot = false;
|
||||
entt::entity m_entityHandle = entt::null;
|
||||
uint16_t m_entityID = 0;
|
||||
uint16_t m_parentID = 0;
|
||||
bool m_exists = false;
|
||||
|
||||
Entity(entt::entity handle, Environment* scene, uint16_t entityID);
|
||||
|
||||
friend class Environment;
|
||||
friend class std::unordered_map<uint32_t, Entity>;
|
||||
};
|
||||
} // namespace Deer
|
||||
|
@ -46,6 +46,7 @@ namespace Deer {
|
||||
#define DEER_CORE_ASSERT(condition, ...) \
|
||||
if (!(condition)) { \
|
||||
Deer::Log::getCoreLogger()->error(__VA_ARGS__); \
|
||||
__builtin_trap(); \
|
||||
}
|
||||
#define DEER_SCRIPT_ASSERT(condition, ...) \
|
||||
if (!(condition)) { \
|
||||
|
@ -18,6 +18,9 @@ namespace Deer {
|
||||
class Scene {
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
Scene(const Scene&) = delete;
|
||||
Scene operator=(Scene&) = delete;
|
||||
|
||||
void createVoxelWorld(const VoxelWorldProps&);
|
||||
void deleteVoxelWorld();
|
||||
@ -28,13 +31,16 @@ namespace Deer {
|
||||
void endExecution();
|
||||
|
||||
public:
|
||||
inline Ref<Environment>& getMainEnviroment() { return m_enviroment; }
|
||||
inline Ref<VoxelWorld>& getVoxelWorld() { return m_voxelWorld; }
|
||||
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; }
|
||||
|
||||
private:
|
||||
Ref<Environment> m_enviroment;
|
||||
Ref<VoxelWorld> m_voxelWorld;
|
||||
Scope<Environment> m_enviroment;
|
||||
Scope<VoxelWorld> m_voxelWorld;
|
||||
|
||||
bool m_isExecuting = false;
|
||||
#ifdef DEER_RENDER
|
||||
@ -49,13 +55,10 @@ namespace Deer {
|
||||
};
|
||||
|
||||
namespace SceneDataStore {
|
||||
Scene loadScene(const Path& name);
|
||||
void loadScene(Scene& scene, const Path& name);
|
||||
void exportScene(const Scene& scene, const Path& name);
|
||||
|
||||
void deleteSceneJson(const Path& name);
|
||||
void exportSceneJson(Scene& scene, const Path& name);
|
||||
void exportScenesBin();
|
||||
|
||||
void exportRuntimeScene(Scene& scene);
|
||||
Scene importRuntimeScene();
|
||||
void exportRuntimeScene(const Scene& scene);
|
||||
void importRuntimeScene(Scene& scene);
|
||||
} // namespace SceneDataStore
|
||||
} // namespace Deer
|
||||
|
@ -148,6 +148,7 @@ namespace Deer {
|
||||
// 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;
|
||||
|
@ -1,108 +1,90 @@
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
namespace Deer {
|
||||
Entity Entity::nullEntity = Entity();
|
||||
|
||||
Entity::Entity(entt::entity handle, Environment* scene)
|
||||
: m_entityHandle(handle), m_environment(scene) {
|
||||
}
|
||||
|
||||
bool Entity::removeChild(Entity& child) {
|
||||
DEER_CORE_ASSERT(child.m_environment == m_environment, "Can not remove childrens from diferent enviroments");
|
||||
|
||||
std::vector<uint32_t>& children = getChildren();
|
||||
|
||||
auto it = std::find(children.begin(), children.end(), child.m_entityUID);
|
||||
if (it != children.end())
|
||||
{
|
||||
children.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Entity::Entity(entt::entity handle, Environment* scene, uint16_t entityID)
|
||||
: m_entityHandle(handle),
|
||||
m_environment(scene),
|
||||
m_entityID(entityID),
|
||||
m_exists(true) {}
|
||||
|
||||
void Entity::setParent(Entity& parent) {
|
||||
DEER_CORE_ASSERT(parent.m_environment == m_environment , "Can not set parent from diferent enviroments");
|
||||
DEER_CORE_ASSERT(!isRoot(), "Can not set parent to root");
|
||||
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
|
||||
DEER_CORE_ASSERT(parent.m_environment == m_environment,
|
||||
"Can not set parent from diferent enviroments");
|
||||
DEER_CORE_ASSERT(parent.isValid(), "Parent is not valid");
|
||||
if (parent.getId() == getId()) return;
|
||||
|
||||
if (m_parentUID == parent.m_entityUID)
|
||||
Entity& current_parent = getParent();
|
||||
if (parent.isDescendantOf(*this)) {
|
||||
return;
|
||||
|
||||
if (m_parentUID != 0){
|
||||
Entity& current_parent = getParent();
|
||||
if (parent.isDescendant(*this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
current_parent.removeChild(*this);
|
||||
}
|
||||
|
||||
m_parentUID = parent.m_entityUID;
|
||||
getComponent<RelationshipComponent>().parent_UID = parent.m_entityUID;
|
||||
parent.getChildren().push_back(m_entityUID);
|
||||
if (!parent.getComponent<RelationshipComponent>().addChildrenId(
|
||||
getId())) {
|
||||
DEER_CORE_ERROR(
|
||||
"Max child count!!!, could not set parent {0} to entity {1}",
|
||||
parent.getComponent<TagComponent>().tag.c_str(),
|
||||
getComponent<TagComponent>().tag.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_parentID = parent.getId();
|
||||
current_parent.getComponent<RelationshipComponent>().removeChildren(
|
||||
getId());
|
||||
|
||||
getComponent<RelationshipComponent>().parent_id = parent.getId();
|
||||
}
|
||||
|
||||
bool Entity::isDescendant(Entity& parent) {
|
||||
if (m_entityUID == parent.m_entityUID)
|
||||
return true;
|
||||
|
||||
if (isRoot())
|
||||
return false;
|
||||
bool Entity::isDescendantOf(Entity& parent) const {
|
||||
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
|
||||
if (getId() == parent.getId()) return true;
|
||||
if (isRoot()) return false;
|
||||
|
||||
return getParent().isDescendant(parent);
|
||||
return getParent().isDescendantOf(parent);
|
||||
}
|
||||
|
||||
Entity& Entity::duplicate() {
|
||||
Entity& creation = m_environment->createEntity(getComponent<TagComponent>().tag + "(d)");
|
||||
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
|
||||
Entity& creation = m_environment->createEntity(
|
||||
getComponent<TagComponent>().tag + "(d)");
|
||||
|
||||
creation.getComponent<TransformComponent>() = getComponent<TransformComponent>();
|
||||
Entity& parent = m_environment->getEntity(m_parentUID);
|
||||
creation.setParent(parent);
|
||||
creation.setParent(getParent());
|
||||
|
||||
creation.getComponent<TransformComponent>() =
|
||||
getComponent<TransformComponent>();
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
if (m_environment->m_registry.any_of<MeshRenderComponent>(m_entityHandle))
|
||||
creation.addComponent<MeshRenderComponent>(getComponent<MeshRenderComponent>());
|
||||
if (m_environment->m_registry.any_of<MeshRenderComponent>(
|
||||
m_entityHandle))
|
||||
creation.addComponent<MeshRenderComponent>(
|
||||
getComponent<MeshRenderComponent>());
|
||||
|
||||
if (m_environment->m_registry.any_of<CameraComponent>(m_entityHandle))
|
||||
creation.addComponent<CameraComponent>(getComponent<CameraComponent>());
|
||||
creation.addComponent<CameraComponent>(
|
||||
getComponent<CameraComponent>());
|
||||
|
||||
if (m_environment->m_registry.any_of<TextureBindingComponent>(m_entityHandle))
|
||||
creation.addComponent<TextureBindingComponent>(getComponent<TextureBindingComponent>());
|
||||
if (m_environment->m_registry.any_of<TextureBindingComponent>(
|
||||
m_entityHandle))
|
||||
creation.addComponent<TextureBindingComponent>(
|
||||
getComponent<TextureBindingComponent>());
|
||||
#endif
|
||||
return creation;
|
||||
}
|
||||
|
||||
void Entity::destroy() {
|
||||
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
|
||||
DEER_CORE_ASSERT(!isRoot(), "Can not destroy the root");
|
||||
getParent().removeChild(*this);
|
||||
|
||||
if (m_environment->tryGetMainCamera() == m_entityUID)
|
||||
m_environment->setMainCamera(nullEntity);
|
||||
|
||||
for (auto entt : getChildren()) {
|
||||
m_environment->getEntity(entt).destroy();
|
||||
}
|
||||
|
||||
m_environment->m_registry.destroy(m_entityHandle);
|
||||
m_entityHandle = entt::null;
|
||||
m_environment = nullptr;
|
||||
m_entityUID = 0;
|
||||
m_environment->destroyEntity(getId());
|
||||
}
|
||||
|
||||
Entity& Entity::getParent() {
|
||||
return m_environment->getEntity(m_parentUID);
|
||||
}
|
||||
|
||||
std::vector<uint32_t>& Entity::getChildren() {
|
||||
return getComponent<RelationshipComponent>().children;
|
||||
Entity& Entity::getParent() const {
|
||||
DEER_CORE_ASSERT(isValid(), "Entity is not valid");
|
||||
return m_environment->getEntity(m_parentID);
|
||||
}
|
||||
|
||||
glm::mat4 Entity::getWorldMatrix() {
|
||||
if (isRoot())
|
||||
return glm::mat4(1.0f);
|
||||
if (isRoot()) return glm::mat4(1.0f);
|
||||
|
||||
return getParent().getWorldMatrix() * getRelativeMatrix();
|
||||
}
|
||||
@ -110,18 +92,4 @@ namespace Deer {
|
||||
glm::mat4 Entity::getRelativeMatrix() {
|
||||
return getComponent<TransformComponent>().getMatrix();
|
||||
}
|
||||
|
||||
void Entity::updateInternalVars() {
|
||||
TagComponent& tag = getComponent<TagComponent>();
|
||||
RelationshipComponent& relation = getComponent<RelationshipComponent>();
|
||||
|
||||
m_entityUID = tag.entityUID;
|
||||
m_parentUID = relation.parent_UID;
|
||||
m_isRoot = relation.parent_UID == 0;
|
||||
|
||||
if (m_isRoot)
|
||||
m_environment->m_rootEntity = tag.entityUID;
|
||||
m_environment->m_entities[tag.entityUID] = *this;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Deer
|
||||
|
@ -1,88 +1,134 @@
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
#include "Deer/Application.h"
|
||||
#include "Deer/Asset.h"
|
||||
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "DeerRender/Render/Render.h"
|
||||
#include "DeerRender/Render/RenderUtils.h"
|
||||
#include "DeerRender/Render/Texture.h"
|
||||
|
||||
#include "Deer/Log.h"
|
||||
|
||||
namespace Deer {
|
||||
Environment::Environment() {
|
||||
entities = MakeScope<std::array<Entity, ENVIRONMENT_MAX_ENTITIES>>();
|
||||
clear();
|
||||
}
|
||||
|
||||
Environment::~Environment() { }
|
||||
Environment::~Environment() {}
|
||||
|
||||
void Environment::clear() {
|
||||
// Clear all existing entities and map
|
||||
m_registry.clear();
|
||||
m_entities.clear();
|
||||
|
||||
m_rootEntity = 0;
|
||||
m_mainCamera = 0;
|
||||
m_idCreationOffset = 0;
|
||||
m_maxIdValue = 0;
|
||||
// We set it to one because we count root
|
||||
m_entityCount = 1;
|
||||
|
||||
m_rootEntity = pullEntityID();
|
||||
|
||||
entt::entity rootEntity = m_registry.create();
|
||||
Entity entity = { rootEntity, this };
|
||||
|
||||
entity.addComponent<TagComponent>("root", m_rootEntity);
|
||||
entity.addComponent<RelationshipComponent>();
|
||||
entity.addComponent<TransformComponent>();
|
||||
|
||||
entity.m_isRoot = true;
|
||||
entity.m_entityUID = m_rootEntity;
|
||||
m_entities.insert({ m_rootEntity, entity });
|
||||
createEntityWithId(0, "root");
|
||||
}
|
||||
|
||||
Entity& Environment::getEntity(uint32_t id) {
|
||||
DEER_CORE_ASSERT(m_entities.contains(id), "Entity id : {0} does not exist", id);
|
||||
return m_entities[id];
|
||||
Entity& Environment::getEntity(uint16_t id) const {
|
||||
DEER_CORE_ASSERT(entityExists(id), "Entity id {0} does not exist", id);
|
||||
Entity& refEntity = (*entities)[id];
|
||||
return refEntity;
|
||||
}
|
||||
|
||||
Entity& Environment::createEntity(const std::string& name)
|
||||
{
|
||||
uint32_t id;
|
||||
|
||||
bool Environment::entityExists(uint16_t id) const {
|
||||
if (id < 0) return false;
|
||||
if (id > m_maxIdValue) return false;
|
||||
if (id >= ENVIRONMENT_MAX_ENTITIES) return false;
|
||||
Entity& refEntity = (*entities)[id];
|
||||
return refEntity.isValid();
|
||||
}
|
||||
|
||||
Entity& Environment::createEntity(const std::string& name) {
|
||||
uint16_t id;
|
||||
do {
|
||||
id = pullEntityID();
|
||||
} while (m_entities.contains(id));
|
||||
DEER_CORE_ASSERT(id < ENVIRONMENT_MAX_ENTITIES,
|
||||
"Fatal error, max number of entities exited");
|
||||
} while (entityExists(id));
|
||||
|
||||
entt::entity entityID = m_registry.create();
|
||||
Entity entity = { entityID, this };
|
||||
Entity& entity = (*entities)[id];
|
||||
entity = {entityID, this, id};
|
||||
|
||||
entity.addComponent<TagComponent>(name, id);
|
||||
entity.addComponent<RelationshipComponent>();
|
||||
entity.addComponent<TransformComponent>();
|
||||
entity.m_exists = true;
|
||||
|
||||
entity.m_entityUID = id;
|
||||
entity.setParent(getRoot());
|
||||
|
||||
m_entities.insert({ id, entity });
|
||||
return m_entities[id];
|
||||
}
|
||||
|
||||
Entity Environment::createEmptyEntity() {
|
||||
entt::entity entityID = m_registry.create();
|
||||
Entity entity = { entityID, this };
|
||||
m_entityCount++;
|
||||
entity.m_parentID = 0;
|
||||
if (!getRoot().getComponent<RelationshipComponent>().addChildrenId(
|
||||
id)) {
|
||||
DEER_CORE_ERROR("Root is full!");
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
uint32_t Environment::tryGetMainCamera() {
|
||||
return m_mainCamera;
|
||||
Entity& Environment::createEntityWithId(uint16_t id,
|
||||
const std::string& name) {
|
||||
// We want to initialize all entities that are not initialized to a
|
||||
// default state of invalid
|
||||
for (int i = m_maxIdValue + 1; i < id; i++) {
|
||||
Entity& nullEntity = (*entities)[i];
|
||||
nullEntity.m_exists = false;
|
||||
}
|
||||
if (m_maxIdValue < id) m_maxIdValue = id;
|
||||
|
||||
Entity& entity = (*entities)[id];
|
||||
entt::entity entityID = m_registry.create();
|
||||
entity = {entityID, this, id};
|
||||
entity.m_exists = true;
|
||||
|
||||
entity.addComponent<TagComponent>(name, id);
|
||||
entity.addComponent<RelationshipComponent>();
|
||||
entity.addComponent<TransformComponent>();
|
||||
|
||||
m_entityCount++;
|
||||
if (id != 0) {
|
||||
if (!getRoot().getComponent<RelationshipComponent>().addChildrenId(
|
||||
id)) {
|
||||
DEER_CORE_ERROR("Root is full!");
|
||||
}
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
void Environment::destroyEntity(uint16_t entityID) {
|
||||
DEER_CORE_ASSERT(entityExists(entityID), "Entity id {0} does not exist",
|
||||
entityID);
|
||||
DEER_CORE_ASSERT(entityID == 0, "Can not destroy root");
|
||||
|
||||
Entity& entity = (*entities)[entityID];
|
||||
entity.getParent().getComponent<RelationshipComponent>().removeChildren(
|
||||
entityID);
|
||||
|
||||
RelationshipComponent& relationship =
|
||||
entity.getComponent<RelationshipComponent>();
|
||||
// We want to delete all childrens
|
||||
for (int i = 0; i < relationship.childCount; i++) {
|
||||
uint16_t childID = relationship.getChildrenId(i);
|
||||
destroyEntity(childID);
|
||||
}
|
||||
|
||||
if (m_mainCamera == entityID) m_mainCamera = 0;
|
||||
if (entityID <= m_idCreationOffset) m_idCreationOffset = entityID - 1;
|
||||
|
||||
m_registry.destroy(entity.m_entityHandle);
|
||||
entity.m_exists = false;
|
||||
m_entityCount--;
|
||||
}
|
||||
|
||||
uint16_t Environment::tryGetMainCamera() { return m_mainCamera; }
|
||||
|
||||
void Environment::setMainCamera(Entity& entity) {
|
||||
if (!entity.isValid())
|
||||
m_mainCamera = 0;
|
||||
if (!entity.isValid()) m_mainCamera = 0;
|
||||
|
||||
m_mainCamera = entity.m_entityUID;
|
||||
m_mainCamera = entity.getId();
|
||||
}
|
||||
|
||||
Entity& Environment::getRoot() {
|
||||
return m_entities[m_rootEntity];
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -1,22 +1,23 @@
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Memory.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
|
||||
#include "Deer/ComponentScript.h"
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Memory.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "Deer/Voxels/Chunk.h"
|
||||
#include "Deer/Voxels/Layer.h"
|
||||
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/ComponentScript.h"
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
|
||||
#endif
|
||||
|
||||
namespace Deer {
|
||||
Scene::Scene() {
|
||||
m_enviroment = Ref<Environment>(new Environment());
|
||||
m_enviroment = MakeScope<Environment>();
|
||||
m_voxelWorld = nullptr;
|
||||
}
|
||||
|
||||
void Scene::beginExecution() {
|
||||
@ -27,14 +28,17 @@ namespace Deer {
|
||||
ScriptEngine::beginExecutionContext(this);
|
||||
|
||||
// Instantiate all the scripts
|
||||
auto view = m_enviroment->m_registry.view<ScriptComponent, TagComponent>();
|
||||
auto view =
|
||||
m_enviroment->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);
|
||||
|
||||
componentScript.roeInstance =
|
||||
ScriptEngine::createComponentScriptInstance(
|
||||
componentScript.scriptID, entity);
|
||||
|
||||
componentScript.roeInstance->start();
|
||||
}
|
||||
}
|
||||
@ -63,15 +67,13 @@ namespace Deer {
|
||||
}
|
||||
|
||||
void Scene::createVoxelWorld(const VoxelWorldProps& props) {
|
||||
m_voxelWorld = Ref<VoxelWorld>(new VoxelWorld(props));
|
||||
m_voxelWorld = MakeScope<VoxelWorld>(props);
|
||||
}
|
||||
|
||||
void Scene::deleteVoxelWorld() {
|
||||
m_voxelWorld.reset();
|
||||
}
|
||||
void Scene::deleteVoxelWorld() { m_voxelWorld.reset(); }
|
||||
|
||||
void Scene::clear() {
|
||||
m_enviroment->clear();
|
||||
m_voxelWorld.reset();
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
||||
|
@ -1,130 +1,74 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Scene/Serialization/Serialization.h"
|
||||
#include "cereal/archives/json.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
|
||||
#include "Deer/Scene/Serialization/Serialization.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace Deer {
|
||||
Scene loadSceneJson(uint8_t* data, uint32_t size);
|
||||
Scene loadSceneBin(uint8_t* data, uint32_t size);
|
||||
|
||||
Scene SceneDataStore::loadScene(const Path& name) {
|
||||
void SceneDataStore::loadScene(Scene& scene, const Path& name) {
|
||||
Path realName;
|
||||
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
|
||||
|
||||
uint32_t size;
|
||||
uint8_t* data = DataStore::readFile(realName, &size);
|
||||
|
||||
Scene scene_data;
|
||||
scene_data = loadSceneJson(data, size);
|
||||
|
||||
delete[] data;
|
||||
return scene_data;
|
||||
}
|
||||
|
||||
Scene loadSceneJson(uint8_t* data, uint32_t size) {
|
||||
std::string strData((char*)data, size);
|
||||
std::istringstream stream(strData);
|
||||
|
||||
Scene scene;
|
||||
{
|
||||
cereal::JSONInputArchive archive(stream);
|
||||
archive(cereal::make_nvp("scene", scene));
|
||||
}
|
||||
|
||||
return scene;
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
Scene loadSceneBin(uint8_t* data, uint32_t size) {
|
||||
std::string strData((char*)data, size);
|
||||
std::istringstream stream(strData);
|
||||
|
||||
Scene scene;
|
||||
{
|
||||
cereal::PortableBinaryInputArchive archive(stream);
|
||||
archive(cereal::make_nvp("scene", scene));
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
void SceneDataStore::deleteSceneJson(const Path& name) {
|
||||
DataStore::deleteFile((Path(DEER_SCENE_PATH) / (name.generic_string() + ".dscn")));
|
||||
}
|
||||
|
||||
void SceneDataStore::exportSceneJson(Scene& scene, const Path& name) {
|
||||
is_server_serialization = false;
|
||||
void SceneDataStore::exportScene(const Scene& scene, 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));
|
||||
}
|
||||
|
||||
Path savePath = Path(DEER_SCENE_PATH) / toLowerCasePath((name.generic_string() + ".dscn"));
|
||||
std::string_view view = output.view();
|
||||
|
||||
DataStore::saveFile(savePath, (uint8_t*)view.data(), view.size());
|
||||
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
|
||||
}
|
||||
|
||||
void exportSceneBin(Scene& scene, const Path& name) {
|
||||
is_server_serialization = false;
|
||||
void SceneDataStore::exportRuntimeScene(const Scene& scene) {
|
||||
Path realName;
|
||||
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");
|
||||
|
||||
std::stringstream output;
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive archive(output);
|
||||
archive(cereal::make_nvp("scene", scene));
|
||||
}
|
||||
|
||||
Path savePath = Path(DEER_BIN_PATH) / Path(DEER_SCENE_PATH) / toLowerCasePath((name.generic_string() + ".dbscn"));
|
||||
std::string_view view = output.view();
|
||||
|
||||
DataStore::saveFile(savePath, (uint8_t*)view.data(), view.size());
|
||||
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
|
||||
}
|
||||
|
||||
void SceneDataStore::exportScenesBin() {
|
||||
std::vector<Path> scenes = DataStore::getFiles(DEER_SCENE_PATH, ".dscn");
|
||||
|
||||
for (Path& scene_path : scenes) {
|
||||
uint32_t size;
|
||||
uint8_t* data = DataStore::readFile(scene_path, &size);
|
||||
|
||||
Scene scene_data = loadSceneJson(data, size);
|
||||
delete[] data;
|
||||
|
||||
Path name = scene_path.lexically_relative(DEER_SCENE_PATH);
|
||||
name = name.root_path() / name.stem();
|
||||
|
||||
exportSceneBin(scene_data, name);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneDataStore::exportRuntimeScene(Scene& scene) {
|
||||
std::stringstream output;
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive archive(output);
|
||||
archive(cereal::make_nvp("scene", scene));
|
||||
}
|
||||
|
||||
Path savePath = Path(DEER_TEMP_PATH) / "scene_runtime.dbscn";
|
||||
std::string_view view = output.view();
|
||||
|
||||
DataStore::saveFile(savePath, (uint8_t*)view.data(), view.size());
|
||||
}
|
||||
|
||||
Scene SceneDataStore::importRuntimeScene() {
|
||||
Path loadPath = Path(DEER_TEMP_PATH) / "scene_runtime.dbscn";
|
||||
void SceneDataStore::importRuntimeScene(Scene& scene) {
|
||||
Path realName;
|
||||
realName = Path(DEER_TEMP_PATH) / ("temp_scene.dbscn");
|
||||
|
||||
uint32_t size;
|
||||
uint8_t* data = DataStore::readFile(loadPath, &size);
|
||||
uint8_t* data = DataStore::readFile(realName, &size);
|
||||
|
||||
std::string strData((char*)data, size);
|
||||
std::istringstream stream(strData);
|
||||
|
||||
{
|
||||
cereal::PortableBinaryInputArchive archive(stream);
|
||||
archive(cereal::make_nvp("scene", scene));
|
||||
}
|
||||
|
||||
Scene scene_data = loadSceneBin(data, size);
|
||||
delete[] data;
|
||||
|
||||
return scene_data;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Deer
|
||||
|
@ -2,13 +2,14 @@
|
||||
#include "Deer/Components.h"
|
||||
|
||||
namespace Deer {
|
||||
// RELATIONSHIP COMPONENT
|
||||
template<class Archive>
|
||||
void serialize(Archive& archive,
|
||||
RelationshipComponent& relationship) {
|
||||
// RELATIONSHIP COMPONENT
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive, RelationshipComponent& relationship) {
|
||||
archive(cereal::make_nvp("parentId", relationship.parent_id));
|
||||
|
||||
archive(cereal::make_nvp("parentUID", relationship.parent_UID));
|
||||
archive(cereal::make_nvp("childrensUIDs", relationship.children));
|
||||
|
||||
}
|
||||
}
|
||||
archive(cereal::make_size_tag(
|
||||
static_cast<cereal::size_type>(relationship.childCount)));
|
||||
for (int i = 0; i < relationship.childCount; i++)
|
||||
archive(relationship.childrens[i]);
|
||||
}
|
||||
} // namespace Deer
|
@ -1,83 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Scene/Serialization/SerializationGlobalVars.h"
|
||||
#include "EntitySerializationStruct.h"
|
||||
|
||||
namespace Deer {
|
||||
template <class Archive, typename T>
|
||||
void saveComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
||||
template <class Archive, typename T>
|
||||
void saveComponent(Archive& archive, const std::string& componentName,
|
||||
Entity const& m_entity) {
|
||||
bool hasComponent = m_entity.hasComponent<T>();
|
||||
archive(
|
||||
cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
const T& component = m_entity.getComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
}
|
||||
}
|
||||
|
||||
bool hasComponent = m_entity.hasComponent<T>();
|
||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
T& component = m_entity.getComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
}
|
||||
}
|
||||
template <class Archive, typename T>
|
||||
void loadComponent(Archive& archive, const std::string& componentName,
|
||||
Entity const& m_entity) {
|
||||
bool hasComponent;
|
||||
archive(
|
||||
cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
T& component = m_entity.addComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
}
|
||||
}
|
||||
// ENTITY
|
||||
template <class Archive>
|
||||
void save(Archive& archive, EntitySerializationStruct const& m_entity) {
|
||||
const Entity& entity = m_entity.env->getEntity(m_entity.entityID);
|
||||
|
||||
template <class Archive, typename T>
|
||||
void loadComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
||||
const TagComponent& name = entity.getComponent<TagComponent>();
|
||||
archive(cereal::make_nvp("id", m_entity.entityID));
|
||||
archive(cereal::make_nvp("name", name.tag));
|
||||
|
||||
bool hasComponent;
|
||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
||||
if (hasComponent) {
|
||||
T& component = m_entity.addComponent<T>();
|
||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
||||
}
|
||||
}
|
||||
// ENTITY
|
||||
template<class Archive>
|
||||
void save(Archive& archive,
|
||||
Entity const& m_entity) {
|
||||
const TransformComponent& transform =
|
||||
entity.getComponent<TransformComponent>();
|
||||
archive(cereal::make_nvp("transform", transform));
|
||||
|
||||
uint32_t id = m_entity.getUID();
|
||||
|
||||
TagComponent& name = m_entity.getComponent<TagComponent>();
|
||||
archive(cereal::make_nvp("id", id));
|
||||
archive(cereal::make_nvp("name", name.tag));
|
||||
|
||||
TransformComponent& transform = m_entity.getComponent<TransformComponent>();
|
||||
archive(cereal::make_nvp("transform", transform));
|
||||
|
||||
RelationshipComponent& relation = m_entity.getComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", relation));
|
||||
const RelationshipComponent& relation =
|
||||
entity.getComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", relation));
|
||||
|
||||
#ifdef DEER_RENDER
|
||||
if (!is_server_serialization) {
|
||||
saveComponent<Archive, MeshRenderComponent>(archive, "meshRenderComponent", m_entity);
|
||||
saveComponent<Archive, CameraComponent>(archive, "cameraComponent", m_entity);
|
||||
saveComponent<Archive, TextureBindingComponent>(archive, "textureBindingComponent", m_entity);
|
||||
}
|
||||
if (!is_server_serialization) {
|
||||
saveComponent<Archive, MeshRenderComponent>(
|
||||
archive, "meshRenderComponent", entity);
|
||||
saveComponent<Archive, CameraComponent>(archive, "cameraComponent",
|
||||
entity);
|
||||
saveComponent<Archive, TextureBindingComponent>(
|
||||
archive, "textureBindingComponent", entity);
|
||||
}
|
||||
#endif
|
||||
saveComponent<Archive, ScriptComponent>(archive, "scriptComponent", m_entity);
|
||||
}
|
||||
saveComponent<Archive, ScriptComponent>(archive, "scriptComponent",
|
||||
entity);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& archive,
|
||||
Entity& m_entity) {
|
||||
|
||||
uint32_t id;
|
||||
std::string name;
|
||||
archive(cereal::make_nvp("id", id));
|
||||
archive(cereal::make_nvp("name", name));
|
||||
m_entity.addComponent<TagComponent>() = TagComponent(name, id);
|
||||
|
||||
TransformComponent& transform = m_entity.addComponent<TransformComponent>();
|
||||
archive(cereal::make_nvp("transform", transform));
|
||||
|
||||
RelationshipComponent& relationship = m_entity.addComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", relationship));
|
||||
template <class Archive>
|
||||
void load(Archive& archive, EntitySerializationStruct& m_entity) {
|
||||
uint16_t id;
|
||||
std::string name;
|
||||
archive(cereal::make_nvp("id", id));
|
||||
archive(cereal::make_nvp("name", name));
|
||||
|
||||
Entity& entity = m_entity.env->createEntityWithId(id);
|
||||
archive(cereal::make_nvp("transform",
|
||||
entity.getComponent<TransformComponent>()));
|
||||
RelationshipComponent& rc =
|
||||
entity.getComponent<RelationshipComponent>();
|
||||
archive(cereal::make_nvp("relationship", rc));
|
||||
entity.setParent(m_entity.env->getEntity(rc.parent_id));
|
||||
#ifdef DEER_RENDER
|
||||
if (!is_server_serialization) {
|
||||
loadComponent<Archive, MeshRenderComponent>(archive, "meshRenderComponent", m_entity);
|
||||
loadComponent<Archive, CameraComponent>(archive, "cameraComponent", m_entity);
|
||||
loadComponent<Archive, TextureBindingComponent>(archive, "textureBindingComponent", m_entity);
|
||||
}
|
||||
if (!is_server_serialization) {
|
||||
loadComponent<Archive, MeshRenderComponent>(
|
||||
archive, "meshRenderComponent", entity);
|
||||
loadComponent<Archive, CameraComponent>(archive, "cameraComponent",
|
||||
entity);
|
||||
loadComponent<Archive, TextureBindingComponent>(
|
||||
archive, "textureBindingComponent", entity);
|
||||
}
|
||||
#endif
|
||||
loadComponent<Archive, ScriptComponent>(archive, "scriptComponent", m_entity);
|
||||
loadComponent<Archive, ScriptComponent>(archive, "scriptComponent",
|
||||
entity);
|
||||
}
|
||||
|
||||
m_entity.updateInternalVars();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Deer
|
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace Deer {
|
||||
class Environment;
|
||||
struct EntitySerializationStruct {
|
||||
uint16_t entityID;
|
||||
Environment* env;
|
||||
};
|
||||
} // namespace Deer
|
@ -1,76 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "EntitySerializationStruct.h"
|
||||
|
||||
namespace Deer {
|
||||
struct EntityVector_Environment {
|
||||
std::vector<Entity> entities;
|
||||
const Ref<Environment>& environment;
|
||||
EntityVector_Environment(const Ref<Environment>& _environment)
|
||||
: environment(_environment) { }
|
||||
};
|
||||
struct EnvironmentEntity {
|
||||
Environment& environment;
|
||||
EnvironmentEntity(Environment& env) : environment(env) {}
|
||||
};
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive& archive,
|
||||
Ref<Environment> const& m_environment) {
|
||||
EntityVector_Environment entityMap(m_environment);
|
||||
auto view = m_environment->m_registry.view<TagComponent>();
|
||||
template <class Archive>
|
||||
void save(Archive& archive, const Deer::Environment& environment) {
|
||||
EnvironmentEntity envEnt(const_cast<Deer::Environment&>(environment));
|
||||
archive(cereal::make_nvp("entities", envEnt));
|
||||
}
|
||||
|
||||
for (auto entity : view) {
|
||||
TagComponent& tag = view.get<TagComponent>(entity);
|
||||
entityMap.entities.push_back(m_environment->getEntity(tag.entityUID));
|
||||
}
|
||||
template <class Archive>
|
||||
void load(Archive& archive, Deer::Environment& environment) {
|
||||
EnvironmentEntity envEnt(environment);
|
||||
archive(cereal::make_nvp("entities", envEnt));
|
||||
}
|
||||
|
||||
// Sort to avoid conflicts
|
||||
std::sort(entityMap.entities.begin(), entityMap.entities.end(), [](Entity& a, Entity& b) {
|
||||
return a.getUID() < b.getUID();
|
||||
});
|
||||
template <class Archive>
|
||||
void save(Archive& archive, EnvironmentEntity const& m_entities) {
|
||||
archive(cereal::make_size_tag(static_cast<cereal::size_type>(
|
||||
m_entities.environment.getEntityCount())));
|
||||
|
||||
uint32_t mainCameraUID = m_environment->tryGetMainCamera();
|
||||
for (uint16_t i = 0; i < m_entities.environment.getEntityCount(); i++) {
|
||||
while (!m_entities.environment.entityExists(i)) {
|
||||
i++;
|
||||
}
|
||||
|
||||
archive(cereal::make_nvp("entities", entityMap));
|
||||
archive(cereal::make_nvp("mainCameraUID", mainCameraUID));
|
||||
EntitySerializationStruct serializationStruct;
|
||||
serializationStruct.env =
|
||||
const_cast<Environment*>(&m_entities.environment);
|
||||
serializationStruct.entityID = i;
|
||||
|
||||
}
|
||||
archive(serializationStruct);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& archive,
|
||||
Ref<Environment>& m_environment) {
|
||||
EntityVector_Environment entityMap(m_environment);
|
||||
template <class Archive>
|
||||
void load(Archive& archive, EnvironmentEntity& m_entities) {
|
||||
cereal::size_type size;
|
||||
archive(cereal::make_size_tag(size));
|
||||
|
||||
uint32_t mainCameraUID;
|
||||
for (int i = 0; i < size; i++) {
|
||||
EntitySerializationStruct serializationStruct;
|
||||
serializationStruct.env = &m_entities.environment;
|
||||
|
||||
archive(cereal::make_nvp("entities", entityMap));
|
||||
archive(cereal::make_nvp("mainCameraUID", mainCameraUID));
|
||||
|
||||
if (mainCameraUID != 0)
|
||||
m_environment->setMainCamera(m_environment->getEntity(mainCameraUID));
|
||||
|
||||
}
|
||||
|
||||
// ENVIRONMENT
|
||||
template<class Archive>
|
||||
void save(Archive& archive,
|
||||
EntityVector_Environment const& m_entityVector) {
|
||||
|
||||
archive(cereal::make_size_tag(static_cast<cereal::size_type>(m_entityVector.entities.size()))); // number of elements
|
||||
for (auto&& v : m_entityVector.entities)
|
||||
archive(v);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void load(Archive& archive,
|
||||
EntityVector_Environment& m_entityVector) {
|
||||
|
||||
cereal::size_type size;
|
||||
archive(cereal::make_size_tag(size));
|
||||
|
||||
m_entityVector.entities.resize(static_cast<std::size_t>(size));
|
||||
for (auto& v : m_entityVector.entities) {
|
||||
v = m_entityVector.environment->createEmptyEntity();
|
||||
archive(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
archive(serializationStruct);
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -1,12 +1,10 @@
|
||||
#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()));
|
||||
}
|
||||
}
|
||||
template <class Archive>
|
||||
void serialize(Archive& archive, Scene& m_scene) {
|
||||
archive(
|
||||
cereal::make_nvp("main_environment", m_scene.getMainEnviroment()));
|
||||
}
|
||||
} // namespace Deer
|
@ -1,28 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "Deer/Asset.h"
|
||||
|
||||
|
||||
#include "cereal/cereal.hpp"
|
||||
#include "cereal/types/vector.hpp"
|
||||
#include "cereal/types/string.hpp"
|
||||
#include "cereal/types/vector.hpp"
|
||||
|
||||
// Serialization Vars
|
||||
#include "Deer/Scene/Serialization/SerializationGlobalVars.h"
|
||||
|
||||
// GENERICS
|
||||
#include "Deer/Scene/Serialization/Vec3Serialization.h"
|
||||
#include "Deer/Scene/Serialization/QuatSerialization.h"
|
||||
#include "Deer/Scene/Serialization/Vec3Serialization.h"
|
||||
|
||||
// SCENE SPECIFIC
|
||||
#include "Deer/Scene/Serialization/SceneSerialization.h"
|
||||
#include "Deer/Scene/Serialization/EnvironmentSerialization.h"
|
||||
#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/TransformComponentSerialization.h"
|
||||
#include "Deer/Scene/Serialization/Components/RelationshipComponentSerialization.h"
|
||||
#include "Deer/Scene/Serialization/Components/ScriptComponentSerialization.h"
|
||||
#include "Deer/Scene/Serialization/Components/TransformComponentSerialization.h"
|
||||
|
||||
// RENDER SPECIFIC
|
||||
#ifdef DEER_RENDER
|
||||
|
@ -1,20 +1,17 @@
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
#include "angelscript.h"
|
||||
#include "scriptbuilder.h"
|
||||
#include "scriptstdstring.h"
|
||||
#include "scriptmath.h"
|
||||
|
||||
#include "ScriptEngineFunctions.h"
|
||||
|
||||
#include "Deer/ComponentScript.h"
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "Deer/ComponentScript.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "ScriptEngineFunctions.h"
|
||||
#include "angelscript.h"
|
||||
#include "scriptbuilder.h"
|
||||
#include "scriptmath.h"
|
||||
#include "scriptstdstring.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Deer {
|
||||
@ -22,30 +19,28 @@ namespace Deer {
|
||||
asIScriptEngine* m_scriptEngine;
|
||||
asIScriptModule* m_scriptModule;
|
||||
Scene* m_scene;
|
||||
|
||||
|
||||
bool m_isCompilationValid = false;
|
||||
|
||||
|
||||
asIScriptContext* m_context;
|
||||
ComponentScriptMap m_componentScripts;
|
||||
|
||||
void loadModuleFolder(const std::filesystem::path& modulePath, const char* moduleName);
|
||||
void registerBaseComponents();
|
||||
}
|
||||
|
||||
void ScriptEngine::shutdownScriptEngine() {
|
||||
m_componentScripts.clear();
|
||||
}
|
||||
void loadModuleFolder(const std::filesystem::path& modulePath,
|
||||
const char* moduleName);
|
||||
void registerBaseComponents();
|
||||
} // namespace ScriptEngine
|
||||
|
||||
void ScriptEngine::shutdownScriptEngine() { m_componentScripts.clear(); }
|
||||
|
||||
void ScriptEngine::beginExecutionContext(Scene* executingScene) {
|
||||
m_scene = executingScene;
|
||||
m_context = m_scriptEngine->CreateContext();
|
||||
}
|
||||
|
||||
void ScriptEngine::endExecutionContext() {
|
||||
m_context->Release();
|
||||
}
|
||||
void ScriptEngine::endExecutionContext() { m_context->Release(); }
|
||||
|
||||
void ScriptEngine::compileScriptEngine(const std::filesystem::path& modulePath) {
|
||||
void ScriptEngine::compileScriptEngine(
|
||||
const std::filesystem::path& modulePath) {
|
||||
m_scriptEngine = asCreateScriptEngine();
|
||||
m_isCompilationValid = true;
|
||||
|
||||
@ -53,7 +48,8 @@ namespace Deer {
|
||||
loadModuleFolder(modulePath, "Deer");
|
||||
|
||||
m_scriptModule = m_scriptEngine->GetModule("Deer");
|
||||
asITypeInfo* m_deerScript = m_scriptModule->GetTypeInfoByName("ComponentScript");
|
||||
asITypeInfo* m_deerScript =
|
||||
m_scriptModule->GetTypeInfoByName("ComponentScript");
|
||||
|
||||
int classCount = m_scriptModule->GetObjectTypeCount();
|
||||
for (int i = 0; i < classCount; i++) {
|
||||
@ -64,12 +60,13 @@ namespace Deer {
|
||||
|
||||
if (parent == m_deerScript) {
|
||||
ComponentScript componentScript(type);
|
||||
m_componentScripts.insert({ scriptID, componentScript });
|
||||
m_componentScripts.insert({scriptID, componentScript});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<ComponentScriptInstance> ScriptEngine::createComponentScriptInstance(const std::string& scriptID, Entity& scriptEntity) {
|
||||
Ref<ComponentScriptInstance> ScriptEngine::createComponentScriptInstance(
|
||||
const std::string& scriptID, Entity& scriptEntity) {
|
||||
ComponentScript& script = getComponentScript(scriptID);
|
||||
asITypeInfo* type = script.getTypeInfo();
|
||||
|
||||
@ -78,34 +75,43 @@ namespace Deer {
|
||||
std::string factoryString(script.getName());
|
||||
factoryString = factoryString + " @" + script.getName() + "()";
|
||||
|
||||
asIScriptFunction* function = type->GetFactoryByDecl(factoryString.c_str());
|
||||
asIScriptFunction* function =
|
||||
type->GetFactoryByDecl(factoryString.c_str());
|
||||
if (!function) {
|
||||
DEER_SCRIPT_ERROR("Function constructor not found for class {0}", script.getName());
|
||||
DEER_SCRIPT_ERROR("Function constructor not found for class {0}",
|
||||
script.getName());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int r = m_context->Prepare(function);
|
||||
if (r < 0) {
|
||||
DEER_SCRIPT_ERROR("Failed to prepare constructor context for class {0}", script.getName());
|
||||
DEER_SCRIPT_ERROR(
|
||||
"Failed to prepare constructor context for class {0}",
|
||||
script.getName());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
r = m_context->Execute();
|
||||
if (r < 0) {
|
||||
DEER_SCRIPT_ERROR("Failed to execute constructor for class {0}", script.getName());
|
||||
DEER_SCRIPT_ERROR("Failed to execute constructor for class {0}",
|
||||
script.getName());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
asIScriptObject* obj = *(asIScriptObject**)m_context->GetAddressOfReturnValue();
|
||||
asIScriptObject* obj =
|
||||
*(asIScriptObject**)m_context->GetAddressOfReturnValue();
|
||||
obj->AddRef();
|
||||
|
||||
int entityPosition = script.getAttribute("entity").internalID;
|
||||
unsigned int* entityValue = (unsigned int*)obj->GetAddressOfProperty(entityPosition);
|
||||
unsigned int* entityValue =
|
||||
(unsigned int*)obj->GetAddressOfProperty(entityPosition);
|
||||
|
||||
*entityValue = scriptEntity.getUID();
|
||||
|
||||
asIScriptFunction* updateFunction = type->GetMethodByDecl("void update()");
|
||||
asIScriptFunction* startFunction = type->GetMethodByDecl("void start()");
|
||||
*entityValue = scriptEntity.getId();
|
||||
|
||||
asIScriptFunction* updateFunction =
|
||||
type->GetMethodByDecl("void update()");
|
||||
asIScriptFunction* startFunction =
|
||||
type->GetMethodByDecl("void start()");
|
||||
instance->m_updateFunction = updateFunction;
|
||||
instance->m_startFuction = startFunction;
|
||||
instance->m_object = obj;
|
||||
@ -113,30 +119,41 @@ namespace Deer {
|
||||
return Ref<ComponentScriptInstance>(instance);
|
||||
}
|
||||
|
||||
void ScriptEngine::loadModuleFolder(const std::filesystem::path& modulePath, const char* moduleName) {
|
||||
void ScriptEngine::loadModuleFolder(const std::filesystem::path& modulePath,
|
||||
const char* moduleName) {
|
||||
CScriptBuilder builder;
|
||||
|
||||
int r = builder.StartNewModule(m_scriptEngine, moduleName);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Unrecoverable error while starting a new module. {0}", moduleName);
|
||||
DEER_SCRIPT_ASSERT(
|
||||
r >= 0, "Unrecoverable error while starting a new module. {0}",
|
||||
moduleName);
|
||||
|
||||
try {
|
||||
DEER_CORE_INFO("=== Loading Scripts ===");
|
||||
for (const auto& entry : fs::recursive_directory_iterator(modulePath)) {
|
||||
if (fs::is_regular_file(entry) && entry.path().extension() == ".as") {
|
||||
for (const auto& entry :
|
||||
fs::recursive_directory_iterator(modulePath)) {
|
||||
if (fs::is_regular_file(entry) &&
|
||||
entry.path().extension() == ".as") {
|
||||
r = builder.AddSectionFromFile(
|
||||
entry.path().generic_string().c_str());
|
||||
DEER_SCRIPT_ASSERT(r >= 0,
|
||||
"Please correct the errors in the "
|
||||
"script and try again. {0}",
|
||||
entry.path().generic_string().c_str());
|
||||
|
||||
r = builder.AddSectionFromFile(entry.path().generic_string().c_str());
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Please correct the errors in the script and try again. {0}", entry.path().generic_string().c_str());
|
||||
|
||||
DEER_CORE_TRACE(" {0}", entry.path().filename().string().c_str());
|
||||
DEER_CORE_TRACE(" {0}",
|
||||
entry.path().filename().string().c_str());
|
||||
}
|
||||
}
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
DEER_CORE_ERROR("Error while loading scripts, error: {0}", e.what());
|
||||
DEER_CORE_ERROR("Error while loading scripts, error: {0}",
|
||||
e.what());
|
||||
}
|
||||
|
||||
r = builder.BuildModule();
|
||||
if (r < 0) {
|
||||
DEER_SCRIPT_INFO("Please correct the errors in the script and try again.");
|
||||
DEER_SCRIPT_INFO(
|
||||
"Please correct the errors in the script and try again.");
|
||||
m_isCompilationValid = false;
|
||||
}
|
||||
}
|
||||
@ -154,4 +171,4 @@ namespace Deer {
|
||||
registerInputFunctions(m_scriptEngine);
|
||||
registerEntityTransformFunctions(m_scriptEngine);
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -1,201 +1,249 @@
|
||||
#include "ScriptEngineFunctions.h"
|
||||
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "angelscript.h"
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "DeerRender/Input.h"
|
||||
|
||||
#include "angelscript.h"
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
namespace Deer {
|
||||
void messageCallback(const asSMessageInfo* msg, void* param) {
|
||||
if (msg->type == asMSGTYPE_WARNING) {
|
||||
DEER_SCRIPT_WARN("({0} {1}) : {2} {3}", msg->row, msg->col, msg->message, msg->section);
|
||||
}
|
||||
else if (msg->type == asMSGTYPE_ERROR) {
|
||||
DEER_SCRIPT_ERROR("({0} {1}) : {2} {3}", msg->row, msg->col, msg->message, msg->section);
|
||||
}
|
||||
else if (msg->type == asMSGTYPE_INFORMATION) {
|
||||
DEER_SCRIPT_INFO("({0} {1}) : {2} {3}", msg->row, msg->col, msg->message, msg->section);
|
||||
}
|
||||
else {
|
||||
DEER_SCRIPT_WARN("({0} {1}) : {2} {3}", msg->row, msg->col, msg->message, msg->section);
|
||||
}
|
||||
}
|
||||
void messageCallback(const asSMessageInfo* msg, void* param) {
|
||||
if (msg->type == asMSGTYPE_WARNING) {
|
||||
DEER_SCRIPT_WARN("({0} {1}) : {2} {3}", msg->row, msg->col,
|
||||
msg->message, msg->section);
|
||||
} else if (msg->type == asMSGTYPE_ERROR) {
|
||||
DEER_SCRIPT_ERROR("({0} {1}) : {2} {3}", msg->row, msg->col,
|
||||
msg->message, msg->section);
|
||||
} else if (msg->type == asMSGTYPE_INFORMATION) {
|
||||
DEER_SCRIPT_INFO("({0} {1}) : {2} {3}", msg->row, msg->col,
|
||||
msg->message, msg->section);
|
||||
} else {
|
||||
DEER_SCRIPT_WARN("({0} {1}) : {2} {3}", msg->row, msg->col,
|
||||
msg->message, msg->section);
|
||||
}
|
||||
}
|
||||
|
||||
void print(std::string& msg) {
|
||||
DEER_SCRIPT_INFO(msg.c_str());
|
||||
}
|
||||
void print(std::string& msg) { DEER_SCRIPT_INFO(msg.c_str()); }
|
||||
|
||||
glm::vec3 getEntityPosition(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return glm::vec3();
|
||||
}
|
||||
glm::vec3 getEntityPosition(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
return entt.getComponent<TransformComponent>().position;
|
||||
}
|
||||
return entt.getComponent<TransformComponent>().position;
|
||||
}
|
||||
|
||||
void setEntityPosition(glm::vec3 position, uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return;
|
||||
}
|
||||
void setEntityPosition(glm::vec3 position, uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
entt.getComponent<TransformComponent>().position = position;
|
||||
}
|
||||
entt.getComponent<TransformComponent>().position = position;
|
||||
}
|
||||
|
||||
glm::vec3 getEntityScale(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return glm::vec3();
|
||||
}
|
||||
glm::vec3 getEntityScale(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
return entt.getComponent<TransformComponent>().scale;
|
||||
}
|
||||
return entt.getComponent<TransformComponent>().scale;
|
||||
}
|
||||
|
||||
void setEntityScale(glm::vec3 scale, uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return;
|
||||
}
|
||||
void setEntityScale(glm::vec3 scale, uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
entt.getComponent<TransformComponent>().scale = scale;
|
||||
}
|
||||
entt.getComponent<TransformComponent>().scale = scale;
|
||||
}
|
||||
|
||||
uint32_t getEntityParent(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return 0;
|
||||
}
|
||||
uint32_t getEntityParent(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) {
|
||||
DEER_SCRIPT_ERROR("Entity is not invalid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
return entt.getParentUID();
|
||||
}
|
||||
return entt.getParentId();
|
||||
}
|
||||
|
||||
bool isEntityValid(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1)
|
||||
return false;
|
||||
bool isEntityValid(uint32_t& entityUID) {
|
||||
if (entityUID == 0 || entityUID == 1) return false;
|
||||
|
||||
Ref<Environment>& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment->getEntity(entityUID);
|
||||
Environment& m_environment = ScriptEngine::m_scene->getMainEnviroment();
|
||||
Entity& entt = m_environment.getEntity(entityUID);
|
||||
|
||||
return entt.isValid();
|
||||
}
|
||||
return entt.isValid();
|
||||
}
|
||||
|
||||
void registerVec3(asIScriptEngine* engine) {
|
||||
engine->RegisterObjectType("Vec3", sizeof(glm::vec3), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::vec3>() | asOBJ_APP_CLASS_ALLFLOATS);
|
||||
void registerVec3(asIScriptEngine* engine) {
|
||||
engine->RegisterObjectType("Vec3", sizeof(glm::vec3),
|
||||
asOBJ_VALUE | asOBJ_POD |
|
||||
asGetTypeTraits<glm::vec3>() |
|
||||
asOBJ_APP_CLASS_ALLFLOATS);
|
||||
|
||||
engine->RegisterObjectBehaviour("Vec3", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR([](void* memory) {
|
||||
new (memory) glm::vec3();
|
||||
}, (void*), void), asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectBehaviour("Vec3", asBEHAVE_CONSTRUCT, "void f(float, float = 0, float = 0)", asFUNCTIONPR([](float x, float y, float z, void* memory) {
|
||||
new (memory) glm::vec3(x, y, z);
|
||||
}, (float, float, float, void*), void), asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectProperty("Vec3", "float x", asOFFSET(glm::vec3, x));
|
||||
engine->RegisterObjectProperty("Vec3", "float y", asOFFSET(glm::vec3, y));
|
||||
engine->RegisterObjectProperty("Vec3", "float z", asOFFSET(glm::vec3, z));
|
||||
engine->RegisterObjectBehaviour(
|
||||
"Vec3", asBEHAVE_CONSTRUCT, "void f()",
|
||||
asFUNCTIONPR([](void* memory) { new (memory) glm::vec3(); },
|
||||
(void*), void),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectBehaviour(
|
||||
"Vec3", asBEHAVE_CONSTRUCT, "void f(float, float = 0, float = 0)",
|
||||
asFUNCTIONPR([](float x, float y, float z,
|
||||
void* memory) { new (memory) glm::vec3(x, y, z); },
|
||||
(float, float, float, void*), void),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectProperty("Vec3", "float x",
|
||||
asOFFSET(glm::vec3, x));
|
||||
engine->RegisterObjectProperty("Vec3", "float y",
|
||||
asOFFSET(glm::vec3, y));
|
||||
engine->RegisterObjectProperty("Vec3", "float z",
|
||||
asOFFSET(glm::vec3, z));
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 opAdd(const Vec3 &in) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a, const glm::vec3& b) -> glm::vec3 {
|
||||
return a + b;
|
||||
}, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 opAdd(const Vec3 &in) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a,
|
||||
const glm::vec3& b) -> glm::vec3 { return a + b; },
|
||||
(const glm::vec3&, const glm::vec3&), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 opSub(const Vec3 &in) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a, const glm::vec3& b) {
|
||||
return a - b;
|
||||
}, (const glm::vec3&, const glm::vec3&), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 opSub(const Vec3 &in) const",
|
||||
asFUNCTIONPR(
|
||||
[](const glm::vec3& a, const glm::vec3& b) { return a - b; },
|
||||
(const glm::vec3&, const glm::vec3&), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 opMul(float) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a, float scalar) {
|
||||
return a * scalar;
|
||||
}, (const glm::vec3&, float), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 opMul(float) const",
|
||||
asFUNCTIONPR(
|
||||
[](const glm::vec3& a, float scalar) { return a * scalar; },
|
||||
(const glm::vec3&, float), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 opDiv(float) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a, float scalar) {
|
||||
return a / scalar;
|
||||
}, (const glm::vec3&, float), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 opDiv(float) const",
|
||||
asFUNCTIONPR(
|
||||
[](const glm::vec3& a, float scalar) { return a / scalar; },
|
||||
(const glm::vec3&, float), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 normalize() const",
|
||||
asFUNCTIONPR(glm::normalize, (const glm::vec3&), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 normalize() const",
|
||||
asFUNCTIONPR(glm::normalize, (const glm::vec3&), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "float getMagnitude() const",
|
||||
asFUNCTIONPR(glm::length, (const glm::vec3&), float), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "float getMagnitude() const",
|
||||
asFUNCTIONPR(glm::length, (const glm::vec3&), float),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "Vec3 opNeg() const",
|
||||
asFUNCTIONPR([](const glm::vec3& a) {
|
||||
return -a;
|
||||
}, (const glm::vec3&), glm::vec3), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "Vec3 opNeg() const",
|
||||
asFUNCTIONPR([](const glm::vec3& a) { return -a; },
|
||||
(const glm::vec3&), glm::vec3),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "bool opEquals(const Vec3 &in) const",
|
||||
asFUNCTIONPR([](const glm::vec3& a, const glm::vec3& b) {
|
||||
return a == b;
|
||||
}, (const glm::vec3&, const glm::vec3&), bool), asCALL_CDECL_OBJFIRST);
|
||||
engine->RegisterObjectMethod(
|
||||
"Vec3", "bool opEquals(const Vec3 &in) const",
|
||||
asFUNCTIONPR(
|
||||
[](const glm::vec3& a, const glm::vec3& b) { return a == b; },
|
||||
(const glm::vec3&, const glm::vec3&), bool),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
|
||||
engine->RegisterObjectMethod("Vec3", "string opImplConv() const",
|
||||
asFUNCTIONPR([](const glm::vec3& a) {
|
||||
// Example string conversion using glm (you may need to format it)
|
||||
char buffer[64];
|
||||
snprintf(buffer, sizeof(buffer), "(%.2f, %.2f, %.2f)", a.x, a.y, a.z);
|
||||
return std::string(buffer);
|
||||
}, (const glm::vec3&), std::string), asCALL_CDECL_OBJFIRST);
|
||||
}
|
||||
engine->RegisterObjectMethod("Vec3", "string opImplConv() const",
|
||||
asFUNCTIONPR(
|
||||
[](const glm::vec3& a) {
|
||||
// Example string conversion using
|
||||
// glm (you may need to format it)
|
||||
char buffer[64];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"(%.2f, %.2f, %.2f)", a.x,
|
||||
a.y, a.z);
|
||||
return std::string(buffer);
|
||||
},
|
||||
(const glm::vec3&), std::string),
|
||||
asCALL_CDECL_OBJFIRST);
|
||||
}
|
||||
|
||||
void registerEntity(asIScriptEngine* engine) {
|
||||
engine->RegisterObjectType("Entity", sizeof(unsigned int), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
|
||||
engine->RegisterObjectProperty("Entity", "uint uint32_t", 0);
|
||||
void registerEntity(asIScriptEngine* engine) {
|
||||
engine->RegisterObjectType(
|
||||
"Entity", sizeof(unsigned int),
|
||||
asOBJ_VALUE | asOBJ_POD | asOBJ_APP_PRIMITIVE);
|
||||
engine->RegisterObjectProperty("Entity", "uint uint32_t", 0);
|
||||
|
||||
engine->RegisterObjectMethod("Entity", "Entity getParent()", asFUNCTION(Deer::getEntityParent), asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectMethod("Entity", "bool isValid()", asFUNCTION(Deer::isEntityValid), asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectMethod("Entity", "Entity getParent()",
|
||||
asFUNCTION(Deer::getEntityParent),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
engine->RegisterObjectMethod("Entity", "bool isValid()",
|
||||
asFUNCTION(Deer::isEntityValid),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
|
||||
engine->RegisterGlobalFunction("Entity getEntity(uint)", asFUNCTIONPR([](uint32_t id) {
|
||||
return id;
|
||||
}, (uint32_t), uint32_t), asCALL_CDECL);
|
||||
engine->RegisterGlobalFunction(
|
||||
"Entity getEntity(uint)",
|
||||
asFUNCTIONPR([](uint32_t id) { return id; }, (uint32_t), uint32_t),
|
||||
asCALL_CDECL);
|
||||
}
|
||||
|
||||
}
|
||||
void registerDeerFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->SetMessageCallback(
|
||||
asFUNCTION(Deer::messageCallback), 0, asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up angel script");
|
||||
|
||||
void registerDeerFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->SetMessageCallback(asFUNCTION(Deer::messageCallback), 0, asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up angel script");
|
||||
r = scriptEngine->RegisterGlobalFunction("void print(const string &in)",
|
||||
asFUNCTION(Deer::print),
|
||||
asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0,
|
||||
"Error in seting up void print(const string &in)");
|
||||
}
|
||||
|
||||
r = scriptEngine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(Deer::print), asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up void print(const string &in)");
|
||||
}
|
||||
void registerInputFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->RegisterGlobalFunction(
|
||||
"bool isKeyPressed(int)", asFUNCTION(Deer::Input::isKeyPressed),
|
||||
asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up bool isKeyPressed(int)");
|
||||
}
|
||||
|
||||
void registerInputFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->RegisterGlobalFunction("bool isKeyPressed(int)", asFUNCTION(Deer::Input::isKeyPressed), asCALL_CDECL);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up bool isKeyPressed(int)");
|
||||
}
|
||||
void registerEntityTransformFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->RegisterObjectMethod(
|
||||
"Entity", "Vec3 getPosition()", asFUNCTION(Deer::getEntityPosition),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up Vec3 getPosition()");
|
||||
|
||||
void registerEntityTransformFunctions(asIScriptEngine* scriptEngine) {
|
||||
int r = scriptEngine->RegisterObjectMethod("Entity", "Vec3 getPosition()", asFUNCTION(Deer::getEntityPosition), asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up Vec3 getPosition()");
|
||||
|
||||
scriptEngine->RegisterObjectMethod("Entity", "void setPosition(Vec3)", asFUNCTION(Deer::setEntityPosition), asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up void setPosition(Vec3)");
|
||||
|
||||
r = scriptEngine->RegisterObjectMethod("Entity", "Vec3 getScale()", asFUNCTION(Deer::getEntityScale), asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up Vec3 getScale()");
|
||||
scriptEngine->RegisterObjectMethod("Entity", "void setPosition(Vec3)",
|
||||
asFUNCTION(Deer::setEntityPosition),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up void setPosition(Vec3)");
|
||||
|
||||
scriptEngine->RegisterObjectMethod("Entity", "void setScale(Vec3)", asFUNCTION(Deer::setEntityScale), asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up void setScale(Vec3)");
|
||||
}
|
||||
r = scriptEngine->RegisterObjectMethod("Entity", "Vec3 getScale()",
|
||||
asFUNCTION(Deer::getEntityScale),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up Vec3 getScale()");
|
||||
|
||||
}
|
||||
scriptEngine->RegisterObjectMethod("Entity", "void setScale(Vec3)",
|
||||
asFUNCTION(Deer::setEntityScale),
|
||||
asCALL_CDECL_OBJLAST);
|
||||
DEER_SCRIPT_ASSERT(r >= 0, "Error in seting up void setScale(Vec3)");
|
||||
}
|
||||
|
||||
} // namespace Deer
|
@ -1,4 +1,5 @@
|
||||
#include "Deer/VoxelWorld.h"
|
||||
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Voxels/Chunk.h"
|
||||
#include "Deer/Voxels/Layer.h"
|
||||
@ -8,19 +9,22 @@
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
namespace Deer {
|
||||
VoxelWorld::VoxelWorld(const VoxelWorldProps& props)
|
||||
: m_worldProps(props) {
|
||||
VoxelWorld::VoxelWorld(const VoxelWorldProps& props) : m_worldProps(props) {
|
||||
m_chunks = MakeScope<Chunk[]>(m_worldProps.getChunkCount());
|
||||
m_layers = MakeScope<Layer[]>(m_worldProps.getLayerCount());
|
||||
#ifdef DEER_RENDER
|
||||
m_renderData = MakeScope<VoxelWorldRenderData>(m_worldProps.getChunkCount());
|
||||
m_renderData =
|
||||
MakeScope<VoxelWorldRenderData>(m_worldProps.getChunkCount());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
VoxelWorld::~VoxelWorld() {}
|
||||
|
||||
uint16_t VoxelWorld::calculateLayerVoxelHeight(int x, int z) {
|
||||
LayerVoxelID layerVoxelID;
|
||||
LayerID layerID;
|
||||
@ -32,7 +36,8 @@ namespace Deer {
|
||||
chunkID.y = y;
|
||||
|
||||
Chunk& chunk = m_chunks[m_worldProps.getWorldChunkID(chunkID)];
|
||||
uint8_t chunkVoxelHeight = chunk.calculateLayerVoxelHeight(layerVoxelID);
|
||||
uint8_t chunkVoxelHeight =
|
||||
chunk.calculateLayerVoxelHeight(layerVoxelID);
|
||||
|
||||
if (chunkVoxelHeight != 0) {
|
||||
return chunkVoxelHeight + chunkID.y * CHUNK_SIZE_Y;
|
||||
@ -40,4 +45,4 @@ namespace Deer {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
||||
|
@ -1,20 +1,22 @@
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
#include "Deer/Components.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "DeerRender/Render/RenderCommand.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
namespace Deer {
|
||||
Scene::~Scene() {}
|
||||
|
||||
void Scene::render() {
|
||||
uint32_t mainCamera = m_enviroment->tryGetMainCamera();
|
||||
if (mainCamera == 0)
|
||||
return;
|
||||
if (mainCamera == 0) return;
|
||||
|
||||
Entity& m_cameraEntity = m_enviroment->getEntity(mainCamera);
|
||||
SceneCamera sceneCamera;
|
||||
sceneCamera.camera = m_cameraEntity.getComponent<CameraComponent>();
|
||||
sceneCamera.transform = m_cameraEntity.getComponent<TransformComponent>();
|
||||
sceneCamera.transform =
|
||||
m_cameraEntity.getComponent<TransformComponent>();
|
||||
|
||||
Scene::render(sceneCamera);
|
||||
}
|
||||
@ -22,10 +24,9 @@ namespace Deer {
|
||||
void Scene::render(SceneCamera sceneCamera) {
|
||||
RenderCommand::setDepthBuffer(true);
|
||||
m_enviroment->render(sceneCamera);
|
||||
if (m_voxelWorld)
|
||||
m_voxelWorld->render(sceneCamera);
|
||||
if (m_voxelWorld) m_voxelWorld->render(sceneCamera);
|
||||
RenderCommand::setDepthBuffer(false);
|
||||
m_gizmoRenderer.render(sceneCamera);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Deer
|
||||
|
@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "Deer/Memory.h"
|
||||
#include "Deer/Voxel.h"
|
||||
|
||||
#include "DeerRender/Render/VertexArray.h"
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace Deer {
|
||||
struct ChunkRender {
|
||||
Ref<VertexArray> solidVoxel;
|
||||
@ -36,30 +35,31 @@ namespace Deer {
|
||||
};
|
||||
|
||||
class ChunkUpdateQueue {
|
||||
public:
|
||||
public:
|
||||
// TODO: Add priority
|
||||
void addChunk(ChunkID);
|
||||
ChunkID pullChunk();
|
||||
bool hasChunk();
|
||||
private:
|
||||
|
||||
private:
|
||||
std::queue<ChunkID> m_updateOrder;
|
||||
std::unordered_set<ChunkID, ChunkIDHash> m_containingChunks;
|
||||
};
|
||||
|
||||
struct VoxelWorldRenderData {
|
||||
VoxelWorldRenderData(size_t chunkCount) {
|
||||
chunksRender = MakeScope<ChunkRender[]>(chunkCount);
|
||||
}
|
||||
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
struct VoxelWorldRenderData {
|
||||
VoxelWorldRenderData(size_t chunkCount) {
|
||||
chunksRender = MakeScope<ChunkRender[]>(chunkCount);
|
||||
}
|
||||
|
||||
// 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;
|
||||
};
|
||||
} // namespace Deer
|
127
Deer/vendor/ImGuizmo/ImGuizmo.h
vendored
127
Deer/vendor/ImGuizmo/ImGuizmo.h
vendored
@ -2,19 +2,19 @@
|
||||
// v 1.61 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
//
|
||||
// Copyright(c) 2016 Cedric Guillemet
|
||||
//
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
@ -26,22 +26,25 @@
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// History :
|
||||
// 2019/11/03 View gizmo
|
||||
// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
|
||||
// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
|
||||
// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
|
||||
// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
|
||||
// 2016/08/31 First version
|
||||
// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by
|
||||
// source matrix scales. local/world rotation and translation fixed. Display
|
||||
// message is incorrect (X: ... Y:...) in local mode. 2016/09/09 Hatched
|
||||
// negative axis. Snapping. Documentation update. 2016/09/04 Axis switch and
|
||||
// translation plan autohiding. Scale transform stability improved 2016/09/01
|
||||
// Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing
|
||||
// scale and translation/rotation gives bad results. 2016/08/31 First version
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Future (no order):
|
||||
//
|
||||
// - Multi view
|
||||
// - display rotation/translation/scale infos in local/world space and not only local
|
||||
// - display rotation/translation/scale infos in local/world space and not only
|
||||
// local
|
||||
// - finish local/world matrix application
|
||||
// - OPERATION as bitmask
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Example
|
||||
// Example
|
||||
#if 0
|
||||
void EditTransform(const Camera& camera, matrix_t& matrix)
|
||||
{
|
||||
@ -111,16 +114,17 @@ void EditTransform(const Camera& camera, matrix_t& matrix)
|
||||
#define IMGUI_API
|
||||
#endif
|
||||
|
||||
namespace ImGuizmo
|
||||
{
|
||||
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
|
||||
// Or pass a specific ImDrawList to draw to (e.g. ImGui::GetForegroundDrawList()).
|
||||
IMGUI_API void SetDrawlist(ImDrawList* drawlist = nullptr);
|
||||
namespace ImGuizmo {
|
||||
// call inside your own window and before Manipulate() in order to draw
|
||||
// gizmo to that window. Or pass a specific ImDrawList to draw to (e.g.
|
||||
// ImGui::GetForegroundDrawList()).
|
||||
IMGUI_API void SetDrawlist(ImDrawList *drawlist = nullptr);
|
||||
|
||||
// call BeginFrame right after ImGui_XXXX_NewFrame();
|
||||
IMGUI_API void BeginFrame();
|
||||
|
||||
// return true if mouse cursor is over any gizmo control (axis, plan or screen component)
|
||||
// return true if mouse cursor is over any gizmo control (axis, plan or
|
||||
// screen component)
|
||||
IMGUI_API bool IsOver();
|
||||
|
||||
// return true if mouse IsOver or if the gizmo is in moving state
|
||||
@ -130,58 +134,71 @@ namespace ImGuizmo
|
||||
// gizmo is rendered with gray half transparent color when disabled
|
||||
IMGUI_API void Enable(bool enable);
|
||||
|
||||
// helper functions for manualy editing translation/rotation/scale with an input float
|
||||
// translation, rotation and scale float points to 3 floats each
|
||||
// helper functions for manualy editing translation/rotation/scale with an
|
||||
// input float translation, rotation and scale float points to 3 floats each
|
||||
// Angles are in degrees (more suitable for human editing)
|
||||
// example:
|
||||
// float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
// ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
// ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
// ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
|
||||
// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation,
|
||||
// matrixRotation, matrixScale); ImGui::InputFloat3("Tr", matrixTranslation,
|
||||
// 3); ImGui::InputFloat3("Rt", matrixRotation, 3); ImGui::InputFloat3("Sc",
|
||||
// matrixScale, 3);
|
||||
// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation,
|
||||
// matrixRotation, matrixScale, gizmoMatrix.m16);
|
||||
//
|
||||
// These functions have some numerical stability issues for now. Use with caution.
|
||||
IMGUI_API void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale);
|
||||
IMGUI_API void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix);
|
||||
// These functions have some numerical stability issues for now. Use with
|
||||
// caution.
|
||||
IMGUI_API void DecomposeMatrixToComponents(const float *matrix,
|
||||
float *translation,
|
||||
float *rotation, float *scale);
|
||||
IMGUI_API void RecomposeMatrixFromComponents(const float *translation,
|
||||
const float *rotation,
|
||||
const float *scale,
|
||||
float *matrix);
|
||||
|
||||
IMGUI_API void SetRect(float x, float y, float width, float height);
|
||||
// default is false
|
||||
IMGUI_API void SetOrthographic(bool isOrthographic);
|
||||
|
||||
// Render a cube with face color corresponding to face normal. Usefull for debug/tests
|
||||
IMGUI_API void DrawCubes(const float *view, const float *projection, const float *matrices, int matrixCount);
|
||||
IMGUI_API void DrawGrid(const float *view, const float *projection, const float *matrix, const float gridSize);
|
||||
// Render a cube with face color corresponding to face normal. Usefull for
|
||||
// debug/tests
|
||||
IMGUI_API void DrawCubes(const float *view, const float *projection,
|
||||
const float *matrices, int matrixCount);
|
||||
IMGUI_API void DrawGrid(const float *view, const float *projection,
|
||||
const float *matrix, const float gridSize);
|
||||
|
||||
// call it when you want a gizmo
|
||||
// Needs view and projection matrices.
|
||||
// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
|
||||
// Needs view and projection matrices.
|
||||
// matrix parameter is the source matrix (where will be gizmo be drawn) and
|
||||
// might be transformed by the function. Return deltaMatrix is optional
|
||||
// translation is applied in world space
|
||||
enum OPERATION
|
||||
{
|
||||
enum OPERATION {
|
||||
TRANSLATE,
|
||||
ROTATE,
|
||||
SCALE,
|
||||
BOUNDS,
|
||||
};
|
||||
|
||||
enum MODE
|
||||
{
|
||||
LOCAL,
|
||||
WORLD
|
||||
};
|
||||
enum MODE { LOCAL, WORLD };
|
||||
|
||||
IMGUI_API bool Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = NULL, float *snap = NULL, float *localBounds = NULL, float *boundsSnap = NULL);
|
||||
//
|
||||
// Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en
|
||||
// It seems to be a defensive patent in the US. I don't think it will bring troubles using it as
|
||||
// other software are using the same mechanics. But just in case, you are now warned!
|
||||
//
|
||||
IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
|
||||
|
||||
IMGUI_API void SetID(int id);
|
||||
|
||||
// return true if the cursor is over the operation's gizmo
|
||||
IMGUI_API bool IsOver(OPERATION op);
|
||||
IMGUI_API bool Manipulate(const float *view, const float *projection,
|
||||
OPERATION operation, MODE mode, float *matrix,
|
||||
float *deltaMatrix = NULL, float *snap = NULL,
|
||||
float *localBounds = NULL,
|
||||
float *boundsSnap = NULL);
|
||||
//
|
||||
// Please note that this cubeview is patented by Autodesk :
|
||||
// https://patents.google.com/patent/US7782319B2/en It seems to be a
|
||||
// defensive patent in the US. I don't think it will bring troubles using it
|
||||
// as other software are using the same mechanics. But just in case, you are
|
||||
// now warned!
|
||||
//
|
||||
IMGUI_API void ViewManipulate(float *view, float length, ImVec2 position,
|
||||
ImVec2 size, ImU32 backgroundColor);
|
||||
|
||||
IMGUI_API void SetID(int id);
|
||||
|
||||
// return true if the cursor is over the operation's gizmo
|
||||
IMGUI_API bool IsOver(OPERATION op);
|
||||
IMGUI_API void SetGizmoSizeClipSpace(float value);
|
||||
};
|
||||
}; // namespace ImGuizmo
|
||||
|
@ -1,246 +1,241 @@
|
||||
#include "DeerStudio.h"
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "Deer/DataStore.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
|
||||
#include "DeerStudio/Editor/PropertiesPannel.h"
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "DeerStudio/Editor/GamePannel.h"
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
#include "DeerStudio/Editor/PropertiesPannel.h"
|
||||
#include "DeerStudio/Editor/SceneExplorer.h"
|
||||
#include "DeerStudio/Editor/Terrain/TerrainEditor.h"
|
||||
#include "DeerStudio/Editor/TreePannel.h"
|
||||
#include "DeerStudio/Editor/Viewport.h"
|
||||
#include "DeerStudio/Editor/Terrain/TerrainEditor.h"
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
|
||||
#include "Style.h"
|
||||
#include <functional>
|
||||
|
||||
namespace Deer {
|
||||
int DeerStudioApplication::onPreInit() {
|
||||
Path projectPath = Application::m_window->folderDialog(nullptr);
|
||||
if (projectPath.empty())
|
||||
return 1;
|
||||
int DeerStudioApplication::onPreInit() {
|
||||
Path projectPath = Application::m_window->folderDialog(nullptr);
|
||||
if (projectPath.empty()) return 1;
|
||||
|
||||
DataStore::rootPath = projectPath;
|
||||
VoxelData::createExampleVoxelData();
|
||||
VoxelData::createExampleVoxelAspect();
|
||||
VoxelData::loadVoxelsData();
|
||||
VoxelData::loadVoxelsAspect();
|
||||
return 0;
|
||||
}
|
||||
DataStore::rootPath = projectPath;
|
||||
VoxelData::createExampleVoxelData();
|
||||
VoxelData::createExampleVoxelAspect();
|
||||
VoxelData::loadVoxelsData();
|
||||
VoxelData::loadVoxelsAspect();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DeerStudioApplication::onInit() {
|
||||
VoxelData::generateTextureAtlas();
|
||||
VoxelData::loadVoxelsShaders();
|
||||
ScriptEngine::compileScriptEngine(DataStore::rootPath / std::filesystem::path("scripts"));
|
||||
int DeerStudioApplication::onInit() {
|
||||
VoxelData::generateTextureAtlas();
|
||||
VoxelData::loadVoxelsShaders();
|
||||
ScriptEngine::compileScriptEngine(DataStore::rootPath /
|
||||
std::filesystem::path("scripts"));
|
||||
|
||||
Icons::setupIcons();
|
||||
Icons::setupIcons();
|
||||
|
||||
// IMGUI STYLE
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
|
||||
std::string fLoc = (DataStore::rootPath / "imgui.ini").generic_string();
|
||||
char* filenameFLoc = new char[fLoc.size() + 1]();
|
||||
strcpy(filenameFLoc, fLoc.c_str());
|
||||
io.IniFilename = filenameFLoc;
|
||||
ImFontConfig cnfg;
|
||||
//cnfg.SizePixels = 26
|
||||
Path rfPath = DataStore::rootPath / "editor/fonts/Roboto-Regular.ttf";
|
||||
io.Fonts->AddFontFromFileTTF(rfPath.generic_string().c_str(), 18);
|
||||
//io.Fonts->AddFontDefault(&cnfg);
|
||||
|
||||
setNatureStyle();
|
||||
// IMGUI STYLE
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
|
||||
auto m_gamePannel = Ref<GamePannel>(new GamePannel());
|
||||
std::string fLoc = (DataStore::rootPath / "imgui.ini").generic_string();
|
||||
char* filenameFLoc = new char[fLoc.size() + 1]();
|
||||
strcpy(filenameFLoc, fLoc.c_str());
|
||||
io.IniFilename = filenameFLoc;
|
||||
ImFontConfig cnfg;
|
||||
// cnfg.SizePixels = 26
|
||||
Path rfPath = DataStore::rootPath / "editor/fonts/Roboto-Regular.ttf";
|
||||
io.Fonts->AddFontFromFileTTF(rfPath.generic_string().c_str(), 18);
|
||||
// io.Fonts->AddFontDefault(&cnfg);
|
||||
|
||||
pannels.push_back(m_gamePannel);
|
||||
setNatureStyle();
|
||||
|
||||
return 0;
|
||||
}
|
||||
auto m_gamePannel = Ref<GamePannel>(new GamePannel());
|
||||
|
||||
void DeerStudioApplication::onShutdown() {
|
||||
if (Project::m_scene.getExecutingState())
|
||||
Project::m_scene.endExecution();
|
||||
pannels.push_back(m_gamePannel);
|
||||
|
||||
ScriptEngine::shutdownScriptEngine();
|
||||
pannels.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeerStudioApplication::onRender(Timestep delta) {
|
||||
for (auto pannel : pannels) {
|
||||
pannel->onRender(delta);
|
||||
}
|
||||
void DeerStudioApplication::onShutdown() {
|
||||
if (Project::m_scene.getExecutingState())
|
||||
Project::m_scene.endExecution();
|
||||
|
||||
int windowWidth = Application::s_application->m_window->getWitdth();
|
||||
int windowHeight = Application::s_application->m_window->getHeight();
|
||||
}
|
||||
ScriptEngine::shutdownScriptEngine();
|
||||
pannels.clear();
|
||||
}
|
||||
|
||||
void DeerStudioApplication::onUpdate(Timestep delta) {
|
||||
if (Project::m_scene.getExecutingState())
|
||||
Project::m_scene.updateInternalVars();
|
||||
if (Project::m_scene.getVoxelWorld())
|
||||
Project::m_scene.getVoxelWorld()->bakeNextChunk();
|
||||
}
|
||||
void DeerStudioApplication::onRender(Timestep delta) {
|
||||
for (auto pannel : pannels) {
|
||||
pannel->onRender(delta);
|
||||
}
|
||||
|
||||
void DeerStudioApplication::onEvent(Event& e) {
|
||||
for (auto& pannel : pannels)
|
||||
pannel->onEventCallback(e);
|
||||
int windowWidth = Application::s_application->m_window->getWitdth();
|
||||
int windowHeight = Application::s_application->m_window->getHeight();
|
||||
}
|
||||
|
||||
viewport_onEvent(e);
|
||||
}
|
||||
void DeerStudioApplication::onUpdate(Timestep delta) {
|
||||
if (Project::m_scene.getExecutingState())
|
||||
Project::m_scene.updateInternalVars();
|
||||
if (Project::m_scene.isVoxelWorldInitialized())
|
||||
Project::m_scene.getVoxelWorld().bakeNextChunk();
|
||||
}
|
||||
|
||||
void DeerStudioApplication::onImGUI() {
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
void DeerStudioApplication::onEvent(Event& e) {
|
||||
for (auto& pannel : pannels) pannel->onEventCallback(e);
|
||||
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
viewport_onEvent(e);
|
||||
}
|
||||
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
}
|
||||
void DeerStudioApplication::onImGUI() {
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
|
||||
static bool p_open = true;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::Begin("DockSpace Demo", &p_open, window_flags);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
|
||||
ImGuiID dockspace_id = ImGui::GetID("DockSpace Demo");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar |
|
||||
ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags_NoNavFocus;
|
||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
drawMenuBar();
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
static bool p_open = true;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::Begin("DockSpace Demo", &p_open, window_flags);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
for (auto pannel : pannels) {
|
||||
pannel->onImGui();
|
||||
}
|
||||
ImGuiID dockspace_id = ImGui::GetID("DockSpace Demo");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
|
||||
// ---- PANNELS -----
|
||||
//sceneExplorer_onImGUI();
|
||||
//treePannel_onImGui();
|
||||
TerrainEditor::terrainEditor_onImGui();
|
||||
viewport_onImGui();
|
||||
// ---- PANNELS -----
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
drawMenuBar();
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
Project::m_scene.getMainGizmoRenderer().refresh();
|
||||
ImGui::End();
|
||||
}
|
||||
for (auto pannel : pannels) {
|
||||
pannel->onImGui();
|
||||
}
|
||||
|
||||
void DeerStudioApplication::drawMenuBar() {
|
||||
if (ImGui::BeginMenu("Project")) {
|
||||
if (ImGui::MenuItem("New project")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Open project")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Save project")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Save project as...")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Create binaries")) {
|
||||
// ---- PANNELS -----
|
||||
// sceneExplorer_onImGUI();
|
||||
TreePannel::treePannel_onImGui();
|
||||
PropertiesPannel::propertiesPannel_onImgui();
|
||||
TerrainEditor::terrainEditor_onImGui();
|
||||
viewport_onImGui();
|
||||
// ---- PANNELS -----
|
||||
|
||||
}
|
||||
if (ImGui::MenuItem("Export project")) {
|
||||
SceneDataStore::exportScenesBin();
|
||||
Project::m_scene.getMainGizmoRenderer().refresh();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
std::vector<Path> scenes = DataStore::getFiles("scenes", ".dbscn");
|
||||
DataStore::compressFiles(scenes, "bin/scene_data");
|
||||
}
|
||||
if (ImGui::MenuItem("Project settings")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
void DeerStudioApplication::drawMenuBar() {
|
||||
if (ImGui::BeginMenu("Project")) {
|
||||
if (ImGui::MenuItem("New project")) {
|
||||
}
|
||||
if (ImGui::MenuItem("Open project")) {
|
||||
}
|
||||
if (ImGui::MenuItem("Save project")) {
|
||||
}
|
||||
if (ImGui::MenuItem("Save project as...")) {
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Create binaries")) {
|
||||
}
|
||||
if (ImGui::MenuItem("Export project")) {
|
||||
}
|
||||
if (ImGui::MenuItem("Project settings")) {
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Scene")) {
|
||||
if (ImGui::MenuItem("New scene")) {
|
||||
// TODO
|
||||
Project::m_scene.clear();
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, "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")) {
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, "saved_scene");
|
||||
}
|
||||
if (ImGui::MenuItem("Save scene as...")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Load scene")) {
|
||||
//Project::m_scene.swap(SceneDataStore::loadScene("new_scene"));
|
||||
//SceneDataStore::exportSceneJson(Project::m_scene, "new_scene");
|
||||
}
|
||||
if (ImGui::MenuItem("Scene settings")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Scene")) {
|
||||
if (ImGui::MenuItem("New scene")) {
|
||||
// TODO
|
||||
Project::m_scene.clear();
|
||||
SceneDataStore::exportScene(Project::m_scene, "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")) {
|
||||
SceneDataStore::exportScene(Project::m_scene, "saved_scene");
|
||||
}
|
||||
if (ImGui::MenuItem("Save scene as...")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Load scene")) {
|
||||
// Project::m_scene.swap(SceneDataStore::loadScene("new_scene"));
|
||||
// SceneDataStore::exportScene(Project::m_scene,
|
||||
// "new_scene");
|
||||
}
|
||||
if (ImGui::MenuItem("Scene settings")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Runtime")) {
|
||||
if (ImGui::MenuItem("Start")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("End")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Restart")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Runtime")) {
|
||||
if (ImGui::MenuItem("Start")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("End")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Restart")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Voxel")) {
|
||||
if (ImGui::MenuItem("Voxel Pannel")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::BeginMenu("Voxel")) {
|
||||
if (ImGui::MenuItem("Voxel Pannel")) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Scripts")) {
|
||||
if (ImGui::MenuItem("Reload scripts") && !Project::m_scene.getExecutingState()) {
|
||||
ScriptEngine::shutdownScriptEngine();
|
||||
ScriptEngine::compileScriptEngine(std::filesystem::path("scripts"));
|
||||
}
|
||||
if (ImGui::BeginMenu("Scripts")) {
|
||||
if (ImGui::MenuItem("Reload scripts") &&
|
||||
!Project::m_scene.getExecutingState()) {
|
||||
ScriptEngine::shutdownScriptEngine();
|
||||
ScriptEngine::compileScriptEngine(
|
||||
std::filesystem::path("scripts"));
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Help")) {
|
||||
if (ImGui::MenuItem("Documentation")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Report bug")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("About")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Help")) {
|
||||
if (ImGui::MenuItem("Documentation")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("Report bug")) {
|
||||
// TODO
|
||||
}
|
||||
if (ImGui::MenuItem("About")) {
|
||||
// TODO
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DeerStudioApplication::onChangeScene() {
|
||||
ActiveEntity::clear();
|
||||
}
|
||||
}
|
||||
void DeerStudioApplication::onChangeScene() { ActiveEntity::clear(); }
|
||||
} // namespace Deer
|
@ -1,91 +1,93 @@
|
||||
#include "GamePannel.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Scene.h"
|
||||
|
||||
#include "Deer/ScriptEngine.h"
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace Deer {
|
||||
GamePannel::GamePannel() {
|
||||
FrameBufferSpecification fbSpecs = FrameBufferSpecification(100, 100, { TextureBufferType::RGBA8 }, 1, false);
|
||||
m_frameBuffer = FrameBuffer::create(fbSpecs);
|
||||
}
|
||||
GamePannel::GamePannel() {
|
||||
FrameBufferSpecification fbSpecs = FrameBufferSpecification(
|
||||
100, 100, {TextureBufferType::RGBA8}, 1, false);
|
||||
m_frameBuffer = FrameBuffer::create(fbSpecs);
|
||||
}
|
||||
|
||||
void GamePannel::onImGui() {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Game Window");
|
||||
ImGui::PopStyleVar();
|
||||
void GamePannel::onImGui() {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Game Window");
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
Ref<Environment> environment = Project::m_scene.getMainEnviroment();
|
||||
uint32_t cameraUID = environment->tryGetMainCamera();
|
||||
Environment& environment = Project::m_scene.getMainEnviroment();
|
||||
uint32_t cameraUID = environment.tryGetMainCamera();
|
||||
|
||||
if (cameraUID == 0) {
|
||||
ImGui::TextColored(ImVec4(.3f, .3f, .8f, 1.0f), "There is no camera");
|
||||
if (cameraUID == 0) {
|
||||
ImGui::TextColored(ImVec4(.3f, .3f, .8f, 1.0f),
|
||||
"There is no camera");
|
||||
|
||||
if (!Project::m_scene.getExecutingState()) {
|
||||
if (ScriptEngine::isCompilationValid() && ImGui::Button("Execute")) {
|
||||
SceneDataStore::exportRuntimeScene(Project::m_scene);
|
||||
Project::m_scene.beginExecution();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ImGui::Button("Stop")) {
|
||||
Project::m_scene.endExecution();
|
||||
Project::m_scene = SceneDataStore::importRuntimeScene();
|
||||
}
|
||||
}
|
||||
if (!Project::m_scene.getExecutingState()) {
|
||||
if (ScriptEngine::isCompilationValid() &&
|
||||
ImGui::Button("Execute")) {
|
||||
SceneDataStore::exportRuntimeScene(Project::m_scene);
|
||||
Project::m_scene.beginExecution();
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("Stop")) {
|
||||
Project::m_scene.endExecution();
|
||||
SceneDataStore::importRuntimeScene(Project::m_scene);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
Entity& cameraEntity = environment->getEntity(cameraUID);
|
||||
CameraComponent& cameraComponent = cameraEntity.getComponent<CameraComponent>();
|
||||
Entity& cameraEntity = environment.getEntity(cameraUID);
|
||||
CameraComponent& cameraComponent =
|
||||
cameraEntity.getComponent<CameraComponent>();
|
||||
|
||||
ImVec2 contentRegionMin = ImGui::GetWindowContentRegionMin();
|
||||
ImVec2 pos = ImGui::GetWindowPos();
|
||||
pos.y += contentRegionMin.y;
|
||||
ImVec2 contentRegionMin = ImGui::GetWindowContentRegionMin();
|
||||
ImVec2 pos = ImGui::GetWindowPos();
|
||||
pos.y += contentRegionMin.y;
|
||||
|
||||
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
|
||||
if (m_lastWindowSize != *(glm::vec2*)&windowSize) {
|
||||
m_lastWindowSize = { windowSize.x, windowSize.y };
|
||||
m_frameBuffer->resize(windowSize.x, windowSize.y);
|
||||
if (m_lastWindowSize != *(glm::vec2*)&windowSize) {
|
||||
m_lastWindowSize = {windowSize.x, windowSize.y};
|
||||
m_frameBuffer->resize(windowSize.x, windowSize.y);
|
||||
|
||||
cameraComponent.aspect = windowSize.x / windowSize.y;
|
||||
}
|
||||
cameraComponent.aspect = windowSize.x / windowSize.y;
|
||||
}
|
||||
|
||||
m_frameBuffer->bind();
|
||||
m_frameBuffer->clear();
|
||||
unsigned char clearColor[4]{ 0, 0, 0, 255 };
|
||||
m_frameBuffer->clearBuffer(0, &clearColor);
|
||||
m_frameBuffer->bind();
|
||||
m_frameBuffer->clear();
|
||||
unsigned char clearColor[4]{0, 0, 0, 255};
|
||||
m_frameBuffer->clearBuffer(0, &clearColor);
|
||||
|
||||
Project::m_scene.render();
|
||||
m_frameBuffer->unbind();
|
||||
Project::m_scene.render();
|
||||
m_frameBuffer->unbind();
|
||||
|
||||
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0), windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0),
|
||||
windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
|
||||
ImGui::SetCursorPos(cursorPos);
|
||||
ImGui::SetCursorPos(cursorPos);
|
||||
|
||||
if (!Project::m_scene.getExecutingState()) {
|
||||
if (ScriptEngine::isCompilationValid() && ImGui::Button("Execute")) {
|
||||
SceneDataStore::exportRuntimeScene(Project::m_scene);
|
||||
Project::m_scene.beginExecution();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ImGui::Button("Stop")) {
|
||||
Project::m_scene.endExecution();
|
||||
Project::m_scene = SceneDataStore::importRuntimeScene();
|
||||
}
|
||||
}
|
||||
if (!Project::m_scene.getExecutingState()) {
|
||||
if (ScriptEngine::isCompilationValid() &&
|
||||
ImGui::Button("Execute")) {
|
||||
SceneDataStore::exportRuntimeScene(Project::m_scene);
|
||||
Project::m_scene.beginExecution();
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("Stop")) {
|
||||
Project::m_scene.endExecution();
|
||||
SceneDataStore::importRuntimeScene(Project::m_scene);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
} // namespace Deer
|
@ -1,22 +1,35 @@
|
||||
#include "PropertiesPannel.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
|
||||
#include "DeerRender/Input.h"
|
||||
#include "DeerRender/KeyCodes.h"
|
||||
#include "DeerRender/Render/Texture.h"
|
||||
|
||||
#include "Deer/Asset.h"
|
||||
#include "Deer/ScriptEngine.h"
|
||||
|
||||
#include "DeerRender/Input.h"
|
||||
#include "DeerRender/KeyCodes.h"
|
||||
#include "DeerRender/Render/Texture.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace Deer {
|
||||
bool* getIsEditingState(ImGuiID id)
|
||||
{
|
||||
namespace PropertiesPannel {
|
||||
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 PropertiesPannel
|
||||
|
||||
bool* getIsEditingState(ImGuiID id) {
|
||||
ImGuiStorage* storage = ImGui::GetStateStorage();
|
||||
void* ptr = storage->GetVoidPtr(id);
|
||||
if (ptr)
|
||||
return (bool*)ptr;
|
||||
if (ptr) return (bool*)ptr;
|
||||
|
||||
// If state doesn't exist, initialize it
|
||||
bool* state = new bool(false);
|
||||
@ -24,7 +37,7 @@ namespace Deer {
|
||||
return state;
|
||||
}
|
||||
|
||||
void PropertiesPannel::onImGui() {
|
||||
void PropertiesPannel::propertiesPannel_onImgui() {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
|
||||
ImGui::Begin("Properties");
|
||||
|
||||
@ -49,7 +62,8 @@ namespace Deer {
|
||||
addComponentContext();
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
|
||||
if (collapsingComponentHeader<TransformComponent>("Transform Component", false)) {
|
||||
if (collapsingComponentHeader<TransformComponent>("Transform Component",
|
||||
false)) {
|
||||
auto& transform = activeEntity.getComponent<TransformComponent>();
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
ImGui::Indent();
|
||||
@ -58,12 +72,10 @@ namespace Deer {
|
||||
glm::vec3 rotation = transform.getEulerAngles();
|
||||
glm::vec3 lastRotation = rotation;
|
||||
drawMagicSlider3f("Rotation", &rotation.x, 0);
|
||||
if (rotation != lastRotation)
|
||||
transform.setEulerAngles(rotation);
|
||||
if (rotation != lastRotation) transform.setEulerAngles(rotation);
|
||||
drawMagicSlider3f("Scale", &transform.scale.x, 1);
|
||||
|
||||
if (rotation != lastRotation)
|
||||
transform.setEulerAngles(rotation);
|
||||
if (rotation != lastRotation) transform.setEulerAngles(rotation);
|
||||
|
||||
ImGui::Unindent();
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
@ -90,7 +102,8 @@ namespace Deer {
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
}
|
||||
|
||||
if (collapsingComponentHeader<MeshRenderComponent>("Mesh Render Component")) {
|
||||
if (collapsingComponentHeader<MeshRenderComponent>(
|
||||
"Mesh Render Component")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
ImGui::Indent();
|
||||
|
||||
@ -101,15 +114,19 @@ namespace Deer {
|
||||
if (mesh.meshAssetID == 0)
|
||||
meshName = " null ";
|
||||
else
|
||||
meshName = AssetManager::getAssetLocation(mesh.meshAssetID).generic_string();
|
||||
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<Mesh>(receivedData);
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("_MESH")) {
|
||||
std::string receivedData =
|
||||
std::string((const char*)payload->Data);
|
||||
mesh.meshAssetID =
|
||||
AssetManager::loadAsset<Mesh>(receivedData);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@ -119,15 +136,19 @@ namespace Deer {
|
||||
if (mesh.shaderAssetID == 0)
|
||||
shaderName = " null ";
|
||||
else
|
||||
shaderName = AssetManager::getAssetLocation(mesh.shaderAssetID).generic_string();
|
||||
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);
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("_SHADER")) {
|
||||
std::string receivedData =
|
||||
std::string((const char*)payload->Data);
|
||||
mesh.shaderAssetID =
|
||||
AssetManager::loadAsset<Shader>(receivedData);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@ -136,23 +157,26 @@ namespace Deer {
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
}
|
||||
|
||||
if (collapsingComponentHeader<TextureBindingComponent>("Texture Binding Component"))
|
||||
{
|
||||
if (collapsingComponentHeader<TextureBindingComponent>(
|
||||
"Texture Binding Component")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
ImGui::Indent();
|
||||
|
||||
TextureBindingComponent& textureBinding = activeEntity.getComponent<TextureBindingComponent>();
|
||||
TextureBindingComponent& textureBinding =
|
||||
activeEntity.getComponent<TextureBindingComponent>();
|
||||
|
||||
int textureBindingCount = 0;
|
||||
for (int x = 0; x < MAX_TEXTURE_BINDINGS; x++) {
|
||||
if (textureBinding.textureAssetID[x] == 0)
|
||||
continue;
|
||||
if (textureBinding.textureAssetID[x] == 0) continue;
|
||||
|
||||
ImGui::PushID(x);
|
||||
|
||||
textureBindingCount++;
|
||||
|
||||
std::string textureBindingName = AssetManager::getAssetLocation(textureBinding.textureAssetID[x]).generic_string();
|
||||
std::string textureBindingName =
|
||||
AssetManager::getAssetLocation(
|
||||
textureBinding.textureAssetID[x])
|
||||
.generic_string();
|
||||
int currentID = textureBinding.textureBindID[x];
|
||||
|
||||
ImGui::Text("Texture : ");
|
||||
@ -160,11 +184,14 @@ namespace Deer {
|
||||
ImGui::Button(textureBindingName.c_str());
|
||||
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_TEXTURE2D")) {
|
||||
std::string receivedData = std::string((const char*)payload->Data);
|
||||
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));
|
||||
textureBinding.textureAssetID[x] =
|
||||
AssetManager::loadAsset<Texture2D>(
|
||||
std::filesystem::path(receivedData));
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@ -173,7 +200,9 @@ namespace Deer {
|
||||
ImGui::SameLine();
|
||||
ImGui::InputInt("#bindingInputID", ¤tID, 0);
|
||||
|
||||
currentID = (currentID < 0) ? 0 : (currentID > 12) ? 12 : currentID;
|
||||
currentID = (currentID < 0) ? 0
|
||||
: (currentID > 12) ? 12
|
||||
: currentID;
|
||||
textureBinding.textureBindID[x] = currentID;
|
||||
|
||||
if (ImGui::Button("Delete texture binding"))
|
||||
@ -189,18 +218,20 @@ namespace Deer {
|
||||
ImGui::Button("Add texture binding");
|
||||
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_TEXTURE2D")) {
|
||||
std::string receivedData = std::string((const char*)payload->Data);
|
||||
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;
|
||||
if (textureBinding.textureAssetID[x] != 0) continue;
|
||||
|
||||
textureBinding.textureAssetID[x] = AssetManager::loadAsset<Texture2D>(std::filesystem::path(receivedData));
|
||||
textureBinding.textureAssetID[x] =
|
||||
AssetManager::loadAsset<Texture2D>(
|
||||
std::filesystem::path(receivedData));
|
||||
textureBinding.textureBindID[x] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@ -210,15 +241,15 @@ namespace Deer {
|
||||
ImGui::Dummy(ImVec2(0.0f, 10.0f));
|
||||
}
|
||||
|
||||
if (collapsingComponentHeader<CameraComponent>("Camera Component"))
|
||||
{
|
||||
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.getUID())
|
||||
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);
|
||||
@ -238,13 +269,14 @@ namespace Deer {
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void PropertiesPannel::drawMagicSlider(const std::string& text, float* value) {
|
||||
void PropertiesPannel::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))
|
||||
if (*isEditing) {
|
||||
if (ImGui::InputFloat(text.c_str(), value, 0.0f, 0.0f, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
*isEditing = false;
|
||||
|
||||
if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0))
|
||||
@ -254,76 +286,93 @@ namespace Deer {
|
||||
}
|
||||
|
||||
ImGui::DragFloat(text.c_str(), value, 0.05f, 0.0f, 0.0f, "%.3f",
|
||||
ImGuiSliderFlags_NoRoundToFormat);
|
||||
ImGuiSliderFlags_NoRoundToFormat);
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
if (ImGui::IsItemHovered() &&
|
||||
ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
*isEditing = true;
|
||||
}
|
||||
|
||||
void PropertiesPannel::drawMagicSlider3f(const std::string& text, float* value, float defaultValue) {
|
||||
|
||||
void PropertiesPannel::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::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
|
||||
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;
|
||||
if (ImGui::Button((" X ##" + text).c_str())) *value = defaultValue;
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PopStyleColor(3); // Restore original style
|
||||
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::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;
|
||||
if (ImGui::Button((" Y ##" + text).c_str())) value[1] = defaultValue;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PopStyleColor(3); // Restore original style
|
||||
|
||||
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::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;
|
||||
if (ImGui::Button((" Z ##" + text).c_str())) value[2] = defaultValue;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PopStyleColor(3); // Restore original style
|
||||
ImGui::PopStyleColor(3); // Restore original style
|
||||
|
||||
drawMagicSlider("##" + text + "_z", &value[2]);
|
||||
ImGui::Columns();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
}
|
||||
|
||||
void PropertiesPannel::addComponentContext() {
|
||||
|
||||
float buttonWidth = ImGui::CalcTextSize(" + add Component ").x; // Example button width
|
||||
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)
|
||||
if (ImGui::Button(
|
||||
" + add Component ")) { //,
|
||||
// ImVec2(ImGui::GetWindowContentRegionWidth(),
|
||||
// 40)
|
||||
// Opens a popup window when the button is clicked
|
||||
ImGui::OpenPopup("Add Component Popup");
|
||||
}
|
||||
@ -331,15 +380,13 @@ namespace Deer {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
|
||||
ImGui::SetNextWindowSize(ImVec2(240, 200));
|
||||
// Create the popup window
|
||||
if (ImGui::BeginPopup("Add Component Popup"))
|
||||
{
|
||||
|
||||
if (ImGui::BeginPopup("Add Component Popup")) {
|
||||
addComponentButton<MeshRenderComponent>("Mesh Render Component");
|
||||
addComponentButton<TextureBindingComponent>("Texture Binding Component");
|
||||
addComponentButton<TextureBindingComponent>(
|
||||
"Texture Binding Component");
|
||||
addComponentButton<CameraComponent>("Camera Component");
|
||||
|
||||
if (ImGui::BeginMenu("Scripts")) {
|
||||
|
||||
for (auto& script : ScriptEngine::getComponentScripts())
|
||||
addScriptButton(script.first.c_str());
|
||||
|
||||
@ -351,14 +398,16 @@ namespace Deer {
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool PropertiesPannel::collapsingComponentHeader(const std::string& componentName, bool canDelete)
|
||||
{
|
||||
if (!ActiveEntity::shareComponent<T>())
|
||||
return false;
|
||||
template <typename T>
|
||||
inline bool PropertiesPannel::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);
|
||||
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());
|
||||
@ -366,7 +415,6 @@ namespace Deer {
|
||||
|
||||
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();
|
||||
@ -393,9 +441,11 @@ namespace Deer {
|
||||
}
|
||||
|
||||
void PropertiesPannel::addScriptButton(const std::string& scriptID) {
|
||||
ImGuiSelectableFlags selectableFlag = (ActiveEntity::shareComponent<ScriptComponent>()) ? ImGuiSelectableFlags_Disabled : ImGuiSelectableFlags_None;
|
||||
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);
|
||||
@ -405,19 +455,18 @@ namespace Deer {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void PropertiesPannel::addComponentButton(const std::string& componentName)
|
||||
{
|
||||
ImGuiSelectableFlags selectableFlag = (ActiveEntity::shareComponent<T>()) ? ImGuiSelectableFlags_Disabled : ImGuiSelectableFlags_None;
|
||||
template <typename T>
|
||||
void PropertiesPannel::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>();
|
||||
if (!entity->hasComponent<T>()) entity->addComponent<T>();
|
||||
}
|
||||
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Deer
|
||||
|
@ -1,31 +1,10 @@
|
||||
#pragma once
|
||||
#include "DeerStudio/Editor/EditorPannel.h"
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
|
||||
#include "Deer/Memory.h"
|
||||
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
#include "DeerStudio/Editor/EditorPannel.h"
|
||||
|
||||
namespace Deer {
|
||||
class PropertiesPannel : public EditorPannel {
|
||||
public:
|
||||
PropertiesPannel() { }
|
||||
void onImGui() override;
|
||||
|
||||
private:
|
||||
void addComponentContext();
|
||||
|
||||
private:
|
||||
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 PropertiesPannel {
|
||||
void propertiesPannel_onImgui();
|
||||
} // namespace PropertiesPannel
|
||||
} // namespace Deer
|
@ -1,279 +1,296 @@
|
||||
#include "SceneExplorer.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
|
||||
#include "Deer/Path.h"
|
||||
#include "Deer/DataStore.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Log.h"
|
||||
|
||||
#include "DeerRender/Render/Texture.h"
|
||||
|
||||
#include "Icons.h"
|
||||
#include "EditorUtils.h"
|
||||
|
||||
#include "imgui.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;
|
||||
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 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 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 openFileExplorer(const std::string& relativePath);
|
||||
|
||||
void sceneExplorer_onImGUI() {
|
||||
if (m_currentScenePath == "null")
|
||||
m_currentScenePath = DataStore::rootPath / DEER_SCENE_PATH;
|
||||
if (m_currentScenePath == "null")
|
||||
m_currentScenePath = DataStore::rootPath / DEER_SCENE_PATH;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 10));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 10));
|
||||
ImGui::Begin("Scene Explorer", (bool*)0, ImGuiWindowFlags_MenuBar);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::MenuItem("Save")) {
|
||||
if (m_currentSceneName == "")
|
||||
ImGui::OpenPopup("SAVE_SCENE_NAME");
|
||||
else
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, m_currentSceneName);
|
||||
}
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::MenuItem("Save")) {
|
||||
if (m_currentSceneName == "")
|
||||
ImGui::OpenPopup("SAVE_SCENE_NAME");
|
||||
else
|
||||
SceneDataStore::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("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("New folder")) {
|
||||
ImGui::OpenPopup("CREATE_SCENE_FOLDER");
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Explorer")) {
|
||||
openFileExplorer(m_currentScenePath.generic_string());
|
||||
}
|
||||
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");
|
||||
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::EndMenuBar();
|
||||
}
|
||||
|
||||
ImGui::Text("%s", m_currentScenePath.generic_string().c_str());
|
||||
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);
|
||||
ImGui::TextDisabled("Active Scene : ");
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.7f, 1), "%s",
|
||||
m_currentSceneName.generic_string().c_str());
|
||||
|
||||
if (m_currentScenePath != DEER_SCENE_PATH) {
|
||||
drawSceneExplorerFolder("..");
|
||||
setupColumns(ICON_MIN_SIZE + 80);
|
||||
|
||||
float cursorOffset = (ICON_MIN_SIZE - ImGui::CalcTextSize("..").x) / 2;
|
||||
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x, ImGui::GetCursorPos().y));
|
||||
ImGui::Text("..");
|
||||
if (m_currentScenePath != DEER_SCENE_PATH) {
|
||||
drawSceneExplorerFolder("..");
|
||||
|
||||
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;
|
||||
float cursorOffset =
|
||||
(ICON_MIN_SIZE - ImGui::CalcTextSize("..").x) / 2;
|
||||
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x,
|
||||
ImGui::GetCursorPos().y));
|
||||
ImGui::Text("..");
|
||||
|
||||
Path sceneName = entry.path().parent_path().lexically_relative(DEER_SCENE_PATH) / entry.path().stem();
|
||||
drawSceneExplorerScene(sceneName);
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
|
||||
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());
|
||||
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;
|
||||
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
ImGui::Columns();
|
||||
Path sceneName = entry.path().parent_path().lexically_relative(
|
||||
DEER_SCENE_PATH) /
|
||||
entry.path().stem();
|
||||
drawSceneExplorerScene(sceneName);
|
||||
}
|
||||
|
||||
saveSceneBeforeLoadingPopup();
|
||||
sceneDialogPopup();
|
||||
deleteInputPopup<deleteScene>("DELETE_SCENE", "Are you sure you want to delete the scene?");
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
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));
|
||||
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(0) && ImGui::IsMouseDoubleClicked(0)) {
|
||||
ImGui::OpenPopup("SAVE_SCENE_BEFORE_LOADING");
|
||||
m_loadSceneName = path;
|
||||
}
|
||||
|
||||
if (ImGui::IsItemClicked(1)) {
|
||||
ImGui::OpenPopup("SCENE_DIALOG");
|
||||
m_dialogSceneName = 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;
|
||||
}
|
||||
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 == "") {
|
||||
Project::m_scene = SceneDataStore::loadScene(m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
void saveSceneBeforeLoadingPopup() {
|
||||
if (ImGui::BeginPopup("SAVE_SCENE_BEFORE_LOADING")) {
|
||||
if (m_currentSceneName == "") {
|
||||
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::Text("Do you want to save the current scene?");
|
||||
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");
|
||||
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();
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, m_currentSceneName);
|
||||
Project::m_scene = SceneDataStore::loadScene(m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
else if (dont_save) {
|
||||
ActiveEntity::clear();
|
||||
Project::m_scene = SceneDataStore::loadScene(m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
} if (cancel) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (save) {
|
||||
ActiveEntity::clear();
|
||||
SceneDataStore::exportScene(Project::m_scene,
|
||||
m_currentSceneName);
|
||||
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
} else if (dont_save) {
|
||||
ActiveEntity::clear();
|
||||
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName);
|
||||
m_currentSceneName = m_loadSceneName;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (cancel) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void sceneDialogPopup() {
|
||||
|
||||
if (ImGui::BeginPopup("SCENE_DIALOG")) {
|
||||
if (ImGui::MenuItem("Rename Scene")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
void sceneDialogPopup() {
|
||||
if (ImGui::BeginPopup("SCENE_DIALOG")) {
|
||||
if (ImGui::MenuItem("Rename Scene")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Delete Scene")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
if (ImGui::MenuItem("Delete Scene")) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
|
||||
ImGui::OpenPopup("DELETE_SCENE");
|
||||
m_deleteSceneName = m_dialogSceneName;
|
||||
return;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
ImGui::OpenPopup("DELETE_SCENE");
|
||||
m_deleteSceneName = m_dialogSceneName;
|
||||
return;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteScene() {
|
||||
SceneDataStore::deleteSceneJson(m_deleteSceneName);
|
||||
}
|
||||
void createFolderName(const std::string& name) {
|
||||
std::string correctInput = sanitizeInput(name);
|
||||
// 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) {
|
||||
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;
|
||||
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;
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, fullName);
|
||||
}
|
||||
}
|
||||
void saveBeforeCreatingNew(bool save) {
|
||||
if (save) {
|
||||
if (m_currentSceneName == "") {
|
||||
ImGui::OpenPopup("SAVE_SCENE_NAME_CREATE_NEW");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ActiveEntity::clear();
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, m_currentSceneName);
|
||||
Project::m_scene = Scene();
|
||||
m_currentSceneName = Path();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ActiveEntity::clear();
|
||||
Project::m_scene = Scene();
|
||||
m_currentSceneName = Path();
|
||||
}
|
||||
}
|
||||
void saveSceneNameBeforeCreatingNew(const std::string& name) {
|
||||
std::string correctInput = sanitizeInput(name);
|
||||
m_currentSceneName = fullName;
|
||||
SceneDataStore::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();
|
||||
SceneDataStore::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;
|
||||
if (name.size() != 0) {
|
||||
Path fullName;
|
||||
if (m_currentScenePath == DEER_SCENE_PATH)
|
||||
fullName = correctInput;
|
||||
else
|
||||
fullName =
|
||||
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
|
||||
correctInput;
|
||||
|
||||
SceneDataStore::exportSceneJson(Project::m_scene, fullName);
|
||||
ActiveEntity::clear();
|
||||
Project::m_scene = Scene();
|
||||
m_currentSceneName = Path();
|
||||
}
|
||||
}
|
||||
}
|
||||
SceneDataStore::exportScene(Project::m_scene, fullName);
|
||||
ActiveEntity::clear();
|
||||
Project::m_scene.clear();
|
||||
m_currentSceneName = Path();
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -24,8 +24,7 @@ namespace Deer {
|
||||
void TerrainEditor::terrainEditor_onImGui() {
|
||||
ImGui::Begin("Terrain Editor");
|
||||
|
||||
Ref<VoxelWorld>& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
if (voxelWorld == nullptr) {
|
||||
if (!Project::m_scene.isVoxelWorldInitialized()) {
|
||||
if (ImGui::Button("Create Voxel World")) {
|
||||
ImGui::OpenPopup(TERRAIN_EDITOR_CREATE_VOXEL_WORLD_POPUP_NAME);
|
||||
}
|
||||
@ -35,6 +34,7 @@ namespace Deer {
|
||||
return;
|
||||
}
|
||||
|
||||
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
ImGui::Text("Edit mode: ");
|
||||
|
||||
setupColumns(ICON_BTN_MIN_SIZE + 16);
|
||||
|
@ -1,142 +1,155 @@
|
||||
#include "TerrainEditor.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "DeerStudio/Editor/Viewport.h"
|
||||
#include "DeerStudio/Editor/EditorUtils.h"
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
|
||||
#include "Deer/Log.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "Deer/Scene.h"
|
||||
|
||||
#include "DeerRender/GizmoRenderer.h"
|
||||
#include "DeerRender/Render/Texture.h"
|
||||
|
||||
#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 {
|
||||
namespace TerrainEditor {
|
||||
VoxelCordinates selectedVoxelStart(-1, -1, -1);
|
||||
VoxelCordinates selectedVoxelEnd(-1, -1, -1);
|
||||
uint8_t voxelSelectMode = 0;
|
||||
}
|
||||
namespace TerrainEditor {
|
||||
VoxelCordinates selectedVoxelStart(-1, -1, -1);
|
||||
VoxelCordinates selectedVoxelEnd(-1, -1, -1);
|
||||
uint8_t voxelSelectMode = 0;
|
||||
} // namespace TerrainEditor
|
||||
|
||||
void TerrainEditor::boxSelect() {
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Select mode: ");
|
||||
ImGui::SameLine();
|
||||
if (voxelSelectMode == FACE_VOXEL_SELECT)
|
||||
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s","Face");
|
||||
else
|
||||
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s","Voxel");
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
setupColumns(ICON_BTN_MIN_SIZE + 16);
|
||||
if (iconButton((ImTextureID)(uint64_t)Icons::face_voxel_selection_icon->getTextureID(), ICON_BTN_MIN_SIZE, voxelSelectMode == FACE_VOXEL_SELECT)) {
|
||||
voxelSelectMode = FACE_VOXEL_SELECT;
|
||||
}
|
||||
ImGui::Text("Face");
|
||||
ImGui::NextColumn();
|
||||
if (iconButton((ImTextureID)(uint64_t)Icons::internal_voxel_selection_icon->getTextureID(), ICON_BTN_MIN_SIZE, voxelSelectMode == INTERNAL_VOXEL_SELECT)) {
|
||||
voxelSelectMode = INTERNAL_VOXEL_SELECT;
|
||||
}
|
||||
ImGui::Text("Voxel");
|
||||
ImGui::Columns();
|
||||
void TerrainEditor::boxSelect() {
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Select mode: ");
|
||||
ImGui::SameLine();
|
||||
if (voxelSelectMode == FACE_VOXEL_SELECT)
|
||||
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s", "Face");
|
||||
else
|
||||
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s", "Voxel");
|
||||
|
||||
if (!viewportIsActive()) {
|
||||
if (selectedVoxelStart.isNull())
|
||||
selectedVoxelStart.makeNull();
|
||||
return;
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
setupColumns(ICON_BTN_MIN_SIZE + 16);
|
||||
if (iconButton((ImTextureID)(uint64_t)
|
||||
Icons::face_voxel_selection_icon->getTextureID(),
|
||||
ICON_BTN_MIN_SIZE,
|
||||
voxelSelectMode == FACE_VOXEL_SELECT)) {
|
||||
voxelSelectMode = FACE_VOXEL_SELECT;
|
||||
}
|
||||
ImGui::Text("Face");
|
||||
ImGui::NextColumn();
|
||||
if (iconButton((ImTextureID)(uint64_t)
|
||||
Icons::internal_voxel_selection_icon->getTextureID(),
|
||||
ICON_BTN_MIN_SIZE,
|
||||
voxelSelectMode == INTERNAL_VOXEL_SELECT)) {
|
||||
voxelSelectMode = INTERNAL_VOXEL_SELECT;
|
||||
}
|
||||
ImGui::Text("Voxel");
|
||||
ImGui::Columns();
|
||||
|
||||
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left) || ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
if (voxelSelectMode == FACE_VOXEL_SELECT) {
|
||||
selectedVoxelEnd = voxelFaceRayCoords;
|
||||
} else {
|
||||
selectedVoxelEnd = voxelRayCoords;
|
||||
}
|
||||
Project::m_scene.getVoxelWorld()->getVoxelWorldProps().clampCordinates(selectedVoxelEnd);
|
||||
}
|
||||
if (!viewportIsActive()) {
|
||||
if (selectedVoxelStart.isNull()) selectedVoxelStart.makeNull();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) == 1) {
|
||||
selectedVoxelStart = selectedVoxelEnd;
|
||||
}
|
||||
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left) ||
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
if (voxelSelectMode == FACE_VOXEL_SELECT) {
|
||||
selectedVoxelEnd = voxelFaceRayCoords;
|
||||
} else {
|
||||
selectedVoxelEnd = voxelRayCoords;
|
||||
}
|
||||
Project::m_scene.getVoxelWorld()
|
||||
.getVoxelWorldProps()
|
||||
.clampCordinates(selectedVoxelEnd);
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Middle) == 1) {
|
||||
selectedVoxelStart.makeNull();
|
||||
selectedVoxelEnd.makeNull();
|
||||
}
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) == 1) {
|
||||
selectedVoxelStart = selectedVoxelEnd;
|
||||
}
|
||||
|
||||
}
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Middle) == 1) {
|
||||
selectedVoxelStart.makeNull();
|
||||
selectedVoxelEnd.makeNull();
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainEditor::boxSelect_Visuals() {
|
||||
void TerrainEditor::boxSelect_Visuals() {
|
||||
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
GizmoRenderer& gizmo = Project::m_scene.getMainGizmoRenderer();
|
||||
|
||||
Ref<VoxelWorld>& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
GizmoRenderer& gizmo = Project::m_scene.getMainGizmoRenderer();
|
||||
if (!selectedVoxelStart.isNull() && !selectedVoxelEnd.isNull()) {
|
||||
VoxelCordinates min;
|
||||
VoxelCordinates max;
|
||||
|
||||
if (!selectedVoxelStart.isNull() && !selectedVoxelEnd.isNull()) {
|
||||
VoxelCordinates min;
|
||||
VoxelCordinates max;
|
||||
if (selectedVoxelEnd.x < selectedVoxelStart.x) {
|
||||
min.x = selectedVoxelEnd.x;
|
||||
max.x = selectedVoxelStart.x;
|
||||
} else {
|
||||
max.x = selectedVoxelEnd.x;
|
||||
min.x = selectedVoxelStart.x;
|
||||
}
|
||||
|
||||
if (selectedVoxelEnd.x < selectedVoxelStart.x) {
|
||||
min.x = selectedVoxelEnd.x;
|
||||
max.x = selectedVoxelStart.x;
|
||||
} else {
|
||||
max.x = selectedVoxelEnd.x;
|
||||
min.x = selectedVoxelStart.x;
|
||||
}
|
||||
if (selectedVoxelEnd.y < selectedVoxelStart.y) {
|
||||
min.y = selectedVoxelEnd.y;
|
||||
max.y = selectedVoxelStart.y;
|
||||
} else {
|
||||
max.y = selectedVoxelEnd.y;
|
||||
min.y = selectedVoxelStart.y;
|
||||
}
|
||||
|
||||
if (selectedVoxelEnd.y < selectedVoxelStart.y) {
|
||||
min.y = selectedVoxelEnd.y;
|
||||
max.y = selectedVoxelStart.y;
|
||||
} else {
|
||||
max.y = selectedVoxelEnd.y;
|
||||
min.y = selectedVoxelStart.y;
|
||||
}
|
||||
if (selectedVoxelEnd.z < selectedVoxelStart.z) {
|
||||
min.z = selectedVoxelEnd.z;
|
||||
max.z = selectedVoxelStart.z;
|
||||
} else {
|
||||
max.z = selectedVoxelEnd.z;
|
||||
min.z = selectedVoxelStart.z;
|
||||
}
|
||||
|
||||
if (selectedVoxelEnd.z < selectedVoxelStart.z) {
|
||||
min.z = selectedVoxelEnd.z;
|
||||
max.z = selectedVoxelStart.z;
|
||||
} else {
|
||||
max.z = selectedVoxelEnd.z;
|
||||
min.z = selectedVoxelStart.z;
|
||||
}
|
||||
int debugVoxel = VoxelData::getVoxelID("debug");
|
||||
int debugInternal = VoxelData::getVoxelID("debug_internal");
|
||||
|
||||
int debugVoxel = VoxelData::getVoxelID("debug");
|
||||
int debugInternal = VoxelData::getVoxelID("debug_internal");
|
||||
// External faces
|
||||
// Z Face
|
||||
for (int x = min.x; x <= max.x; x++) {
|
||||
for (int y = min.y; y <= max.y; y++) {
|
||||
gizmo.drawVoxelFace(x, y, min.z, debugVoxel, NORMAL_BACK,
|
||||
5);
|
||||
gizmo.drawVoxelFace(x, y, max.z, debugVoxel, NORMAL_FRONT,
|
||||
5);
|
||||
gizmo.drawVoxelFaceInverted(x, y, min.z, debugInternal,
|
||||
NORMAL_BACK, 4);
|
||||
gizmo.drawVoxelFaceInverted(x, y, max.z, debugInternal,
|
||||
NORMAL_FRONT, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// External faces
|
||||
// Z Face
|
||||
for (int x = min.x; x <= max.x; x++) {
|
||||
for (int y = min.y; y <= max.y; y++) {
|
||||
gizmo.drawVoxelFace(x, y, min.z, debugVoxel, NORMAL_BACK, 5);
|
||||
gizmo.drawVoxelFace(x, y, max.z, debugVoxel, NORMAL_FRONT, 5);
|
||||
gizmo.drawVoxelFaceInverted(x, y, min.z, debugInternal, NORMAL_BACK, 4);
|
||||
gizmo.drawVoxelFaceInverted(x, y, max.z, debugInternal, NORMAL_FRONT, 4);
|
||||
}
|
||||
}
|
||||
// Y Face
|
||||
for (int x = min.x; x <= max.x; x++) {
|
||||
for (int z = min.z; z <= max.z; z++) {
|
||||
gizmo.drawVoxelFace(x, min.y, z, debugVoxel, NORMAL_DOWN,
|
||||
5);
|
||||
gizmo.drawVoxelFace(x, max.y, z, debugVoxel, NORMAL_UP, 5);
|
||||
gizmo.drawVoxelFaceInverted(x, min.y, z, debugInternal,
|
||||
NORMAL_DOWN, 4);
|
||||
gizmo.drawVoxelFaceInverted(x, max.y, z, debugInternal,
|
||||
NORMAL_UP, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Y Face
|
||||
for (int x = min.x; x <= max.x; x++) {
|
||||
for (int z = min.z; z <= max.z; z++) {
|
||||
gizmo.drawVoxelFace(x, min.y, z, debugVoxel, NORMAL_DOWN, 5);
|
||||
gizmo.drawVoxelFace(x, max.y, z, debugVoxel, NORMAL_UP, 5);
|
||||
gizmo.drawVoxelFaceInverted(x, min.y, z, debugInternal, NORMAL_DOWN, 4);
|
||||
gizmo.drawVoxelFaceInverted(x, max.y, z, debugInternal, NORMAL_UP, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// X Face
|
||||
for (int y = min.y; y <= max.y; y++) {
|
||||
for (int z = min.z; z <= max.z; z++) {
|
||||
gizmo.drawVoxelFace(min.x, y, z, debugVoxel, NORMAL_LEFT, 5);
|
||||
gizmo.drawVoxelFace(max.x, y, z, debugVoxel, NORMAL_RIGHT, 5);
|
||||
gizmo.drawVoxelFaceInverted(min.x, y, z, debugInternal, NORMAL_LEFT, 4);
|
||||
gizmo.drawVoxelFaceInverted(max.x, y, z, debugInternal, NORMAL_RIGHT, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// X Face
|
||||
for (int y = min.y; y <= max.y; y++) {
|
||||
for (int z = min.z; z <= max.z; z++) {
|
||||
gizmo.drawVoxelFace(min.x, y, z, debugVoxel, NORMAL_LEFT,
|
||||
5);
|
||||
gizmo.drawVoxelFace(max.x, y, z, debugVoxel, NORMAL_RIGHT,
|
||||
5);
|
||||
gizmo.drawVoxelFaceInverted(min.x, y, z, debugInternal,
|
||||
NORMAL_LEFT, 4);
|
||||
gizmo.drawVoxelFaceInverted(max.x, y, z, debugInternal,
|
||||
NORMAL_RIGHT, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -84,7 +84,7 @@ namespace Deer {
|
||||
props.chunkSizeZ = values[2];
|
||||
|
||||
Project::m_scene.createVoxelWorld(props);
|
||||
Project::m_scene.getVoxelWorld()->fillVoxels(
|
||||
Project::m_scene.getVoxelWorld().fillVoxels(
|
||||
VoxelCordinates(0, 0, 0), VoxelCordinates(31, 8, 31),
|
||||
Voxel(VoxelData::getVoxelID("wood")));
|
||||
|
||||
|
@ -1,54 +1,56 @@
|
||||
#include "TerrainEditor.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
#include "DeerStudio/Editor/Viewport.h"
|
||||
#include "DeerStudio/Editor/EditorUtils.h"
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "Deer/Scene.h"
|
||||
|
||||
#include "DeerRender/GizmoRenderer.h"
|
||||
|
||||
#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 {
|
||||
void TerrainEditor::empty() {
|
||||
if (!viewportIsActive())
|
||||
return;
|
||||
void TerrainEditor::empty() {
|
||||
if (!viewportIsActive()) return;
|
||||
|
||||
VoxelCordinates selectVoxel;
|
||||
VoxelCordinates clampedCordinates;
|
||||
selectVoxel = voxelRayCoords;
|
||||
VoxelCordinates selectVoxel;
|
||||
VoxelCordinates clampedCordinates;
|
||||
selectVoxel = voxelRayCoords;
|
||||
|
||||
clampedCordinates = selectVoxel;
|
||||
Project::m_scene.getVoxelWorld()->getVoxelWorldProps().clampCordinates(clampedCordinates);
|
||||
clampedCordinates = selectVoxel;
|
||||
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampCordinates(
|
||||
clampedCordinates);
|
||||
|
||||
if (clampedCordinates != selectVoxel)
|
||||
return;
|
||||
|
||||
VoxelCordinates min = selectedVoxelStart;
|
||||
VoxelCordinates max = selectedVoxelEnd;
|
||||
if (clampedCordinates != selectVoxel) return;
|
||||
|
||||
if (min.isNull() || max.isNull()) {
|
||||
min = VoxelCordinates(selectVoxel.x - 16, selectVoxel.y - 16, selectVoxel.z - 16);
|
||||
max = VoxelCordinates(selectVoxel.x + 15, selectVoxel.y + 15, selectVoxel.z + 15);
|
||||
}
|
||||
Project::m_scene.getVoxelWorld()->getVoxelWorldProps().clampAndSetMinMax(min, max);
|
||||
VoxelCordinates min = selectedVoxelStart;
|
||||
VoxelCordinates max = selectedVoxelEnd;
|
||||
|
||||
if (selectVoxel.x < min.x || selectVoxel.x > max.x ||
|
||||
selectVoxel.y < min.y || selectVoxel.y > max.y ||
|
||||
selectVoxel.z < min.z || selectVoxel.z > max.z)
|
||||
return;
|
||||
if (min.isNull() || max.isNull()) {
|
||||
min = VoxelCordinates(selectVoxel.x - 16, selectVoxel.y - 16,
|
||||
selectVoxel.z - 16);
|
||||
max = VoxelCordinates(selectVoxel.x + 15, selectVoxel.y + 15,
|
||||
selectVoxel.z + 15);
|
||||
}
|
||||
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampAndSetMinMax(
|
||||
min, max);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Project::m_scene.getMainGizmoRenderer().drawVoxelFace(clampedCordinates.x, clampedCordinates.y, clampedCordinates.z,
|
||||
VoxelData::getVoxelID("debug"), i, 0);
|
||||
}
|
||||
if (selectVoxel.x < min.x || selectVoxel.x > max.x ||
|
||||
selectVoxel.y < min.y || selectVoxel.y > max.y ||
|
||||
selectVoxel.z < min.z || selectVoxel.z > max.z)
|
||||
return;
|
||||
|
||||
if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) {
|
||||
Voxel voxel = Project::m_scene.getVoxelWorld()->readVoxel(selectVoxel);
|
||||
Project::m_scene.getVoxelWorld()->remplaceVoxels(min, max, voxel, Voxel(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Project::m_scene.getMainGizmoRenderer().drawVoxelFace(
|
||||
clampedCordinates.x, clampedCordinates.y, clampedCordinates.z,
|
||||
VoxelData::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,
|
||||
Voxel(0));
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -52,7 +52,7 @@ namespace Deer {
|
||||
}
|
||||
|
||||
clampedCordinates = selectVoxel;
|
||||
Project::m_scene.getVoxelWorld()->getVoxelWorldProps().clampCordinates(
|
||||
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampCordinates(
|
||||
clampedCordinates);
|
||||
|
||||
if (clampedCordinates != selectVoxel) return;
|
||||
@ -66,9 +66,8 @@ namespace Deer {
|
||||
max = VoxelCordinates(selectVoxel.x + 15, selectVoxel.y + 15,
|
||||
selectVoxel.z + 15);
|
||||
}
|
||||
Project::m_scene.getVoxelWorld()
|
||||
->getVoxelWorldProps()
|
||||
.clampAndSetMinMax(min, max);
|
||||
Project::m_scene.getVoxelWorld().getVoxelWorldProps().clampAndSetMinMax(
|
||||
min, max);
|
||||
|
||||
if (selectVoxel.x < min.x || selectVoxel.x > max.x ||
|
||||
selectVoxel.y < min.y || selectVoxel.y > max.y ||
|
||||
@ -83,8 +82,8 @@ namespace Deer {
|
||||
|
||||
if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) {
|
||||
Voxel voxel =
|
||||
Project::m_scene.getVoxelWorld()->readVoxel(selectVoxel);
|
||||
Project::m_scene.getVoxelWorld()->remplaceVoxels(
|
||||
Project::m_scene.getVoxelWorld().readVoxel(selectVoxel);
|
||||
Project::m_scene.getVoxelWorld().remplaceVoxels(
|
||||
min, max, voxel, Voxel(selectedVoxelID));
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,73 @@
|
||||
#include "TerrainEditor.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
#include "DeerStudio/Editor/EditorUtils.h"
|
||||
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include <string>
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Voxel.h"
|
||||
#include "Deer/VoxelWorld.h"
|
||||
#include "DeerStudio/Editor/EditorUtils.h"
|
||||
#include "DeerStudio/Editor/Icons.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "TerrainEditor.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace Deer {
|
||||
namespace TerrainEditor {
|
||||
namespace TerrainEditor {
|
||||
void deleteVoxelWorld();
|
||||
}
|
||||
|
||||
void TerrainEditor::info() {
|
||||
Ref<VoxelWorld>& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
VoxelWorldProps worldProps = voxelWorld->getVoxelWorldProps();
|
||||
void TerrainEditor::info() {
|
||||
VoxelWorld& voxelWorld = Project::m_scene.getVoxelWorld();
|
||||
VoxelWorldProps worldProps = voxelWorld.getVoxelWorldProps();
|
||||
|
||||
ImGui::Text("Voxel world chunk and voxel size:");
|
||||
ImGui::Text(" x: %s chunks -> %s voxels", std::to_string(worldProps.chunkSizeX).c_str(), std::to_string(worldProps.chunkSizeX * CHUNK_SIZE_X).c_str());
|
||||
ImGui::Text(" y: %s chunks -> %s voxels", std::to_string(worldProps.chunkSizeY).c_str(), std::to_string(worldProps.chunkSizeY * CHUNK_SIZE_Y).c_str());
|
||||
ImGui::Text(" z: %s chunks -> %s voxels", std::to_string(worldProps.chunkSizeZ).c_str(), std::to_string(worldProps.chunkSizeZ * CHUNK_SIZE_Z).c_str());
|
||||
ImGui::Text("Voxel world chunk and voxel size:");
|
||||
ImGui::Text(
|
||||
" x: %s chunks -> %s voxels",
|
||||
std::to_string(worldProps.chunkSizeX).c_str(),
|
||||
std::to_string(worldProps.chunkSizeX * CHUNK_SIZE_X).c_str());
|
||||
ImGui::Text(
|
||||
" y: %s chunks -> %s voxels",
|
||||
std::to_string(worldProps.chunkSizeY).c_str(),
|
||||
std::to_string(worldProps.chunkSizeY * CHUNK_SIZE_Y).c_str());
|
||||
ImGui::Text(
|
||||
" z: %s chunks -> %s voxels",
|
||||
std::to_string(worldProps.chunkSizeZ).c_str(),
|
||||
std::to_string(worldProps.chunkSizeZ * CHUNK_SIZE_Z).c_str());
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Separator();
|
||||
|
||||
int64_t voxelCount = CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z *
|
||||
worldProps.chunkSizeX * worldProps.chunkSizeY *
|
||||
worldProps.chunkSizeZ;
|
||||
int64_t clientSize = voxelCount * (sizeof(Voxel) + sizeof(VoxelLight));
|
||||
int64_t serverSize = voxelCount * (sizeof(Voxel));
|
||||
|
||||
int64_t voxelCount = CHUNK_SIZE_X * CHUNK_SIZE_Y * CHUNK_SIZE_Z * worldProps.chunkSizeX * worldProps.chunkSizeY * worldProps.chunkSizeZ;
|
||||
int64_t clientSize = voxelCount * (sizeof(Voxel) + sizeof(VoxelLight));
|
||||
int64_t serverSize = voxelCount * (sizeof(Voxel));
|
||||
ImGui::Text("%s", "Theorical max voxel count : ");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", std::to_string(voxelCount).c_str());
|
||||
|
||||
ImGui::Text("%s", "Theorical max voxel count : ");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", std::to_string(voxelCount).c_str());
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Text("%s", "Client theorical max size : ");
|
||||
ImGui::Text(" %sB", std::to_string(clientSize).c_str());
|
||||
ImGui::Text(" +%sKB", std::to_string(clientSize / 1024).c_str());
|
||||
ImGui::Text(" +%sMB",
|
||||
std::to_string(clientSize / (1024 * 1024)).c_str());
|
||||
ImGui::Text(" +%sGB",
|
||||
std::to_string(clientSize / (1024 * 1024 * 1024)).c_str());
|
||||
|
||||
ImGui::Text("%s", "Client theorical max size : ");
|
||||
ImGui::Text(" %sB", std::to_string(clientSize).c_str());
|
||||
ImGui::Text(" +%sKB", std::to_string(clientSize / 1024).c_str());
|
||||
ImGui::Text(" +%sMB", std::to_string(clientSize / (1024 * 1024)).c_str());
|
||||
ImGui::Text(" +%sGB", std::to_string(clientSize / (1024 * 1024 * 1024)).c_str());
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("%s", "Server theorical max size : ");
|
||||
ImGui::Text(" %sB", std::to_string(serverSize).c_str());
|
||||
ImGui::Text(" +%sKB", std::to_string(serverSize / 1024).c_str());
|
||||
ImGui::Text(" +%sMB", std::to_string(serverSize / (1024 * 1024)).c_str());
|
||||
ImGui::Text(" +%sGB", std::to_string(serverSize / (1024 * 1024 * 1024)).c_str());
|
||||
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("%s", "Server theorical max size : ");
|
||||
ImGui::Text(" %sB", std::to_string(serverSize).c_str());
|
||||
ImGui::Text(" +%sKB", std::to_string(serverSize / 1024).c_str());
|
||||
ImGui::Text(" +%sMB",
|
||||
std::to_string(serverSize / (1024 * 1024)).c_str());
|
||||
ImGui::Text(" +%sGB",
|
||||
std::to_string(serverSize / (1024 * 1024 * 1024)).c_str());
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Delete voxel world")) {
|
||||
ImGui::OpenPopup("DELETE_VOXEL_WORLD");
|
||||
@ -65,26 +75,25 @@ namespace Deer {
|
||||
|
||||
// TEMP
|
||||
if (ImGui::Button("Create Ceiling")) {
|
||||
Project::m_scene.getVoxelWorld()->fillVoxels(
|
||||
VoxelCordinates(), VoxelCordinates(
|
||||
32 * worldProps.chunkSizeX - 1,
|
||||
16,
|
||||
32 * worldProps.chunkSizeZ - 1),
|
||||
Voxel(VoxelData::getVoxelID("wood")));
|
||||
|
||||
Project::m_scene.getVoxelWorld()->fillVoxels(
|
||||
VoxelCordinates(1, 8, 1),
|
||||
VoxelCordinates(
|
||||
32 * worldProps.chunkSizeX - 2,
|
||||
15,
|
||||
32 * worldProps.chunkSizeZ - 2),
|
||||
Voxel(VoxelData::getVoxelID("air")));
|
||||
Project::m_scene.getVoxelWorld().fillVoxels(
|
||||
VoxelCordinates(),
|
||||
VoxelCordinates(32 * worldProps.chunkSizeX - 1, 16,
|
||||
32 * worldProps.chunkSizeZ - 1),
|
||||
Voxel(VoxelData::getVoxelID("wood")));
|
||||
|
||||
Project::m_scene.getVoxelWorld().fillVoxels(
|
||||
VoxelCordinates(1, 8, 1),
|
||||
VoxelCordinates(32 * worldProps.chunkSizeX - 2, 15,
|
||||
32 * worldProps.chunkSizeZ - 2),
|
||||
Voxel(VoxelData::getVoxelID("air")));
|
||||
}
|
||||
|
||||
deleteInputPopup<deleteVoxelWorld>("DELETE_VOXEL_WORLD", "Are you sure you want to delete voxel world?");
|
||||
}
|
||||
deleteInputPopup<deleteVoxelWorld>(
|
||||
"DELETE_VOXEL_WORLD",
|
||||
"Are you sure you want to delete voxel world?");
|
||||
}
|
||||
|
||||
void TerrainEditor::deleteVoxelWorld() {
|
||||
Project::m_scene.deleteVoxelWorld();
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -42,7 +42,7 @@ namespace Deer {
|
||||
glm::vec3 rayDir = farPoint - nearPoint;
|
||||
rayDir = glm::normalize(rayDir);
|
||||
|
||||
VoxelRayResult res = Project::m_scene.getVoxelWorld()->rayCast_editor(
|
||||
VoxelRayResult res = Project::m_scene.getVoxelWorld().rayCast_editor(
|
||||
viewport_sceneCamera.transform.position, rayDir, 50);
|
||||
|
||||
voxelRayCoords.makeNull();
|
||||
@ -59,8 +59,8 @@ namespace Deer {
|
||||
if (viewport_isActive && ImGui::GetMouseClickedCount(0) > 0) {
|
||||
if (terrainEditMode == TerrainEditMode_Substract) {
|
||||
if (res.hitPos.y >= 0) {
|
||||
Project::m_scene.getVoxelWorld()->setVoxel(res.hitPos,
|
||||
emptyVoxel);
|
||||
Project::m_scene.getVoxelWorld().setVoxel(res.hitPos,
|
||||
emptyVoxel);
|
||||
}
|
||||
} else if (terrainEditMode == TerrainEditMode_Add) {
|
||||
VoxelCordinates position(
|
||||
@ -68,7 +68,7 @@ namespace Deer {
|
||||
res.hitPos.y + NORMAL_DIR(1, res.face),
|
||||
res.hitPos.z + NORMAL_DIR(2, res.face));
|
||||
|
||||
Project::m_scene.getVoxelWorld()->setVoxel(
|
||||
Project::m_scene.getVoxelWorld().setVoxel(
|
||||
position, Voxel(selectedVoxelID));
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,45 @@
|
||||
#include "TreePannel.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "DeerRender/Input.h"
|
||||
#include "DeerRender/KeyCodes.h"
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace Deer {
|
||||
void updateEntity(Entity& entity);
|
||||
void updateReciveDragPayload(Entity& entity);
|
||||
bool updateDragPayload(Entity* entity, const std::string& name);
|
||||
void updateContextMenu();
|
||||
void clickEntity(Entity& entity);
|
||||
namespace TreePannel {
|
||||
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;
|
||||
bool m_isRightClickHandled;
|
||||
Entity* m_contextMenuEntity = nullptr;
|
||||
} // namespace TreePannel
|
||||
|
||||
void treePannel_onImGui() {
|
||||
void TreePannel::treePannel_onImGui() {
|
||||
ImGui::Begin("Tree Pannel", (bool*)0, ImGuiWindowFlags_MenuBar);
|
||||
|
||||
m_isRightClickHandled = false;
|
||||
Entity& root = Project::m_scene.getMainEnviroment()->getRoot();
|
||||
Entity& root = Project::m_scene.getMainEnviroment().getRoot();
|
||||
|
||||
if (!m_contextMenuEntity)
|
||||
m_contextMenuEntity = &root;
|
||||
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& 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& entity =
|
||||
Project::m_scene.getMainEnviroment().createEntity(
|
||||
"new camera");
|
||||
entity.addComponent<CameraComponent>();
|
||||
entity.setParent(root);
|
||||
}
|
||||
@ -47,8 +49,14 @@ namespace Deer {
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
for (auto& entityID : Project::m_scene.getMainEnviroment()->getRoot().getChildren()) {
|
||||
Entity& childEntity = Project::m_scene.getMainEnviroment()->getEntity(entityID);
|
||||
RelationshipComponent& relation =
|
||||
Project::m_scene.getMainEnviroment()
|
||||
.getRoot()
|
||||
.getComponent<RelationshipComponent>();
|
||||
for (int i = 0; i < relation.childCount; i++) {
|
||||
Entity& childEntity =
|
||||
Project::m_scene.getMainEnviroment().getEntity(
|
||||
relation.getChildrenId(i));
|
||||
updateEntity(childEntity);
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
@ -61,10 +69,12 @@ namespace Deer {
|
||||
ImGui::InvisibleButton("DragDropSpace", spaceSize);
|
||||
updateReciveDragPayload(root);
|
||||
|
||||
if (!m_isRightClickHandled && ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right) &&
|
||||
!ImGui::IsAnyItemHovered()) {
|
||||
|
||||
if (!m_isRightClickHandled &&
|
||||
ImGui::IsWindowHovered(
|
||||
ImGuiHoveredFlags_AllowWhenBlockedByPopup |
|
||||
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right) &&
|
||||
!ImGui::IsAnyItemHovered()) {
|
||||
m_contextMenuEntity = &root;
|
||||
ImGui::OpenPopup("Entity Context Menu");
|
||||
}
|
||||
@ -73,20 +83,22 @@ namespace Deer {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
void updateEntity(Entity& entity) {
|
||||
void TreePannel::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.getUID()));
|
||||
const void* entityID = reinterpret_cast<const void*>(
|
||||
static_cast<uintptr_t>(entity.getId()));
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
//End of the tree
|
||||
if (relationship.children.size() == 0) {
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
// End of the tree
|
||||
if (relationship.childCount == 0) {
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
|
||||
ImGuiTreeNodeFlags_NoTreePushOnOpen |
|
||||
ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
if (ActiveEntity::contains(entity))
|
||||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
@ -105,7 +117,9 @@ namespace Deer {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
|
||||
ImGuiTreeNodeFlags_OpenOnArrow |
|
||||
ImGuiTreeNodeFlags_SpanFullWidth;
|
||||
if (ActiveEntity::contains(entity))
|
||||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
@ -113,8 +127,7 @@ namespace Deer {
|
||||
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
||||
|
||||
if (ImGui::TreeNodeEx(entityID, flags, "%s", name.c_str())) {
|
||||
if (!entity.isRoot())
|
||||
updateDragPayload(&entity, tag.tag);
|
||||
if (!entity.isRoot()) updateDragPayload(&entity, tag.tag);
|
||||
updateReciveDragPayload(entity);
|
||||
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
@ -125,17 +138,17 @@ namespace Deer {
|
||||
|
||||
clickEntity(entity);
|
||||
|
||||
for (auto& entityID : entity.getChildren()) {
|
||||
updateReciveDragPayload(entity);
|
||||
|
||||
Entity& childEntity = Project::m_scene.getMainEnviroment()->getEntity(entityID);
|
||||
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 {
|
||||
} else {
|
||||
clickEntity(entity);
|
||||
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
@ -144,19 +157,18 @@ namespace Deer {
|
||||
ImGui::OpenPopup("Entity Context Menu");
|
||||
}
|
||||
|
||||
if (!entity.isRoot())
|
||||
updateDragPayload(&entity, tag.tag);
|
||||
if (!entity.isRoot()) updateDragPayload(&entity, tag.tag);
|
||||
updateReciveDragPayload(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void updateReciveDragPayload(Entity& entity) {
|
||||
void TreePannel::updateReciveDragPayload(Entity& entity) {
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_ENTITY")) {
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("_ENTITY")) {
|
||||
Entity* receivedData = *(Entity**)payload->Data;
|
||||
|
||||
if (!entity.isDescendant(*receivedData))
|
||||
if (!entity.isDescendantOf(*receivedData))
|
||||
receivedData->setParent(entity);
|
||||
}
|
||||
|
||||
@ -164,9 +176,9 @@ namespace Deer {
|
||||
}
|
||||
}
|
||||
|
||||
bool updateDragPayload(Entity* entity, const std::string& name) {
|
||||
if (!ImGui::BeginDragDropSource())
|
||||
return false;
|
||||
bool TreePannel::updateDragPayload(Entity* entity,
|
||||
const std::string& name) {
|
||||
if (!ImGui::BeginDragDropSource()) return false;
|
||||
|
||||
ImGui::SetDragDropPayload("_ENTITY", &entity, sizeof(Entity*));
|
||||
|
||||
@ -175,9 +187,10 @@ namespace Deer {
|
||||
return true;
|
||||
}
|
||||
|
||||
void clickEntity(Entity& entity) {
|
||||
void TreePannel::clickEntity(Entity& entity) {
|
||||
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
|
||||
if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) || Input::isKeyPressed(DEER_KEY_LEFT_ALT)))
|
||||
if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) ||
|
||||
Input::isKeyPressed(DEER_KEY_LEFT_ALT)))
|
||||
ActiveEntity::clear();
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT))
|
||||
@ -187,19 +200,22 @@ namespace Deer {
|
||||
}
|
||||
}
|
||||
|
||||
void updateContextMenu() {
|
||||
|
||||
void TreePannel::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& 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& entity =
|
||||
Project::m_scene.getMainEnviroment().createEntity(
|
||||
"new camera");
|
||||
entity.addComponent<CameraComponent>();
|
||||
entity.setParent(*m_contextMenuEntity);
|
||||
|
||||
@ -214,29 +230,31 @@ namespace Deer {
|
||||
callRename = true;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
if (!m_contextMenuEntity->isRoot() && ImGui::MenuItem("Duplicate")) {
|
||||
if (!m_contextMenuEntity->isRoot() &&
|
||||
ImGui::MenuItem("Duplicate")) {
|
||||
m_contextMenuEntity->duplicate();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (callRename)
|
||||
ImGui::OpenPopup("Rename Entity Menu");
|
||||
if (callRename) ImGui::OpenPopup("Rename Entity Menu");
|
||||
|
||||
if (ImGui::BeginPopup("Rename Entity Menu")) {
|
||||
|
||||
std::string& name = m_contextMenuEntity->getComponent<TagComponent>().tag;
|
||||
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;
|
||||
if (ImGui::InputText("##", nameBuffer, 256,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
m_contextMenuEntity->getComponent<TagComponent>().tag =
|
||||
nameBuffer;
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Deer
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace Deer {
|
||||
void treePannel_onImGui();
|
||||
namespace TreePannel {
|
||||
void treePannel_onImGui();
|
||||
}
|
||||
}
|
@ -1,246 +1,265 @@
|
||||
#include "Viewport.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Deer/Enviroment.h"
|
||||
#include "Deer/Scene.h"
|
||||
#include "DeerRender/Events/KeyEvent.h"
|
||||
#include "DeerRender/Events/MouseEvent.h"
|
||||
#include "DeerRender/GizmoRenderer.h"
|
||||
#include "DeerRender/Input.h"
|
||||
#include "DeerRender/Render/FrameBuffer.h"
|
||||
#include "DeerStudio/Editor/ActiveEntity.h"
|
||||
#include "DeerStudio/Project.h"
|
||||
|
||||
#include "DeerRender/Render/FrameBuffer.h"
|
||||
#include "DeerRender/GizmoRenderer.h"
|
||||
#include "DeerRender/Events/MouseEvent.h"
|
||||
#include "DeerRender/Events/KeyEvent.h"
|
||||
#include "DeerRender/Input.h"
|
||||
|
||||
#include "Deer/Scene.h"
|
||||
#include "Deer/Enviroment.h"
|
||||
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
#include "glm/gtc/type_ptr.hpp"
|
||||
#include "glm/gtx/matrix_decompose.hpp"
|
||||
|
||||
#include "imgui.h"
|
||||
// In this order
|
||||
#include "ImGuizmo.h"
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace Deer {
|
||||
Ref<FrameBuffer> m_frameBuffer;
|
||||
Ref<FrameBuffer> m_frameBuffer;
|
||||
|
||||
glm::vec2 m_lastWindowSize;
|
||||
glm::vec2 m_lastMousePos;
|
||||
glm::vec2 m_lastWindowSize;
|
||||
glm::vec2 m_lastMousePos;
|
||||
|
||||
float viewport_relativeXMouse, viewport_relativeYMouse;
|
||||
bool viewport_isActive;
|
||||
SceneCamera viewport_sceneCamera(TransformComponent(glm::vec3(16, 16, -16)), CameraComponent());
|
||||
float viewport_relativeXMouse, viewport_relativeYMouse;
|
||||
bool viewport_isActive;
|
||||
SceneCamera viewport_sceneCamera(TransformComponent(glm::vec3(16, 16, -16)),
|
||||
CameraComponent());
|
||||
|
||||
bool m_lastMousePressedButton1;
|
||||
bool m_handleClick;
|
||||
bool m_lastMousePressedButton1;
|
||||
bool m_handleClick;
|
||||
|
||||
float m_sensitivity = 0.005f;
|
||||
float m_sensitivity = 0.005f;
|
||||
|
||||
enum class TransformMode {
|
||||
Translate = 0,
|
||||
Rotate = 1,
|
||||
Scale = 2
|
||||
};
|
||||
enum class TransformMode { Translate = 0, Rotate = 1, Scale = 2 };
|
||||
|
||||
TransformMode m_transformMode = TransformMode::Translate;
|
||||
TransformMode m_transformMode = TransformMode::Translate;
|
||||
|
||||
void processMovment();
|
||||
bool viewport_onClickEvent(MouseButtonPressedEvent mouseEvent);
|
||||
bool viewport_onKeyEvent(KeyPressedEvent keyEvent);
|
||||
bool drawGizmos(int wPosX, int wPosY, int wSizeX, int wSizeY);
|
||||
void processMovment();
|
||||
bool viewport_onClickEvent(MouseButtonPressedEvent mouseEvent);
|
||||
bool viewport_onKeyEvent(KeyPressedEvent keyEvent);
|
||||
bool drawGizmos(int wPosX, int wPosY, int wSizeX, int wSizeY);
|
||||
|
||||
void viewport_onImGui() {
|
||||
processMovment();
|
||||
void viewport_onImGui() {
|
||||
processMovment();
|
||||
|
||||
if (!m_frameBuffer) {
|
||||
m_frameBuffer = FrameBuffer::create(FrameBufferSpecification(100, 100, { TextureBufferType::RGBA8, TextureBufferType::RED_INTEGER }, 4, false));
|
||||
}
|
||||
if (!m_frameBuffer) {
|
||||
m_frameBuffer = FrameBuffer::create(FrameBufferSpecification(
|
||||
100, 100,
|
||||
{TextureBufferType::RGBA8, TextureBufferType::RED_INTEGER}, 4,
|
||||
false));
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Viewport");
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("Viewport");
|
||||
|
||||
ImVec2 contentRegionMin = ImGui::GetWindowContentRegionMin();
|
||||
ImVec2 wPos = ImGui::GetWindowPos();
|
||||
wPos.y += contentRegionMin.y;
|
||||
ImVec2 contentRegionMin = ImGui::GetWindowContentRegionMin();
|
||||
ImVec2 wPos = ImGui::GetWindowPos();
|
||||
wPos.y += contentRegionMin.y;
|
||||
|
||||
if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)
|
||||
&& ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
|
||||
ImGui::SetWindowFocus();
|
||||
}
|
||||
if (ImGui::IsWindowHovered(
|
||||
ImGuiHoveredFlags_AllowWhenBlockedByPopup |
|
||||
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
|
||||
ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
|
||||
ImGui::SetWindowFocus();
|
||||
}
|
||||
|
||||
viewport_isActive = ImGui::IsWindowFocused();
|
||||
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
||||
viewport_isActive = ImGui::IsWindowFocused();
|
||||
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
||||
|
||||
if (m_lastWindowSize != *(glm::vec2*)&windowSize) {
|
||||
m_lastWindowSize = { windowSize.x, windowSize.y };
|
||||
m_frameBuffer->resize(windowSize.x, windowSize.y);
|
||||
viewport_sceneCamera.camera.aspect = (float)windowSize.x / (float)windowSize.y;
|
||||
}
|
||||
if (m_lastWindowSize != *(glm::vec2*)&windowSize) {
|
||||
m_lastWindowSize = {windowSize.x, windowSize.y};
|
||||
m_frameBuffer->resize(windowSize.x, windowSize.y);
|
||||
viewport_sceneCamera.camera.aspect =
|
||||
(float)windowSize.x / (float)windowSize.y;
|
||||
}
|
||||
|
||||
m_frameBuffer->bind();
|
||||
m_frameBuffer->clear();
|
||||
int clearData = -1;
|
||||
m_frameBuffer->clearBuffer(1, &clearData);
|
||||
unsigned char clearColor[4]{ 15, 10, 10, 255 };
|
||||
m_frameBuffer->clearBuffer(0, &clearColor);
|
||||
m_frameBuffer->bind();
|
||||
m_frameBuffer->clear();
|
||||
int clearData = -1;
|
||||
m_frameBuffer->clearBuffer(1, &clearData);
|
||||
unsigned char clearColor[4]{15, 10, 10, 255};
|
||||
m_frameBuffer->clearBuffer(0, &clearColor);
|
||||
|
||||
ImVec2 mPos = ImGui::GetMousePos();
|
||||
ImVec2 mPos = ImGui::GetMousePos();
|
||||
|
||||
viewport_relativeXMouse = (mPos.x - wPos.x) / windowSize.x;
|
||||
viewport_relativeYMouse = 1 - (mPos.y - wPos.y) / windowSize.y;
|
||||
viewport_relativeXMouse = (mPos.x - wPos.x) / windowSize.x;
|
||||
viewport_relativeYMouse = 1 - (mPos.y - wPos.y) / windowSize.y;
|
||||
|
||||
Project::m_scene.render(viewport_sceneCamera);
|
||||
Project::m_scene.render(viewport_sceneCamera);
|
||||
|
||||
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0), windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
bool isUsingDrawGizmo = drawGizmos(wPos.x, wPos.y, windowSize.x, windowSize.y);
|
||||
ImGui::Image((void*)(uint64_t)m_frameBuffer->getTextureBufferID(0),
|
||||
windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
bool isUsingDrawGizmo =
|
||||
drawGizmos(wPos.x, wPos.y, windowSize.x, windowSize.y);
|
||||
|
||||
if (!isUsingDrawGizmo && m_handleClick) {
|
||||
int relativeX, relativeY;
|
||||
if (!isUsingDrawGizmo && m_handleClick) {
|
||||
int relativeX, relativeY;
|
||||
|
||||
ImVec2 mPos = ImGui::GetMousePos();
|
||||
relativeX = mPos.x - wPos.x;
|
||||
relativeY = windowSize.y - (mPos.y - wPos.y);
|
||||
ImVec2 mPos = ImGui::GetMousePos();
|
||||
relativeX = mPos.x - wPos.x;
|
||||
relativeY = windowSize.y - (mPos.y - wPos.y);
|
||||
|
||||
if (relativeX >= 0 && relativeX < windowSize.x &&
|
||||
relativeY >= 0 && relativeY < windowSize.y) {
|
||||
if (relativeX >= 0 && relativeX < windowSize.x && relativeY >= 0 &&
|
||||
relativeY < windowSize.y) {
|
||||
int id = m_frameBuffer->getTextureBufferPixel(1, relativeX,
|
||||
relativeY);
|
||||
|
||||
int id = m_frameBuffer->getTextureBufferPixel(1, relativeX, relativeY);
|
||||
if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) ||
|
||||
Input::isKeyPressed(DEER_KEY_LEFT_ALT)))
|
||||
ActiveEntity::clear();
|
||||
|
||||
if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) || Input::isKeyPressed(DEER_KEY_LEFT_ALT)))
|
||||
ActiveEntity::clear();
|
||||
if (id >= 0) {
|
||||
Entity& selectedEntity =
|
||||
Project::m_scene.getMainEnviroment().getEntity(
|
||||
(uint32_t)id);
|
||||
ActiveEntity::addEntity(selectedEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id >= 0) {
|
||||
Entity& selectedEntity = Project::m_scene.getMainEnviroment()->getEntity((uint32_t)id);
|
||||
ActiveEntity::addEntity(selectedEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_handleClick = false;
|
||||
|
||||
m_handleClick = false;
|
||||
m_frameBuffer->unbind();
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
m_frameBuffer->unbind();
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
void processMovment() {
|
||||
if (!viewport_isActive) return;
|
||||
|
||||
void processMovment() {
|
||||
if (!viewport_isActive)
|
||||
return;
|
||||
if (!Input::isKeyPressed(DEER_KEY_LEFT_CONTROL)) {
|
||||
float vel = 1.5f;
|
||||
if (Input::isKeyPressed(DEER_KEY_LEFT_SHIFT)) vel = 8;
|
||||
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT)) vel = 1.0f;
|
||||
|
||||
if (!Input::isKeyPressed(DEER_KEY_LEFT_CONTROL)) {
|
||||
if (Input::isKeyPressed(DEER_KEY_W))
|
||||
viewport_sceneCamera.transform.position +=
|
||||
viewport_sceneCamera.transform.rotation *
|
||||
glm::vec3(0, 0, 1) * 0.02f * vel;
|
||||
|
||||
float vel = 1.5f;
|
||||
if (Input::isKeyPressed(DEER_KEY_LEFT_SHIFT))
|
||||
vel = 8;
|
||||
if (Input::isKeyPressed(DEER_KEY_LEFT_ALT))
|
||||
vel = 1.0f;
|
||||
if (Input::isKeyPressed(DEER_KEY_S))
|
||||
viewport_sceneCamera.transform.position +=
|
||||
viewport_sceneCamera.transform.rotation *
|
||||
glm::vec3(0, 0, -1) * 0.02f * vel;
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_W))
|
||||
viewport_sceneCamera.transform.position += viewport_sceneCamera.transform.rotation * glm::vec3(0, 0, 1) * 0.02f * vel;
|
||||
if (Input::isKeyPressed(DEER_KEY_D))
|
||||
viewport_sceneCamera.transform.position +=
|
||||
viewport_sceneCamera.transform.rotation *
|
||||
glm::vec3(1, 0, 0) * 0.02f * vel;
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_S))
|
||||
viewport_sceneCamera.transform.position += viewport_sceneCamera.transform.rotation * glm::vec3(0, 0, -1) * 0.02f * vel;
|
||||
if (Input::isKeyPressed(DEER_KEY_A))
|
||||
viewport_sceneCamera.transform.position +=
|
||||
viewport_sceneCamera.transform.rotation *
|
||||
glm::vec3(-1, 0, 0) * 0.02f * vel;
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_D))
|
||||
viewport_sceneCamera.transform.position += viewport_sceneCamera.transform.rotation * glm::vec3(1, 0, 0) * 0.02f * vel;
|
||||
if (Input::isKeyPressed(DEER_KEY_SPACE))
|
||||
viewport_sceneCamera.transform.position.y += 0.02f;
|
||||
}
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_A))
|
||||
viewport_sceneCamera.transform.position += viewport_sceneCamera.transform.rotation * glm::vec3(-1, 0, 0) * 0.02f * vel;
|
||||
if (Input::isMouseButtonPressed(DEER_MOUSE_BUTTON_2)) {
|
||||
float posX, posY;
|
||||
Input::getMousePos(posX, posY);
|
||||
glm::vec2 newMousePos = glm::vec2(posX, posY);
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_SPACE))
|
||||
viewport_sceneCamera.transform.position.y += 0.02f;
|
||||
if (m_lastMousePressedButton1) {
|
||||
glm::vec2 mouseDiff = newMousePos - m_lastMousePos;
|
||||
|
||||
}
|
||||
glm::quat pitchQuat = glm::angleAxis(
|
||||
mouseDiff.y * m_sensitivity, glm::vec3(1, 0, 0));
|
||||
glm::quat yawQuat = glm::angleAxis(mouseDiff.x * m_sensitivity,
|
||||
glm::vec3(0, 1, 0));
|
||||
|
||||
if (Input::isMouseButtonPressed(DEER_MOUSE_BUTTON_2)) {
|
||||
float posX, posY;
|
||||
Input::getMousePos(posX, posY);
|
||||
glm::vec2 newMousePos = glm::vec2(posX, posY);
|
||||
viewport_sceneCamera.transform.rotation =
|
||||
yawQuat * viewport_sceneCamera.transform.rotation *
|
||||
pitchQuat;
|
||||
}
|
||||
|
||||
if (m_lastMousePressedButton1) {
|
||||
glm::vec2 mouseDiff = newMousePos - m_lastMousePos;
|
||||
m_lastMousePos = newMousePos;
|
||||
m_lastMousePressedButton1 = true;
|
||||
} else
|
||||
m_lastMousePressedButton1 = false;
|
||||
}
|
||||
|
||||
glm::quat pitchQuat = glm::angleAxis(mouseDiff.y * m_sensitivity, glm::vec3(1, 0, 0));
|
||||
glm::quat yawQuat = glm::angleAxis(mouseDiff.x * m_sensitivity, glm::vec3(0, 1, 0));
|
||||
bool drawGizmos(int wPosX, int wPosY, int wSizeX, int wSizeY) {
|
||||
ImGuizmo::SetOrthographic(false);
|
||||
ImGuizmo::SetDrawlist();
|
||||
|
||||
viewport_sceneCamera.transform.rotation = yawQuat * viewport_sceneCamera.transform.rotation * pitchQuat;
|
||||
}
|
||||
glm::mat4 camMatrix =
|
||||
glm::inverse(viewport_sceneCamera.transform.getMatrix());
|
||||
glm::mat4 projectionMatrix =
|
||||
viewport_sceneCamera.camera.getMatrix() *
|
||||
glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
|
||||
|
||||
m_lastMousePos = newMousePos;
|
||||
m_lastMousePressedButton1 = true;
|
||||
}
|
||||
else
|
||||
m_lastMousePressedButton1 = false;
|
||||
}
|
||||
ImGuizmo::SetRect(wPosX, wPosY, wSizeX, wSizeY);
|
||||
if (ActiveEntity::count() != 0) {
|
||||
Entity& currentEntity = ActiveEntity::getEntity(0);
|
||||
|
||||
bool drawGizmos(int wPosX, int wPosY, int wSizeX, int wSizeY) {
|
||||
ImGuizmo::SetOrthographic(false);
|
||||
ImGuizmo::SetDrawlist();
|
||||
glm::mat4 entity_matrix = currentEntity.getWorldMatrix();
|
||||
|
||||
glm::mat4 camMatrix = glm::inverse(viewport_sceneCamera.transform.getMatrix());
|
||||
glm::mat4 projectionMatrix = viewport_sceneCamera.camera.getMatrix() * glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, -1));
|
||||
ImGuizmo::OPERATION operations;
|
||||
|
||||
ImGuizmo::SetRect(wPosX, wPosY, wSizeX, wSizeY);
|
||||
if (ActiveEntity::count() != 0) {
|
||||
ImGuizmo::Manipulate(
|
||||
glm::value_ptr(camMatrix), glm::value_ptr(projectionMatrix),
|
||||
(ImGuizmo::OPERATION)m_transformMode, ImGuizmo::MODE::LOCAL,
|
||||
glm::value_ptr(entity_matrix));
|
||||
|
||||
Entity& currentEntity = ActiveEntity::getEntity(0);
|
||||
if (ImGuizmo::IsUsing()) {
|
||||
glm::mat4 parentMatrix =
|
||||
currentEntity.getParent().getWorldMatrix();
|
||||
glm::mat4 relativeMatrix =
|
||||
glm::inverse(parentMatrix) * entity_matrix;
|
||||
|
||||
glm::mat4 entity_matrix = currentEntity.getWorldMatrix();
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
|
||||
ImGuizmo::OPERATION operations;
|
||||
TransformComponent& t =
|
||||
currentEntity.getComponent<TransformComponent>();
|
||||
glm::decompose(relativeMatrix, t.scale, t.rotation, t.position,
|
||||
skew, perspective);
|
||||
|
||||
ImGuizmo::Manipulate(glm::value_ptr(camMatrix), glm::value_ptr(projectionMatrix), (ImGuizmo::OPERATION)m_transformMode,
|
||||
ImGuizmo::MODE::LOCAL, glm::value_ptr(entity_matrix));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGuizmo::IsUsing()) {
|
||||
glm::mat4 parentMatrix = currentEntity.getParent().getWorldMatrix();
|
||||
glm::mat4 relativeMatrix = glm::inverse(parentMatrix) * entity_matrix;
|
||||
return false;
|
||||
}
|
||||
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
void viewport_onEvent(Event& e) {
|
||||
EventDispatcher dispatcher(e);
|
||||
|
||||
TransformComponent& t = currentEntity.getComponent<TransformComponent>();
|
||||
glm::decompose(relativeMatrix, t.scale, t.rotation, t.position, skew, perspective);
|
||||
dispatcher.dispatch<MouseButtonPressedEvent>(
|
||||
Deer::viewport_onClickEvent);
|
||||
dispatcher.dispatch<KeyPressedEvent>(Deer::viewport_onKeyEvent);
|
||||
}
|
||||
bool viewport_onClickEvent(MouseButtonPressedEvent mouseEvent) {
|
||||
if (!viewport_isActive) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mouseEvent.getMouseButton() == DEER_MOUSE_BUTTON_1)
|
||||
m_handleClick = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool viewport_onKeyEvent(KeyPressedEvent keyEvent) {
|
||||
if (!viewport_isActive) return false;
|
||||
|
||||
void viewport_onEvent(Event& e) {
|
||||
EventDispatcher dispatcher(e);
|
||||
if (Input::isKeyPressed(DEER_KEY_T))
|
||||
m_transformMode = TransformMode::Translate;
|
||||
if (Input::isKeyPressed(DEER_KEY_R))
|
||||
m_transformMode = TransformMode::Rotate;
|
||||
if (Input::isKeyPressed(DEER_KEY_G))
|
||||
m_transformMode = TransformMode::Scale;
|
||||
|
||||
dispatcher.dispatch<MouseButtonPressedEvent>(Deer::viewport_onClickEvent);
|
||||
dispatcher.dispatch<KeyPressedEvent>(Deer::viewport_onKeyEvent);
|
||||
}
|
||||
bool viewport_onClickEvent(MouseButtonPressedEvent mouseEvent) {
|
||||
if (!viewport_isActive)
|
||||
return false;
|
||||
if (Input::isKeyPressed(DEER_KEY_D) &&
|
||||
Input::isKeyPressed(DEER_KEY_LEFT_CONTROL)) {
|
||||
if (ActiveEntity::count() > 0)
|
||||
ActiveEntity::getEntity(0).duplicate();
|
||||
}
|
||||
|
||||
if (mouseEvent.getMouseButton() == DEER_MOUSE_BUTTON_1)
|
||||
m_handleClick = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
bool viewport_onKeyEvent(KeyPressedEvent keyEvent) {
|
||||
if (!viewport_isActive)
|
||||
return false;
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_T))
|
||||
m_transformMode = TransformMode::Translate;
|
||||
if (Input::isKeyPressed(DEER_KEY_R))
|
||||
m_transformMode = TransformMode::Rotate;
|
||||
if (Input::isKeyPressed(DEER_KEY_G))
|
||||
m_transformMode = TransformMode::Scale;
|
||||
|
||||
if (Input::isKeyPressed(DEER_KEY_D) && Input::isKeyPressed(DEER_KEY_LEFT_CONTROL)) {
|
||||
if (ActiveEntity::count() > 0)
|
||||
ActiveEntity::getEntity(0).duplicate();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace Deer
|
@ -9,19 +9,20 @@ Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Properties]
|
||||
Pos=724,240
|
||||
Size=569,648
|
||||
Pos=2152,24
|
||||
Size=408,1347
|
||||
Collapsed=0
|
||||
DockId=0x00000004,1
|
||||
|
||||
[Window][Game Window]
|
||||
Pos=0,24
|
||||
Size=2150,1347
|
||||
Pos=526,24
|
||||
Size=1624,1347
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Window][Tree Pannel]
|
||||
Pos=0,24
|
||||
Size=323,903
|
||||
Size=524,1347
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
@ -32,8 +33,8 @@ Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=0,24
|
||||
Size=2150,1347
|
||||
Pos=526,24
|
||||
Size=1624,1347
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@ -47,8 +48,8 @@ DockId=0x00000002,0
|
||||
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=2560,1347 Split=Y
|
||||
DockNode ID=0x00000001 Parent=0xA1672E74 SizeRef=2560,903 Split=X Selected=0x13926F0B
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=2150,779 Split=X Selected=0x13926F0B
|
||||
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=323,779 Selected=0xBD1B42A3
|
||||
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=1599,779 CentralNode=1 Selected=0x13926F0B
|
||||
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=524,779 Selected=0xBD1B42A3
|
||||
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=1624,779 CentralNode=1 Selected=0x13926F0B
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=408,779 Selected=0x2A2C795E
|
||||
DockNode ID=0x00000002 Parent=0xA1672E74 SizeRef=2560,442 Selected=0xCF339702
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user