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