Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c5992db4a | |||
| a4c8f44ae3 | |||
| 0b1dcb5e55 | |||
| 76f2204074 | |||
| b72fb412a7 | |||
| d377e99d31 | |||
| f154eac1e9 | |||
| 7489393d3d | |||
| 1af4547c97 | |||
| 3e222b09be | |||
| 7813d35cad | |||
| efab720485 | |||
| 5d0741635c | |||
| 041853a4a0 | |||
| 946c9e0027 | |||
| 6ee3cc146f | |||
| 398b655f3d | |||
| 818941460f | |||
| 2d15ff8c07 | |||
| 5d3fc40d74 | |||
| 84fa7a450b | |||
| baba8f2e09 | |||
| 9e6ee7b2e2 | |||
| f246d0e227 | |||
| 67b316a70b | |||
| 54f8156b6b | |||
| 47871fa1dc | |||
| ba42be46ba | |||
| 90f5569855 | |||
| a6328299ec | |||
| c9378c630d | |||
| 19c342b921 | |||
| 3817b5a355 | |||
| ded41e7c3e | |||
| 23989d5cf7 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@
|
|||||||
*.dbscn
|
*.dbscn
|
||||||
*.make
|
*.make
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
as.predefined
|
||||||
Makefile
|
Makefile
|
||||||
|
|
||||||
as.predefined_tmp
|
as.predefined_tmp
|
||||||
|
|||||||
@ -19,9 +19,12 @@ project "DeerService"
|
|||||||
"vendor/entt/include",
|
"vendor/entt/include",
|
||||||
"vendor/cereal/include",
|
"vendor/cereal/include",
|
||||||
"vendor/angelScript/include",
|
"vendor/angelScript/include",
|
||||||
"vendor/smallVector"
|
"vendor/smallVector",
|
||||||
|
"vendor/enet/include"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
links {"enet"}
|
||||||
|
|
||||||
targetdir ("../bin/" .. OutputDir .. "/%{prj.name}")
|
targetdir ("../bin/" .. OutputDir .. "/%{prj.name}")
|
||||||
objdir ("../bin/int/" .. OutputDir .. "/%{prj.name}")
|
objdir ("../bin/int/" .. OutputDir .. "/%{prj.name}")
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@ project "Deer"
|
|||||||
staticruntime "off"
|
staticruntime "off"
|
||||||
|
|
||||||
files {
|
files {
|
||||||
"src/Deer/**.h",
|
"src/DeerCore/**.h",
|
||||||
"src/Deer/**.cpp",
|
"src/DeerCore/**.cpp",
|
||||||
"src/DeerRender/**.h",
|
"src/DeerRender/**.h",
|
||||||
"src/DeerRender/**.cpp",
|
"src/DeerRender/**.cpp",
|
||||||
"src/Plattform/OpenGL/**.h",
|
"src/Plattform/OpenGL/**.h",
|
||||||
@ -35,7 +35,8 @@ project "Deer"
|
|||||||
"vendor/cereal/include",
|
"vendor/cereal/include",
|
||||||
"vendor/objload/include/objload",
|
"vendor/objload/include/objload",
|
||||||
"vendor/angelScript/include",
|
"vendor/angelScript/include",
|
||||||
"vendor/smallVector"
|
"vendor/smallVector",
|
||||||
|
"vendor/enet/include"
|
||||||
}
|
}
|
||||||
|
|
||||||
targetdir ("../bin/" .. OutputDir .. "/%{prj.name}")
|
targetdir ("../bin/" .. OutputDir .. "/%{prj.name}")
|
||||||
@ -81,7 +82,8 @@ project "Deer"
|
|||||||
"gdk_pixbuf-2.0", -- GDK Pixbuf library
|
"gdk_pixbuf-2.0", -- GDK Pixbuf library
|
||||||
"gio-2.0", -- GIO library
|
"gio-2.0", -- GIO library
|
||||||
"gobject-2.0", -- GObject library
|
"gobject-2.0", -- GObject library
|
||||||
"pthread" -- POSIX threads library
|
"pthread", -- POSIX threads library
|
||||||
|
"enet"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class ImGuiLayer;
|
|
||||||
namespace Core {
|
|
||||||
extern int argc;
|
|
||||||
extern char** argv;
|
|
||||||
} // namespace Core
|
|
||||||
|
|
||||||
class Timestep {
|
|
||||||
public:
|
|
||||||
Timestep(float time = 0.0f) : m_time(time) {}
|
|
||||||
|
|
||||||
float getSeconds() const { return m_time; }
|
|
||||||
float getMilliseconds() const { return m_time * 1000; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
float m_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Application {
|
|
||||||
using Function = void (*)();
|
|
||||||
|
|
||||||
extern bool running;
|
|
||||||
|
|
||||||
void run();
|
|
||||||
void setTickCallback(Function);
|
|
||||||
|
|
||||||
void shutdown();
|
|
||||||
} // namespace Application
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "Deer/Tools/TypeDefs.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
/*
|
|
||||||
class DataSource {
|
|
||||||
public:
|
|
||||||
using DataImporter = [ClassOfTheDataImporter]
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
using StorageMetadata = std::unordered_map<std::string, std::string>;
|
|
||||||
template <typename T>
|
|
||||||
concept HasMetadata = requires(const std::string& location) {
|
|
||||||
{ T::loadMetadata(location) } -> std::same_as<StorageMetadata>;
|
|
||||||
{ T::saveMetadata(StorageMetadata{}, location) };
|
|
||||||
};
|
|
||||||
|
|
||||||
class StorageData {
|
|
||||||
public:
|
|
||||||
StorageData() = default;
|
|
||||||
StorageData(uint32_t dataSize) : size(dataSize), data(MakeScope<uint8_t[]>(dataSize)) {}
|
|
||||||
|
|
||||||
inline uint8_t* getData() { return data.get(); }
|
|
||||||
inline const uint8_t* getData() const { return data.get(); }
|
|
||||||
inline uint32_t getSize() const { return size; }
|
|
||||||
inline StorageMetadata& getMetadata() { return metadata; }
|
|
||||||
|
|
||||||
template <typename DataImporter, typename T>
|
|
||||||
Scope<T> deserialize();
|
|
||||||
|
|
||||||
template <typename DataImporter, typename T>
|
|
||||||
static StorageData serialize(const T&);
|
|
||||||
|
|
||||||
inline explicit operator bool() const { return size != 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
StorageMetadata metadata;
|
|
||||||
Scope<uint8_t[]> data = nullptr;
|
|
||||||
uint32_t size = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DataSource>
|
|
||||||
class StorageBackend {
|
|
||||||
public:
|
|
||||||
static StorageData loadData(const std::string& location);
|
|
||||||
static void saveData(const std::string& location, const StorageData& data);
|
|
||||||
|
|
||||||
static StorageMetadata loadMetadata(const std::string& location);
|
|
||||||
static void saveMetadata(const StorageMetadata& metadata, const std::string& location);
|
|
||||||
|
|
||||||
static std::vector<std::string> indexResources(const std::string& location);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DataSource>
|
|
||||||
class DataManager {
|
|
||||||
public:
|
|
||||||
template <typename T>
|
|
||||||
static Scope<T> load(const std::string& dataId) {
|
|
||||||
StorageData data = StorageBackend<DataSource>::loadData(dataId);
|
|
||||||
|
|
||||||
if constexpr (HasMetadata<StorageBackend<DataSource>>) {
|
|
||||||
data.getMetadata() = StorageBackend<DataSource>::loadMetadata(dataId);
|
|
||||||
data.getMetadata()["dataId"] = dataId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data.deserialize<typename DataSource::DataImporter, T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void store(const std::string& dataId, T& value) {
|
|
||||||
StorageData data = StorageData::serialize<typename DataSource::DataImporter, T>(value);
|
|
||||||
StorageBackend<DataSource>::saveData(dataId, data);
|
|
||||||
if constexpr (HasMetadata<StorageBackend<DataSource>>) {
|
|
||||||
StorageBackend<DataSource>::saveMetadata(data.getMetadata(), dataId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Deer/Tools/Path.h"
|
|
||||||
|
|
||||||
#define DEER_RESOURCE_PATH "Assets"
|
|
||||||
|
|
||||||
#define DEER_VOXEL_PATH "Voxels"
|
|
||||||
#define DEER_VOXEL_DATA_PATH "Voxels/Data"
|
|
||||||
#define DEER_VOXEL_ASPECT_PATH "Voxels/Visuals"
|
|
||||||
#define DEER_VOXEL_TEXTURE_PATH "Voxels/Textures"
|
|
||||||
#define DEER_VOXEL_SHADER_PATH "Voxels/Shaders"
|
|
||||||
|
|
||||||
#define DEER_EDITOR_PATH "Editor"
|
|
||||||
#define DEER_EDITOR_PANEL_PATH "Editor/Panels"
|
|
||||||
#define DEER_EDITOR_SERVICE_PATH "Editor/Services"
|
|
||||||
|
|
||||||
#define DEER_MESH_EXTENSION ".dmesh"
|
|
||||||
#define DEER_SHADER_EXTENSION ".glsl"
|
|
||||||
#define DEER_SCRIPT_EXTENSION ".as"
|
|
||||||
|
|
||||||
#define DEER_BIN_PATH "bin"
|
|
||||||
#define DEER_TEMP_PATH "tmp"
|
|
||||||
#define DEER_NULL_PATH "null"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
|
|
||||||
struct DirectoryData {
|
|
||||||
std::vector<Path> dirs;
|
|
||||||
std::vector<Path> elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Namespace to manage memory interactions
|
|
||||||
namespace DataStore {
|
|
||||||
// Clears the cache of dir data
|
|
||||||
void clearCache();
|
|
||||||
|
|
||||||
// Rerturns a directory data with the elements relative to the id
|
|
||||||
const DirectoryData& getDirData(const Path& id, const Path& dir, const char* extension);
|
|
||||||
|
|
||||||
// TODO: Add safety
|
|
||||||
// Returns the data of the specified file path
|
|
||||||
bool loadFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
|
|
||||||
// Returns the data of the specified file path avoiding extension
|
|
||||||
bool loadGlobalFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size);
|
|
||||||
void freeFileData(uint8_t*);
|
|
||||||
|
|
||||||
void createFolder(const Path& path);
|
|
||||||
|
|
||||||
void saveFile(const Path&, uint8_t* data, uint32_t size);
|
|
||||||
uint8_t* readFile(const Path&, uint32_t* size);
|
|
||||||
void deleteFile(const Path&);
|
|
||||||
|
|
||||||
// Refactor----
|
|
||||||
void compressFiles(std::vector<Path> files, const Path& path);
|
|
||||||
std::vector<Path> getFiles(const Path& path,
|
|
||||||
const std::string& extension);
|
|
||||||
// Refactor----
|
|
||||||
} // namespace DataStore
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/DataStore.h"
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "Deer/Tools/Path.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/GizmoRenderer.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Environment;
|
|
||||||
class GizmoRenderer;
|
|
||||||
|
|
||||||
// A scene is a 3d simulation with its environment and voxel world in case
|
|
||||||
// of initialized, here things can be simulated
|
|
||||||
namespace Scene {
|
|
||||||
// Clears all the assets and memory the Scene had conained
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
// This is the cycle to execution of scripts and physics
|
|
||||||
void initExecution();
|
|
||||||
void tickExecution();
|
|
||||||
void endExecution();
|
|
||||||
|
|
||||||
bool getExecutingState();
|
|
||||||
uint32_t getCurrentExTick();
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
// This function renders with the default camera in the environment
|
|
||||||
void render();
|
|
||||||
void render(SceneCamera);
|
|
||||||
|
|
||||||
extern GizmoRenderer gizmoRenderer;
|
|
||||||
#endif
|
|
||||||
extern Environment environment;
|
|
||||||
} // namespace Scene
|
|
||||||
|
|
||||||
// Namespace to manage scenes in memory
|
|
||||||
namespace DataStore {
|
|
||||||
void loadScene(const Path& name);
|
|
||||||
void exportScene(const Path& name);
|
|
||||||
|
|
||||||
void exportRuntimeScene();
|
|
||||||
void importRuntimeScene();
|
|
||||||
} // namespace DataStore
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,296 +0,0 @@
|
|||||||
// Structure definition for voxel and voxel manipulation
|
|
||||||
// copyright Copyright (c) 2025 Deer
|
|
||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/VoxelAspect.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Texture2D;
|
|
||||||
class Shader;
|
|
||||||
} // namespace Deer
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VOXEL_INFO_TYPE_AIR "air"
|
|
||||||
#define VOXEL_INFO_TYPE_VOXEL "voxel"
|
|
||||||
#define VOXEL_INFO_TYPE_TRANSPARENT_VOXEL "transparentVoxel"
|
|
||||||
#define VOXEL_INFO_TYPE_CUSTOM "custom"
|
|
||||||
|
|
||||||
#define CHUNK_SIZE_X 32
|
|
||||||
#define CHUNK_SIZE_Y 32
|
|
||||||
#define CHUNK_SIZE_Z 32
|
|
||||||
#define CHUNK_SIZE(axis) \
|
|
||||||
((axis == 0) ? CHUNK_SIZE_X : (axis == 1) ? CHUNK_SIZE_Y \
|
|
||||||
: CHUNK_SIZE_Z)
|
|
||||||
|
|
||||||
#define LAYER_VOXELS CHUNK_SIZE_X* CHUNK_SIZE_Z
|
|
||||||
#define CHUNK_VOXELS CHUNK_SIZE_X* CHUNK_SIZE_Y* CHUNK_SIZE_Z
|
|
||||||
|
|
||||||
// TODO: Change this to be a inline function
|
|
||||||
#define VOXEL_POSITION(id) \
|
|
||||||
id.z + id.y* CHUNK_SIZE_Z + id.x* CHUNK_SIZE_Z* CHUNK_SIZE_Y
|
|
||||||
#define LAYER_VOXEL_POSITION(id) id.z + id.x* CHUNK_SIZE_Z
|
|
||||||
|
|
||||||
#define X_AXIS 0
|
|
||||||
#define Y_AXIS 1
|
|
||||||
#define Z_AXIS 2
|
|
||||||
|
|
||||||
// TODO: Change this to be a inline function
|
|
||||||
#define NORMAL_DIR(axis, normal) normalDirs[axis + normal * 3]
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
struct Voxel;
|
|
||||||
struct LayerVoxel;
|
|
||||||
|
|
||||||
extern Voxel nullVoxel;
|
|
||||||
extern Voxel emptyVoxel;
|
|
||||||
extern LayerVoxel nullLayerVoxel;
|
|
||||||
extern int normalDirs[3 * 6];
|
|
||||||
|
|
||||||
enum NormalDirection : uint8_t {
|
|
||||||
NORMAL_LEFT = 0,
|
|
||||||
NORMAL_RIGHT = 1,
|
|
||||||
NORMAL_DOWN = 2,
|
|
||||||
NORMAL_UP = 3,
|
|
||||||
NORMAL_BACK = 4,
|
|
||||||
NORMAL_FRONT = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class VoxelInfoType : uint8_t {
|
|
||||||
Air = 0,
|
|
||||||
Voxel = 1,
|
|
||||||
TransparentVoxel = 2,
|
|
||||||
Custom = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defines the general data of a voxel id stored in the array
|
|
||||||
// DataStore::voxelsInfo
|
|
||||||
struct VoxelInfo {
|
|
||||||
std::string name;
|
|
||||||
VoxelInfoType type = VoxelInfoType::Air;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Namespace to load and manage voxel data
|
|
||||||
namespace DataStore {
|
|
||||||
// List of the voxels loaded with loadVoxelsData()
|
|
||||||
extern std::vector<VoxelInfo> voxelsInfo;
|
|
||||||
|
|
||||||
// Loads basic voxel data from folder DEER_VOXEL_DATA_PATH defined in
|
|
||||||
// DataStore.h
|
|
||||||
void loadVoxelsData();
|
|
||||||
void createExampleVoxelData();
|
|
||||||
|
|
||||||
int32_t getVoxelID(const std::string&);
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
// List of the voxels Aspect loaded with loadVoxelsAspect()
|
|
||||||
extern std::vector<VoxelAspect> voxelsAspect;
|
|
||||||
|
|
||||||
// Loads voxel aspect from folder DEER_VOXEL_ASPECT_PATH defined in
|
|
||||||
// DataStore.h
|
|
||||||
void loadVoxelsAspect();
|
|
||||||
void createExampleVoxelAspect();
|
|
||||||
|
|
||||||
// Generates the texture atlas that the voxels demanded from folder
|
|
||||||
// DEER_VOXEL_TEXTURE_PATH defined in DataStore.h Warning : This
|
|
||||||
// function must be called with a render context, otherwise this will
|
|
||||||
// crash
|
|
||||||
void generateTextureAtlas();
|
|
||||||
// Loads the shaders for rendering chunks from folder
|
|
||||||
// DEER_VOXEL_SHADER_PATH defined in DataStore.h
|
|
||||||
void loadVoxelsShaders();
|
|
||||||
|
|
||||||
// Returns with & height of the texture atlas generated
|
|
||||||
// Warning: If you call this before generate Texture Atlas the return
|
|
||||||
// value will be 0
|
|
||||||
int getVoxelTextureAtlasSize();
|
|
||||||
// Texture atlas created with generateTextureAtlas() call
|
|
||||||
// Warning: You must have called generateTextureAtlas() in order to work
|
|
||||||
/// Ref<Texture2D>& getVoxelColorTextureAtlas();
|
|
||||||
// Returns the shader created with loadVoxelsShaders()
|
|
||||||
// Warning: You must have called loadVoxelsShaders() in order to work
|
|
||||||
/// Ref<Shader>& getSolidVoxelShader();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
} // namespace DataStore
|
|
||||||
|
|
||||||
// Structure to define what a voxel inside a world must have
|
|
||||||
struct Voxel {
|
|
||||||
// Reference to the voxel id
|
|
||||||
uint16_t id = 0;
|
|
||||||
|
|
||||||
Voxel() = default;
|
|
||||||
Voxel(uint16_t _id) : id(_id) {}
|
|
||||||
|
|
||||||
inline bool operator==(const Voxel& b) const { return id == b.id; }
|
|
||||||
inline bool isVoxelType() const {
|
|
||||||
return DataStore::voxelsInfo[id].type == VoxelInfoType::Voxel;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Structure to define the general cordinates of a voxel in the world
|
|
||||||
struct VoxelCordinates {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int32_t x, y, z;
|
|
||||||
};
|
|
||||||
std::array<int32_t, 3> data;
|
|
||||||
};
|
|
||||||
|
|
||||||
VoxelCordinates(int32_t _x = 0, int32_t _y = 0, int32_t _z = 0)
|
|
||||||
: x(_x), y(_y), z(_z) {}
|
|
||||||
|
|
||||||
inline int32_t& operator[](int id) { return data[id]; }
|
|
||||||
inline bool operator==(const VoxelCordinates& b) const {
|
|
||||||
return x == b.x && y == b.y && z == b.z;
|
|
||||||
}
|
|
||||||
inline bool isNull() const { return x < 0 || y < 0 || z < 0; }
|
|
||||||
inline void makeNull() { x = -1; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Stucture that defines the info of a layer voxel
|
|
||||||
struct LayerVoxel {
|
|
||||||
uint16_t height = 0;
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
uint16_t ambient_light_height = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LayerVoxel() = default;
|
|
||||||
LayerVoxel(uint16_t _height) : height(_height) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returning info of a raycast
|
|
||||||
struct VoxelRayResult {
|
|
||||||
float distance = 0;
|
|
||||||
VoxelCordinates hitPos;
|
|
||||||
uint8_t face = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Coordinates of a chunk
|
|
||||||
struct ChunkID {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint16_t x;
|
|
||||||
uint16_t y;
|
|
||||||
uint16_t z;
|
|
||||||
};
|
|
||||||
std::array<uint16_t, 3> axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkID(uint16_t _x = 0, uint16_t _y = 0, uint16_t _z = 0)
|
|
||||||
: x(_x), y(_y), z(_z) {}
|
|
||||||
|
|
||||||
inline bool operator==(const ChunkID& b) const {
|
|
||||||
return x == b.x && y == b.y && z == b.z;
|
|
||||||
}
|
|
||||||
inline uint16_t& operator[](size_t i) { return axis[i]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ChunkIDHash {
|
|
||||||
size_t operator()(const ChunkID& chunk) const {
|
|
||||||
size_t h1 = std::hash<uint16_t>{}(chunk.x);
|
|
||||||
size_t h2 = std::hash<uint16_t>{}(chunk.y);
|
|
||||||
size_t h3 = std::hash<uint16_t>{}(chunk.z);
|
|
||||||
|
|
||||||
size_t result = h1;
|
|
||||||
result = result * 31 + h2;
|
|
||||||
result = result * 31 + h3;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Cordinates of a Layer
|
|
||||||
struct LayerID {
|
|
||||||
uint16_t x = 0;
|
|
||||||
uint16_t z = 0;
|
|
||||||
|
|
||||||
LayerID() = default;
|
|
||||||
LayerID(uint16_t _x, uint16_t _z) : x(_x), z(_z) {}
|
|
||||||
inline bool operator==(const LayerID& b) const {
|
|
||||||
return x == b.x && z == b.z;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Coordinates of a layer voxel relative to the Layer Chunk
|
|
||||||
struct LayerVoxelID {
|
|
||||||
uint8_t x = 0;
|
|
||||||
uint8_t z = 0;
|
|
||||||
|
|
||||||
LayerVoxelID() = default;
|
|
||||||
LayerVoxelID(uint8_t _x, uint8_t _z = 0) : x(_x), z(_z) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Coordinates of a voxel inside a Chunk
|
|
||||||
struct ChunkVoxelID {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint8_t x;
|
|
||||||
uint8_t y;
|
|
||||||
uint8_t z;
|
|
||||||
};
|
|
||||||
std::array<uint8_t, 3> axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
ChunkVoxelID(uint8_t _x = 0, uint8_t _y = 0, uint8_t _z = 0)
|
|
||||||
: x(_x), y(_y), z(_z) {}
|
|
||||||
inline uint8_t& operator[](size_t i) { return axis[i]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extracts the chunk coordinaes and the chunk voxel coordinates from a
|
|
||||||
// world position
|
|
||||||
inline void extractChunkCordinates(uint32_t x, uint32_t y, uint32_t z,
|
|
||||||
ChunkID& _chunkID,
|
|
||||||
ChunkVoxelID& _chunkVoxelID) {
|
|
||||||
uint16_t posX = x;
|
|
||||||
uint16_t posY = y;
|
|
||||||
uint16_t posZ = z;
|
|
||||||
|
|
||||||
_chunkID.x = posX >> 5;
|
|
||||||
_chunkID.y = posY >> 5;
|
|
||||||
_chunkID.z = posZ >> 5;
|
|
||||||
|
|
||||||
_chunkVoxelID.x = posX & 31;
|
|
||||||
_chunkVoxelID.y = posY & 31;
|
|
||||||
_chunkVoxelID.z = posZ & 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extracts the chunk coordinaes and the chunk voxel chunk coordinates from
|
|
||||||
// a world position
|
|
||||||
inline void extractChunkCordinates(VoxelCordinates coords,
|
|
||||||
ChunkID& _chunkID,
|
|
||||||
ChunkVoxelID& _chunkVoxelID) {
|
|
||||||
uint16_t posX = coords.x;
|
|
||||||
uint16_t posY = coords.y;
|
|
||||||
uint16_t posZ = coords.z;
|
|
||||||
|
|
||||||
_chunkID.x = posX >> 5;
|
|
||||||
_chunkID.y = posY >> 5;
|
|
||||||
_chunkID.z = posZ >> 5;
|
|
||||||
|
|
||||||
_chunkVoxelID.x = posX & 31;
|
|
||||||
_chunkVoxelID.y = posY & 31;
|
|
||||||
_chunkVoxelID.z = posZ & 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extracts the layer chunk coordinaes and the layer chunk voxel coordinates
|
|
||||||
// from a world position
|
|
||||||
inline void extractLayerCordinates(uint32_t x, uint32_t z,
|
|
||||||
LayerID& _layerID,
|
|
||||||
LayerVoxelID& _layerVoxelID) {
|
|
||||||
uint16_t posX = x;
|
|
||||||
uint16_t posZ = z;
|
|
||||||
|
|
||||||
_layerID.x = posX >> 5;
|
|
||||||
_layerID.z = posZ >> 5;
|
|
||||||
|
|
||||||
_layerVoxelID.x = posX & 31;
|
|
||||||
_layerVoxelID.z = posZ & 31;
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
// copyright Copyright (c) 2025 Deer
|
|
||||||
#pragma once
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/Voxel.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "glm/glm.hpp"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Chunk;
|
|
||||||
class Layer;
|
|
||||||
struct SceneCamera;
|
|
||||||
struct VoxelWorldProps;
|
|
||||||
struct VoxelWorldRenderData;
|
|
||||||
|
|
||||||
// Properties of a Voxel World
|
|
||||||
struct VoxelWorldProps {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint8_t chunkSizeX;
|
|
||||||
uint8_t chunkSizeY;
|
|
||||||
uint8_t chunkSizeZ;
|
|
||||||
};
|
|
||||||
std::array<uint8_t, 3> axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
VoxelWorldProps() = default;
|
|
||||||
VoxelWorldProps(uint8_t _chunkSizeX, uint8_t _chunkSizeY,
|
|
||||||
uint8_t _chunkSizeZ)
|
|
||||||
: chunkSizeX(_chunkSizeX),
|
|
||||||
chunkSizeY(_chunkSizeY),
|
|
||||||
chunkSizeZ(_chunkSizeZ) {}
|
|
||||||
|
|
||||||
inline uint8_t& operator[](size_t i) { return axis[i]; }
|
|
||||||
|
|
||||||
// Returns the count of chunks
|
|
||||||
inline int getChunkCount() const {
|
|
||||||
return chunkSizeX * chunkSizeY * chunkSizeZ;
|
|
||||||
}
|
|
||||||
// Returns the count of layers
|
|
||||||
inline int getLayerCount() const { return chunkSizeX * chunkSizeZ; }
|
|
||||||
// Returns the internal id of a chunk relative to a Voxel World Props
|
|
||||||
// from a chunk id
|
|
||||||
inline int getWorldChunkID(ChunkID chunkID) const {
|
|
||||||
return chunkID.z + chunkID.y * chunkSizeZ +
|
|
||||||
chunkID.x * chunkSizeZ * chunkSizeY;
|
|
||||||
}
|
|
||||||
// Returns the internal id of a layer relative to a Voxel World Props
|
|
||||||
// from a Layer id
|
|
||||||
inline int getWorldLayerID(LayerID layerID) const {
|
|
||||||
return layerID.z + layerID.x * chunkSizeZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extracts the LayerID from a internal Layer id relative to Voxel World
|
|
||||||
// Props
|
|
||||||
inline LayerID getLayerID(int id) const {
|
|
||||||
LayerID l_id;
|
|
||||||
|
|
||||||
l_id.x = id / chunkSizeZ;
|
|
||||||
id -= l_id.x * chunkSizeZ;
|
|
||||||
|
|
||||||
l_id.z = id;
|
|
||||||
return l_id;
|
|
||||||
}
|
|
||||||
// Extracts the ChunkID from a internal Chunk id relative to Voxel World
|
|
||||||
// Props
|
|
||||||
inline ChunkID getChunkID(int id) const {
|
|
||||||
ChunkID c_id;
|
|
||||||
|
|
||||||
c_id.x = id / (chunkSizeZ * chunkSizeY);
|
|
||||||
id -= c_id.x * (chunkSizeZ * chunkSizeY);
|
|
||||||
|
|
||||||
c_id.y = id / chunkSizeZ;
|
|
||||||
id -= c_id.y * chunkSizeZ;
|
|
||||||
|
|
||||||
c_id.z = id;
|
|
||||||
return c_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if the Chunk id is inside the voxel World bounds
|
|
||||||
inline bool isValid(ChunkID chunkID) const {
|
|
||||||
return chunkID.x >= 0 && chunkID.x < chunkSizeX && chunkID.y >= 0 &&
|
|
||||||
chunkID.y < chunkSizeY && chunkID.z >= 0 &&
|
|
||||||
chunkID.z < chunkSizeZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if the Layer id is inside the voxel World bounds
|
|
||||||
inline bool isValid(LayerID layerID) const {
|
|
||||||
return layerID.x >= 0 && layerID.x < chunkSizeX && layerID.z >= 0 &&
|
|
||||||
layerID.z < chunkSizeZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the max amount of voxels in the Voxel World Props
|
|
||||||
inline int getMaxVoxelCount() const {
|
|
||||||
return getChunkCount() * CHUNK_VOXELS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clamps the coordinates of a Voxel World Coordinates to be inside the
|
|
||||||
// voxel world props
|
|
||||||
inline void clampCordinates(VoxelCordinates& coords) const {
|
|
||||||
if (coords.x < 0)
|
|
||||||
coords.x = 0;
|
|
||||||
else if (coords.x >= chunkSizeX * CHUNK_SIZE_X)
|
|
||||||
coords.x = chunkSizeX * CHUNK_SIZE_X - 1;
|
|
||||||
|
|
||||||
if (coords.y < 0)
|
|
||||||
coords.y = 0;
|
|
||||||
else if (coords.y >= chunkSizeY * CHUNK_SIZE_Y)
|
|
||||||
coords.y = chunkSizeY * CHUNK_SIZE_Y - 1;
|
|
||||||
|
|
||||||
if (coords.z < 0)
|
|
||||||
coords.z = 0;
|
|
||||||
else if (coords.z >= chunkSizeZ * CHUNK_SIZE_Z)
|
|
||||||
coords.z = chunkSizeZ * CHUNK_SIZE_Z - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes 2 Voxel coordinates and outputs them in the same variables
|
|
||||||
// being the min with the min values and the max with the max This is
|
|
||||||
// useful for loops
|
|
||||||
inline void clampAndSetMinMax(VoxelCordinates& min,
|
|
||||||
VoxelCordinates& max) const {
|
|
||||||
VoxelCordinates a_cache = min;
|
|
||||||
VoxelCordinates b_cache = max;
|
|
||||||
|
|
||||||
for (int x = 0; x < 3; x++) {
|
|
||||||
if (a_cache[x] > b_cache[x]) {
|
|
||||||
max[x] = a_cache[x];
|
|
||||||
min[x] = b_cache[x];
|
|
||||||
} else {
|
|
||||||
min[x] = a_cache[x];
|
|
||||||
max[x] = b_cache[x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clampCordinates(min);
|
|
||||||
clampCordinates(max);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class to manage the voxels
|
|
||||||
namespace VoxelWorld {
|
|
||||||
void initialize(const VoxelWorldProps&);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
// Returns the voxel in a voxel coordinates
|
|
||||||
Voxel readVoxel(VoxelCordinates);
|
|
||||||
// Sets the voxel in the coordinates to the value
|
|
||||||
void setVoxel(VoxelCordinates, Voxel value);
|
|
||||||
|
|
||||||
// Fills a space with the voxel value inside the 2 coordinates
|
|
||||||
// Note that you don't have to give then ordeered by min and max
|
|
||||||
void fillVoxels(VoxelCordinates, VoxelCordinates, Voxel value);
|
|
||||||
// Remplaces the ref voxel with the value of a space inside the 2 coordinates
|
|
||||||
// Note that you don't have to give then ordeered by min and max
|
|
||||||
void remplaceVoxels(VoxelCordinates, VoxelCordinates, Voxel ref, Voxel value);
|
|
||||||
|
|
||||||
// Returns the layer data of a woorld coordinates
|
|
||||||
// Note out of bounds will return a default Layer Voxel
|
|
||||||
LayerVoxel readLayerVoxel(int x, int z);
|
|
||||||
// Calculates the max height of a layer in a space
|
|
||||||
// Note out of bounds will return a 0 of height
|
|
||||||
// Tip: this will calculate, you should use the cached height in a layer voxel
|
|
||||||
uint16_t calculateLayerVoxelHeight(int x, int z);
|
|
||||||
|
|
||||||
// Raycast a ray from a source and dir
|
|
||||||
VoxelRayResult rayCast(glm::vec3 position, glm::vec3 dir,
|
|
||||||
float maxDistance = 10.0f);
|
|
||||||
// Raycast a ray from a source and dir ignoring if the ray stats inside a voxel
|
|
||||||
VoxelRayResult rayCast_editor(glm::vec3 position, glm::vec3 dir,
|
|
||||||
float maxDistance = 10.0f);
|
|
||||||
|
|
||||||
bool isInitialized();
|
|
||||||
|
|
||||||
// Returns the voxel world props used in the voxel world
|
|
||||||
// Note that you can't change the world size unless you create a new Voxel World
|
|
||||||
const VoxelWorldProps& getWorldProps();
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
// Renders the current voxel world with a specified scene camera
|
|
||||||
void render(const SceneCamera&);
|
|
||||||
// Generates the next chunk mesh
|
|
||||||
void bakeNextChunk();
|
|
||||||
|
|
||||||
// Light data
|
|
||||||
VoxelLight readLight(VoxelCordinates);
|
|
||||||
VoxelLight& modLight(VoxelCordinates);
|
|
||||||
|
|
||||||
// Chunk vertex creation
|
|
||||||
void genSolidVoxel(ChunkID chunkID, ChunkVoxelID chunkVoxelID);
|
|
||||||
|
|
||||||
// --- Light propagation ---
|
|
||||||
// Warning: This function is private and needs to have min and max
|
|
||||||
// clamped and in order
|
|
||||||
void bakeVoxelLight(VoxelCordinates min, VoxelCordinates max);
|
|
||||||
void bakeVoxelLightFromPoint(VoxelCordinates);
|
|
||||||
void bakeAmbientLight(int minX, int maxX, int minZ, int maxZ);
|
|
||||||
void bakeAmbientLightFromPoint(int x, int z);
|
|
||||||
|
|
||||||
void resolveNextAmbientLightPropagation();
|
|
||||||
void resolveNextVoxelLightPropagation();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LayerVoxel& modLayerVoxel(int x, int z);
|
|
||||||
} // namespace VoxelWorld
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
#include "Deer/Tools/SmallVector.h"
|
#include "DeerCore/Tools/SmallVector.h"
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Deer/Log.h"
|
#include "DeerCore/Log.h"
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
#include "glm/gtc/quaternion.hpp"
|
#include "glm/gtc/quaternion.hpp"
|
||||||
|
|
||||||
@ -18,10 +18,16 @@
|
|||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
class ComponentScriptInstance;
|
class ComponentScriptInstance;
|
||||||
|
enum class EntityNetworkBehaviour : uint32_t {
|
||||||
|
PARENT = 0,
|
||||||
|
SERVER = 1 << 0,
|
||||||
|
CLIENT = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
struct TagComponent {
|
struct TagComponent {
|
||||||
std::string tag;
|
std::string tag;
|
||||||
uint32_t entityUID;
|
uint32_t entityUID;
|
||||||
|
EntityNetworkBehaviour networkBehaviour = EntityNetworkBehaviour::PARENT;
|
||||||
|
|
||||||
TagComponent() = default;
|
TagComponent() = default;
|
||||||
TagComponent(const TagComponent&) = default;
|
TagComponent(const TagComponent&) = default;
|
||||||
@ -30,18 +36,18 @@ namespace Deer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RelationshipComponent {
|
struct RelationshipComponent {
|
||||||
uint16_t parent_id = 0;
|
u_int32_t parent_id = 0;
|
||||||
|
|
||||||
// Use p-ranav's small_vector for children storage
|
// Use p-ranav's small_vector for children storage
|
||||||
// Inline capacity ENTITY_MAX_CHILDREN, fallback to heap if exceeded
|
// Inline capacity ENTITY_MAX_CHILDREN, fallback to heap if exceeded
|
||||||
ankerl::svector<uint16_t, ENTITY_BUFFER_CHILDREN> children;
|
ankerl::svector<u_int32_t, ENTITY_BUFFER_CHILDREN> children;
|
||||||
|
|
||||||
inline uint16_t getChildId(size_t i) const {
|
inline u_int32_t getChildId(size_t i) const {
|
||||||
DEER_CORE_ASSERT(i < children.size() && children[i] != 0, "Invalid child request {0}", i);
|
DEER_CORE_ASSERT(i < children.size() && children[i] != 0, "Invalid child request {0}", i);
|
||||||
return children[i];
|
return children[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void addChildId(uint16_t childId) {
|
inline void addChildId(u_int32_t childId) {
|
||||||
// Prevent duplicates
|
// Prevent duplicates
|
||||||
for (auto id : children)
|
for (auto id : children)
|
||||||
if (id == childId)
|
if (id == childId)
|
||||||
@ -49,7 +55,7 @@ namespace Deer {
|
|||||||
children.push_back(childId);
|
children.push_back(childId);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool removeChild(uint16_t childId) {
|
inline bool removeChild(u_int32_t childId) {
|
||||||
for (size_t i = 0; i < children.size(); ++i) {
|
for (size_t i = 0; i < children.size(); ++i) {
|
||||||
if (children[i] == childId) {
|
if (children[i] == childId) {
|
||||||
// Swap-remove for O(1)
|
// Swap-remove for O(1)
|
||||||
@ -67,7 +73,7 @@ namespace Deer {
|
|||||||
|
|
||||||
RelationshipComponent() = default;
|
RelationshipComponent() = default;
|
||||||
RelationshipComponent(const RelationshipComponent&) = default;
|
RelationshipComponent(const RelationshipComponent&) = default;
|
||||||
RelationshipComponent(uint16_t _parent) : parent_id(_parent) {}
|
RelationshipComponent(u_int32_t _parent) : parent_id(_parent) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransformComponent {
|
struct TransformComponent {
|
||||||
@ -75,9 +81,9 @@ namespace Deer {
|
|||||||
glm::vec3 scale = glm::vec3(1.0f);
|
glm::vec3 scale = glm::vec3(1.0f);
|
||||||
glm::quat rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
glm::quat rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
TransformComponent() = default;
|
TransformComponent() {}
|
||||||
TransformComponent(glm::vec3 _position) : position(_position) {}
|
TransformComponent(glm::vec3 _position) : position(_position) {}
|
||||||
TransformComponent(const TransformComponent&) = default;
|
TransformComponent(const TransformComponent&) {}
|
||||||
|
|
||||||
inline const glm::vec3 getEulerAngles() {
|
inline const glm::vec3 getEulerAngles() {
|
||||||
return glm::degrees(glm::eulerAngles(rotation));
|
return glm::degrees(glm::eulerAngles(rotation));
|
||||||
12
Deer/Include/DeerCore/Engine.h
Normal file
12
Deer/Include/DeerCore/Engine.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
using Function = void (*)();
|
||||||
|
|
||||||
|
namespace Engine {
|
||||||
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
void setUpdateCallback(Function);
|
||||||
|
} // namespace Engine
|
||||||
|
} // namespace Deer
|
||||||
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Components.h"
|
#include "DeerCore/Components.h"
|
||||||
#include "Deer/Log.h"
|
#include "DeerCore/Log.h"
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
|
||||||
#include "entt/entt.hpp"
|
#include "entt/entt.hpp"
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
#ifdef DEER_RENDER
|
||||||
#include "DeerRender/Render/FrameBuffer.h"
|
#include "DeerRender/Render/FrameBuffer.h"
|
||||||
#include "DeerRender/Scene.h"
|
#include "DeerRender/World.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -19,37 +19,28 @@
|
|||||||
namespace Deer {
|
namespace Deer {
|
||||||
class Entity;
|
class Entity;
|
||||||
|
|
||||||
class Environment {
|
class EntityEnvironment {
|
||||||
// Note: Outdated note
|
|
||||||
///////// 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();
|
EntityEnvironment();
|
||||||
~Environment();
|
~EntityEnvironment();
|
||||||
// This class can not be copyed
|
// This class can not be copyed
|
||||||
Environment(const Environment&) = delete;
|
EntityEnvironment(const EntityEnvironment&) = delete;
|
||||||
Environment& operator=(Environment&) = delete;
|
EntityEnvironment& operator=(EntityEnvironment&) = delete;
|
||||||
|
|
||||||
// Clears all entities
|
// Clears all entities
|
||||||
void clear();
|
void clear();
|
||||||
// Obtains the entity
|
// Obtains the entity
|
||||||
Entity& getEntity(uint16_t id);
|
Entity& getEntity(uint32_t id);
|
||||||
bool entityExists(uint16_t id) const;
|
bool entityExists(uint32_t id) const;
|
||||||
uint16_t getEntityCount() const;
|
uint32_t getEntityCount() const;
|
||||||
|
|
||||||
// Creates a entity child at root
|
// Creates a entity child at root
|
||||||
// WARNING: This method can change internal pointers and invalidate entitiy references
|
// WARNING: This method can change internal pointers and invalidate entitiy references
|
||||||
Entity& createEntity(const std::string& name = "");
|
Entity& createEntity(const std::string& name = "");
|
||||||
// Can be slow! This has to empty the stack of empty entities in case its necessary so use it in ascendent order!
|
// Can be slow! This has to empty the stack of empty entities in case its necessary so use it in ascendent order!
|
||||||
// WARNING: This method can change internal pointers and invalidate entitiy references
|
// WARNING: This method can change internal pointers and invalidate entitiy references
|
||||||
Entity& createEntityWithId(uint16_t id, const std::string& name = "");
|
Entity& createEntityWithId(uint32_t id, const std::string& name = "");
|
||||||
void destroyEntity(uint16_t id);
|
void destroyEntity(uint32_t id);
|
||||||
|
|
||||||
// Special behaviour
|
// Special behaviour
|
||||||
// WARNING: This method can change internal pointers and invalidate entitiy references
|
// WARNING: This method can change internal pointers and invalidate entitiy references
|
||||||
@ -62,20 +53,19 @@ namespace Deer {
|
|||||||
// Obtains the entity that is on the root of the environment
|
// Obtains the entity that is on the root of the environment
|
||||||
inline Entity& getRoot() { return getEntity(0); }
|
inline Entity& getRoot() { return getEntity(0); }
|
||||||
#ifdef DEER_RENDER
|
#ifdef DEER_RENDER
|
||||||
void render(SceneCamera& camera);
|
void render(const WorldCamera& camera);
|
||||||
#endif
|
#endif
|
||||||
Scope<entt::registry> m_registry;
|
Scope<entt::registry> m_registry;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t m_mainCamera = 0;
|
uint16_t m_mainCamera = 0;
|
||||||
|
|
||||||
std::stack<u_int16_t> unused_entities_spaces;
|
std::stack<u_int32_t> unused_entities_spaces;
|
||||||
std::vector<Entity> entities;
|
std::vector<Entity> entities;
|
||||||
|
|
||||||
friend class Entity;
|
friend class Entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Warning: This calss does not initialize for performance
|
|
||||||
class Entity {
|
class Entity {
|
||||||
public:
|
public:
|
||||||
Entity() {}
|
Entity() {}
|
||||||
@ -87,15 +77,18 @@ namespace Deer {
|
|||||||
Entity& duplicate();
|
Entity& duplicate();
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
uint16_t getId() const { return entId; }
|
uint32_t getId() const { return entId; }
|
||||||
Entity& getParent() const;
|
Entity& getParent() const;
|
||||||
inline uint16_t getParentId() const { return parentId; }
|
inline uint32_t getParentId() const { return parentId; }
|
||||||
|
|
||||||
|
EntityNetworkBehaviour getForcedNetworkBehaviour();
|
||||||
|
bool isValidNetworkBehaviour(EntityNetworkBehaviour nb = EntityNetworkBehaviour::PARENT);
|
||||||
|
|
||||||
// TODO, enable transfer entitys from difrent environments
|
// TODO, enable transfer entitys from difrent environments
|
||||||
void setParent(Entity& parent);
|
void setParent(Entity& parent);
|
||||||
bool isDescendantOf(Entity& parent) const;
|
bool isDescendantOf(Entity& parent) const;
|
||||||
|
|
||||||
Environment* getEnvironment() const { return environment; }
|
EntityEnvironment* getEntityEnvironment() const { return environment; }
|
||||||
|
|
||||||
bool isRoot() const { return entId == 0; }
|
bool isRoot() const { return entId == 0; }
|
||||||
glm::mat4 getWorldMatrix() const;
|
glm::mat4 getWorldMatrix() const;
|
||||||
@ -107,14 +100,14 @@ namespace Deer {
|
|||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Environment* environment = nullptr;
|
EntityEnvironment* environment = nullptr;
|
||||||
entt::entity entHandle = entt::null;
|
entt::entity entHandle = entt::null;
|
||||||
uint16_t entId = 0;
|
uint32_t entId = 0;
|
||||||
uint16_t parentId = 0;
|
uint32_t parentId = 0;
|
||||||
|
|
||||||
Entity(entt::entity handle, Environment* scene, uint16_t entityID);
|
Entity(entt::entity handle, EntityEnvironment* scene, uint32_t entityID);
|
||||||
|
|
||||||
friend class Environment;
|
friend class EntityEnvironment;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
@ -123,8 +116,7 @@ namespace Deer {
|
|||||||
!environment->m_registry->all_of<T>(entHandle),
|
!environment->m_registry->all_of<T>(entHandle),
|
||||||
"Entity already have component {0}", typeid(T).name());
|
"Entity already have component {0}", typeid(T).name());
|
||||||
|
|
||||||
return environment->m_registry->emplace<T>(
|
return environment->m_registry->emplace<T>(entHandle, std::forward<Args>(args)...);
|
||||||
entHandle, std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
@ -10,32 +9,17 @@ namespace spdlog {
|
|||||||
// Simple file to define logs functions optimized depending on the compilation
|
// Simple file to define logs functions optimized depending on the compilation
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
class Log {
|
namespace Log {
|
||||||
public:
|
void init();
|
||||||
static void init();
|
void shutdown();
|
||||||
static void shutdown();
|
|
||||||
|
|
||||||
static void coreTrace(const char* msg);
|
void coreTrace(const char* msg);
|
||||||
|
|
||||||
static inline Ref<spdlog::logger>& getCoreLogger() {
|
spdlog::logger* getCoreLogger();
|
||||||
return coreLogger;
|
spdlog::logger* getClientLogger();
|
||||||
}
|
spdlog::logger* getScriptLogger();
|
||||||
static inline Ref<spdlog::logger>& getClientLogger() {
|
spdlog::logger* getEditorEngineLogger();
|
||||||
return clientLogger;
|
}; // namespace Log
|
||||||
}
|
|
||||||
static inline Ref<spdlog::logger>& getScriptLogger() {
|
|
||||||
return scriptLogger;
|
|
||||||
}
|
|
||||||
static inline Ref<spdlog::logger>& getEditorEngineLogger() {
|
|
||||||
return EditorEngineLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Ref<spdlog::logger> coreLogger;
|
|
||||||
static Ref<spdlog::logger> clientLogger;
|
|
||||||
static Ref<spdlog::logger> scriptLogger;
|
|
||||||
static Ref<spdlog::logger> EditorEngineLogger;
|
|
||||||
};
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
|
|
||||||
#define DEER_CORE_TRACE(...) Deer::Log::getCoreLogger()->trace(__VA_ARGS__)
|
#define DEER_CORE_TRACE(...) Deer::Log::getCoreLogger()->trace(__VA_ARGS__)
|
||||||
35
Deer/Include/DeerCore/Network.h
Normal file
35
Deer/Include/DeerCore/Network.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
#include "DeerCore/Tools/TypeDefs.h"
|
||||||
|
|
||||||
|
typedef struct _ENetPeer ENetPeer;
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Network {
|
||||||
|
struct ServerSettings;
|
||||||
|
struct DeerClient;
|
||||||
|
|
||||||
|
void initServer(const ServerSettings&);
|
||||||
|
void shutdownServer();
|
||||||
|
|
||||||
|
void flushServerEvents();
|
||||||
|
|
||||||
|
enum class DeerClientState : int {
|
||||||
|
NotConnected = 0,
|
||||||
|
Connected = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeerClient {
|
||||||
|
DeerClientState clientState = DeerClientState::NotConnected;
|
||||||
|
ENetPeer* internalPeer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerSettings {
|
||||||
|
uint32_t port = 500;
|
||||||
|
uint32_t maxClients = 32;
|
||||||
|
uint32_t maxOutgoingBand = 0;
|
||||||
|
uint32_t maxIncomingBand = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Network
|
||||||
|
} // namespace Deer
|
||||||
118
Deer/Include/DeerCore/Scripting.h
Normal file
118
Deer/Include/DeerCore/Scripting.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
#include "DeerCore/Tools/Path.h"
|
||||||
|
#include "DeerCore/Tools/TypeDefs.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class asIScriptEngine;
|
||||||
|
class asIScriptObject;
|
||||||
|
class asIScriptFunction;
|
||||||
|
class asITypeInfo;
|
||||||
|
class asIScriptContext;
|
||||||
|
class asIScriptModule;
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
class ScriptEnvironment;
|
||||||
|
class ScriptSystem;
|
||||||
|
class ScriptEnvironmentContextData;
|
||||||
|
class World;
|
||||||
|
|
||||||
|
namespace Scripting {
|
||||||
|
// The event type is necessary to know wich parameters to put
|
||||||
|
enum class EventType {
|
||||||
|
void_event // Defines a event with void as return and no parameter
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SystemEvent {
|
||||||
|
EventType eventType;
|
||||||
|
std::string eventName;
|
||||||
|
SystemEvent(const std::string _name, EventType _type) : eventName(_name), eventType(_type) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SystemDescription {
|
||||||
|
std::string baseTypeName;
|
||||||
|
std::string moduleName;
|
||||||
|
std::vector<SystemEvent> events;
|
||||||
|
SystemDescription(const std::string& _baseTypeName = "", const std::string& _moduleName = "", const std::vector<SystemEvent>& _events = {}) : baseTypeName(_baseTypeName), moduleName(_moduleName), events(_events) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Functions called by Engine
|
||||||
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
void registerInterface(const char* name);
|
||||||
|
void registerInterfaceFunction(const char* name, const char* funcName, EventType funcType);
|
||||||
|
|
||||||
|
asIScriptEngine* getScriptEngine();
|
||||||
|
void compileFiles(const Path&, const char* moduleName);
|
||||||
|
|
||||||
|
Scope<ScriptEnvironment> createScriptEnvironment(const SystemDescription& systemDescription);
|
||||||
|
} // namespace Scripting
|
||||||
|
|
||||||
|
struct ScriptObjectGroup {
|
||||||
|
public:
|
||||||
|
// returns false if the object already existed
|
||||||
|
bool createScriptObject(size_t systemIndex);
|
||||||
|
|
||||||
|
void executeOnGroup_voidEvent(size_t eventIndex);
|
||||||
|
void executeOnObject_voidEvent(size_t systemIndex, size_t eventIndex);
|
||||||
|
void executeOnObject_voidEvent(ScriptSystem* system, size_t eventIndex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScriptObjectGroup(ScriptEnvironment* env);
|
||||||
|
|
||||||
|
Scope<asIScriptObject*[]> systemInstances;
|
||||||
|
ScriptEnvironment* environment;
|
||||||
|
friend ScriptSystem;
|
||||||
|
friend ScriptEnvironment;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptSystem {
|
||||||
|
public:
|
||||||
|
const char* getSystemName();
|
||||||
|
bool hasFunction(size_t index);
|
||||||
|
size_t getSystemIndex();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ScriptSystem(const Scripting::SystemDescription& desc, asITypeInfo* type, size_t _systemIndex);
|
||||||
|
|
||||||
|
asITypeInfo* systemType;
|
||||||
|
Scope<asIScriptFunction*[]> environmentFunctions;
|
||||||
|
size_t systemIndex;
|
||||||
|
|
||||||
|
friend ScriptEnvironment;
|
||||||
|
friend ScriptObjectGroup;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Script Environment is based of one angelscript interface, the clas analizes all the classes that derives from that
|
||||||
|
// interface and calls them systems, I extract the functions as defined from system description and then the user can tell me to create a
|
||||||
|
// system group, a system group can have each system created or not
|
||||||
|
class ScriptEnvironment {
|
||||||
|
public:
|
||||||
|
~ScriptEnvironment();
|
||||||
|
|
||||||
|
ScriptObjectGroup* createGroupWithAllSystems();
|
||||||
|
ScriptObjectGroup* createEmptyGroup();
|
||||||
|
|
||||||
|
size_t getSystemCount();
|
||||||
|
ScriptSystem* getSystemByIndex(size_t index);
|
||||||
|
|
||||||
|
void tieWorld(World* world);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Scripting::SystemDescription systemDescription;
|
||||||
|
asIScriptContext* context;
|
||||||
|
asIScriptModule* module;
|
||||||
|
asITypeInfo* baseType;
|
||||||
|
|
||||||
|
std::vector<Scope<ScriptSystem>> systems;
|
||||||
|
std::vector<Scope<ScriptObjectGroup>> systemGroups;
|
||||||
|
Scope<ScriptEnvironmentContextData> environmentContext;
|
||||||
|
|
||||||
|
ScriptEnvironment(const Scripting::SystemDescription&);
|
||||||
|
friend Scope<ScriptEnvironment> Scripting::createScriptEnvironment(const Scripting::SystemDescription& systemDescription);
|
||||||
|
friend ScriptObjectGroup;
|
||||||
|
};
|
||||||
|
} // namespace Deer
|
||||||
@ -3,30 +3,66 @@
|
|||||||
#include "angelscript.h"
|
#include "angelscript.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace StudioAPI {
|
namespace Scripting {
|
||||||
const char* getAngelScriptReturnCodeString(int code);
|
const char* getAngelScriptReturnCodeString(int code);
|
||||||
}
|
bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface);
|
||||||
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
|
|
||||||
|
#define REGISTER_GLOBAL_FUNC(scriptEngine, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterGlobalFunction( \
|
||||||
|
funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL))
|
||||||
|
|
||||||
|
#define REGISTER_OBJECT_METHOD(scriptEngine, clasdef, funcdef, clas, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asMETHOD(clas, func), asCALL_THISCALL))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_METHOD(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_GENERIC))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_CONSTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_DESTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_DESTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_DESTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_DESTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
#define AS_CHECK(f) \
|
#define AS_CHECK(f) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::EditorEngine::getAngelScriptReturnCodeString(__r)); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define AS_CHECK_ADDITIONAL_INFO(f, i) \
|
#define AS_CHECK_ADDITIONAL_INFO(f, i) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::EditorEngine::getAngelScriptReturnCodeString(__r), i); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r), i); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define AS_RET_CHECK(f) \
|
#define AS_RET_CHECK(f) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::EditorEngine::getAngelScriptReturnCodeString(__r)); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
32
Deer/Include/DeerCore/Serialization/WorldSettings.h
Normal file
32
Deer/Include/DeerCore/Serialization/WorldSettings.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "cereal/cereal.hpp"
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
#include "DeerRender/Mesh.h"
|
||||||
|
#include "DeerRender/Resource.h"
|
||||||
|
#include "DeerRender/Shader.h"
|
||||||
|
|
||||||
|
#include "DeerRender/Tools/Memory.h"
|
||||||
|
#include <functional>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
struct WorldSerializationSettings {
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
bool includeServer = false;
|
||||||
|
bool includeClient = true;
|
||||||
|
|
||||||
|
std::function<Resource<GPUMesh>(ResourceId)> meshLoadingFunction = nullptr;
|
||||||
|
std::function<Resource<Shader>(ResourceId)> shaderLoadingFunction = nullptr;
|
||||||
|
#else
|
||||||
|
bool includeServer = true;
|
||||||
|
bool includeClient = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& archive) {
|
||||||
|
archive(CEREAL_NVP(includeServer));
|
||||||
|
archive(CEREAL_NVP(includeClient));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace Deer
|
||||||
18
Deer/Include/DeerCore/Universe.h
Normal file
18
Deer/Include/DeerCore/Universe.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Serialization/WorldSettings.h"
|
||||||
|
#include "DeerCore/Tools/Path.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
class World;
|
||||||
|
class WorldSettings;
|
||||||
|
|
||||||
|
namespace Universe {
|
||||||
|
World* createWorld(const WorldSettings&);
|
||||||
|
|
||||||
|
World* loadWorldFromJson(const WorldSettings&, WorldSerializationSettings&, const Path&);
|
||||||
|
void saveWorldInJson(World*, WorldSerializationSettings& serializationSettings, const Path& path);
|
||||||
|
|
||||||
|
void destroyAllWorlds();
|
||||||
|
void flushDestroyedWorlds();
|
||||||
|
} // namespace Universe
|
||||||
|
} // namespace Deer
|
||||||
42
Deer/Include/DeerCore/Voxel.h
Normal file
42
Deer/Include/DeerCore/Voxel.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
#include "DeerCore/Tools/TypeDefs.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define CLUSTER_SIZE 16
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
#include "DeerRender/Resource.h"
|
||||||
|
namespace Deer {
|
||||||
|
class VoxelBuilder;
|
||||||
|
class GPUMesh;
|
||||||
|
} // namespace Deer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
class VoxelWorldData;
|
||||||
|
|
||||||
|
struct VoxelType {
|
||||||
|
std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VoxelEnvironment {
|
||||||
|
public:
|
||||||
|
VoxelEnvironment();
|
||||||
|
~VoxelEnvironment();
|
||||||
|
|
||||||
|
void modifyVoxel(uint32_t voxelId, int x, int y, int z);
|
||||||
|
uint32_t getVoxel(int x, int y, int z);
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
public:
|
||||||
|
Resource<GPUMesh> buildCluster(int x, int y, int z);
|
||||||
|
Scope<VoxelBuilder> voxelBuilder;
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
Scope<VoxelWorldData> voxelWorldData;
|
||||||
|
};
|
||||||
|
} // namespace Deer
|
||||||
62
Deer/Include/DeerCore/World.h
Executable file
62
Deer/Include/DeerCore/World.h
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
#include "DeerCore/Tools/TypeDefs.h"
|
||||||
|
#include "DeerCore/Universe.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
class EntityEnvironment;
|
||||||
|
class GizmoRenderer;
|
||||||
|
class World;
|
||||||
|
|
||||||
|
struct WorldCamera;
|
||||||
|
using WorldCallback = std::function<void(World&)>;
|
||||||
|
|
||||||
|
struct WorldSettings {
|
||||||
|
WorldCallback updateCallback;
|
||||||
|
u_int32_t updateFrequency;
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
WorldCallback renderCallback;
|
||||||
|
u_int32_t renderFrequency;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class WorldState {
|
||||||
|
Created,
|
||||||
|
Executing,
|
||||||
|
StopRequested,
|
||||||
|
Stopped,
|
||||||
|
DestroyQueued,
|
||||||
|
ReadyToDestroy
|
||||||
|
};
|
||||||
|
|
||||||
|
class World {
|
||||||
|
public:
|
||||||
|
~World();
|
||||||
|
|
||||||
|
void execute();
|
||||||
|
void stopExecution();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
WorldState getExecutionState();
|
||||||
|
Scope<EntityEnvironment> entityEnvironment;
|
||||||
|
const WorldSettings& getWorldSettings() { return worldSettings; }
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
inline float getRenderDeltaTime() { return renderDeltaTime; }
|
||||||
|
void setRenderFrequency(int);
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
World(const WorldSettings&);
|
||||||
|
|
||||||
|
std::atomic<WorldState> executingState;
|
||||||
|
WorldSettings worldSettings;
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
float renderDeltaTime;
|
||||||
|
#endif
|
||||||
|
friend World* Universe::createWorld(const WorldSettings& worldSettings);
|
||||||
|
}; // namespace World
|
||||||
|
} // namespace Deer
|
||||||
@ -1,21 +0,0 @@
|
|||||||
#include "Deer/Application.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/Events/ApplicationEvent.h"
|
|
||||||
#include "DeerRender/Events/Event.h"
|
|
||||||
#include "DeerRender/Window.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace Application {
|
|
||||||
using EventFunction = void(*)(Event&);
|
|
||||||
|
|
||||||
void initWindow();
|
|
||||||
void shutdownWindow();
|
|
||||||
|
|
||||||
void setRenderCallback(Function);
|
|
||||||
void setEventCallback(EventFunction);
|
|
||||||
|
|
||||||
Window& getWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Components.h"
|
#include "DeerCore/Components.h"
|
||||||
|
|
||||||
#include "DeerRender/Mesh.h"
|
#include "DeerRender/Mesh.h"
|
||||||
#include "DeerRender/Shader.h"
|
#include "DeerRender/Shader.h"
|
||||||
@ -18,21 +18,15 @@ namespace Deer {
|
|||||||
MeshComponent(const MeshComponent&) = default;
|
MeshComponent(const MeshComponent&) = default;
|
||||||
|
|
||||||
Resource<GPUMesh> mesh;
|
Resource<GPUMesh> mesh;
|
||||||
|
Resource<Shader> shader;
|
||||||
|
Resource<Texture> texture;
|
||||||
|
|
||||||
bool active = true;
|
bool active = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShaderComponent {
|
|
||||||
ShaderComponent() = default;
|
|
||||||
ShaderComponent(Resource<Shader> _shader) : shader(_shader) {}
|
|
||||||
ShaderComponent(const ShaderComponent&) = default;
|
|
||||||
|
|
||||||
Resource<Shader> shader;
|
|
||||||
Resource<Texture> texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CameraComponent {
|
struct CameraComponent {
|
||||||
CameraComponent() = default;
|
CameraComponent() {}
|
||||||
CameraComponent(const CameraComponent&) = default;
|
CameraComponent(const CameraComponent&) {}
|
||||||
|
|
||||||
float fov = glm::radians(50.0f);
|
float fov = glm::radians(50.0f);
|
||||||
float aspect = 16 / 9;
|
float aspect = 16 / 9;
|
||||||
@ -41,11 +35,4 @@ namespace Deer {
|
|||||||
|
|
||||||
inline glm::mat4 getMatrix() const { return glm::perspective(fov, aspect, nearZ, farZ); }
|
inline glm::mat4 getMatrix() const { return glm::perspective(fov, aspect, nearZ, farZ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureComponent {
|
|
||||||
TextureComponent() = default;
|
|
||||||
TextureComponent(const TextureComponent&) = default;
|
|
||||||
|
|
||||||
Resource<Texture> texture;
|
|
||||||
};
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/DataManager.h"
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/DataManagment.h"
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/DataStore.h"
|
|
||||||
20
Deer/Include/DeerRender/Engine.h
Normal file
20
Deer/Include/DeerRender/Engine.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Engine.h"
|
||||||
|
#include "DeerRender/Events/Event.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
using EventFunction = void (*)(Event&);
|
||||||
|
class World;
|
||||||
|
class Window;
|
||||||
|
|
||||||
|
namespace Engine {
|
||||||
|
void setRenderCallback(Function);
|
||||||
|
void setEventCallback(EventFunction);
|
||||||
|
|
||||||
|
void beginRender();
|
||||||
|
void endRender();
|
||||||
|
|
||||||
|
World& getMainWorld();
|
||||||
|
Window& getWindow();
|
||||||
|
} // namespace Engine
|
||||||
|
} // namespace Deer
|
||||||
2
Deer/Include/DeerRender/EntityEnviroment.h
Normal file
2
Deer/Include/DeerRender/EntityEnviroment.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/EntityEnviroment.h"
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Enviroment.h"
|
|
||||||
@ -1,22 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "DeerRender/Render/FrameBuffer.h"
|
#include "DeerRender/Render/FrameBuffer.h"
|
||||||
|
#include "DeerRender/Resource.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
// TODO: Add safety
|
struct FrameBufferData {
|
||||||
namespace FrameBufferManager {
|
enum class FrameBufferType : int {
|
||||||
uint16_t createRGBA8FrameBuffer(std::string& name, int, int);
|
RGBA8 = 1,
|
||||||
void resizeFrameBuffer(uint16_t frameBufferId, int, int);
|
GBuffer = 2,
|
||||||
|
};
|
||||||
|
|
||||||
int getFrameBufferWidth(uint16_t frameBufferId);
|
FrameBufferType frameBufferType;
|
||||||
int getFrameBufferHeight(uint16_t frameBufferId);
|
int sizeX, sizeY;
|
||||||
|
int samples;
|
||||||
|
|
||||||
const std::string& getFrameBufferName(uint16_t);
|
FrameBufferData(int _sizeX = 100, int _sizeY = 100, int _samples = 4, FrameBufferType type = FrameBufferType::RGBA8)
|
||||||
uint16_t getFrameBufferId(std::string& name);
|
: sizeX(_sizeX), sizeY(_sizeY), samples(_samples), frameBufferType(type) { }
|
||||||
FrameBuffer& getFrameBuffer(uint16_t);
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class ResourceBuilder<FrameBuffer> {
|
||||||
|
public:
|
||||||
|
using BaseDataType = FrameBufferData;
|
||||||
|
static Scope<FrameBuffer> buildResource(const BaseDataType& baseData);
|
||||||
|
};
|
||||||
|
|
||||||
void unloadAllFrameBuffer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,33 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "glm/glm.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
#define GIZMO_DEPTH 8
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
struct SceneCamera;
|
|
||||||
struct GizmoFace {
|
|
||||||
glm::vec3 positions[4];
|
|
||||||
uint16_t textureID;
|
|
||||||
uint8_t face;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GizmoRenderer {
|
|
||||||
public:
|
|
||||||
void drawLine(glm::vec3 a, glm::vec3 b, glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f));
|
|
||||||
void drawVoxelLine(int x, int y, int z, glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f));
|
|
||||||
void drawVoxelLineFace(int x, int y, int z, uint8_t face, glm::vec3 color = glm::vec3(1.0f, 1.0f, 1.0f));
|
|
||||||
|
|
||||||
void drawVoxelFace(int x, int y, int z, uint16_t voxelID, uint8_t face, uint8_t priority = 0);
|
|
||||||
void drawVoxelFaceInverted(int x, int y, int z, uint16_t voxelID, uint8_t face, uint8_t priority = 0);
|
|
||||||
|
|
||||||
void render(const SceneCamera& camera);
|
|
||||||
void refresh();
|
|
||||||
private:
|
|
||||||
std::vector<std::array<glm::vec3, 3>> m_lines;
|
|
||||||
std::array<std::vector<GizmoFace>, GIZMO_DEPTH> m_faces;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -3,19 +3,25 @@
|
|||||||
#include "DeerRender/Events/KeyEvent.h"
|
#include "DeerRender/Events/KeyEvent.h"
|
||||||
#include "DeerRender/Events/MouseEvent.h"
|
#include "DeerRender/Events/MouseEvent.h"
|
||||||
|
|
||||||
namespace Deer {
|
struct ImFont;
|
||||||
class ImGuiLayer {
|
|
||||||
public:
|
|
||||||
~ImGuiLayer() = default;
|
|
||||||
|
|
||||||
void onAttach();
|
namespace Deer {
|
||||||
void onDetach();
|
class Window;
|
||||||
|
|
||||||
|
namespace ImGuiLayer {
|
||||||
|
void init(Window& window);
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
void onEvent(Event& event);
|
void onEvent(Event& event);
|
||||||
private:
|
|
||||||
|
void setTextFont(ImFont*);
|
||||||
|
void setTitleFont(ImFont*);
|
||||||
|
ImFont* getTextFont();
|
||||||
|
ImFont* getTitleFont();
|
||||||
|
|
||||||
bool onMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
bool onMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
||||||
bool onMouseButtonReleasedEvent(MouseButtonReleasedEvent& e);
|
bool onMouseButtonReleasedEvent(MouseButtonReleasedEvent& e);
|
||||||
bool onMouseMovedEvent(MouseMovedEvent& e);
|
bool onMouseMovedEvent(MouseMovedEvent& e);
|
||||||
@ -24,6 +30,5 @@ namespace Deer {
|
|||||||
bool onKeyReleasedEvent(KeyReleasedEvent& e);
|
bool onKeyReleasedEvent(KeyReleasedEvent& e);
|
||||||
bool onKeyTypedEvent(KeyTypedEvent& e);
|
bool onKeyTypedEvent(KeyTypedEvent& e);
|
||||||
bool onWindowResizeEvent(WindowResizeEvent& e);
|
bool onWindowResizeEvent(WindowResizeEvent& e);
|
||||||
};
|
}; // namespace ImGuiLayer
|
||||||
}
|
} // namespace Deer
|
||||||
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Application.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
class Input {
|
class Input {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Log.h"
|
#include "DeerCore/Log.h"
|
||||||
@ -24,8 +24,6 @@ namespace Deer {
|
|||||||
VertexUV(float _u, float _v) : u(_u), v(_v) {}
|
VertexUV(float _u, float _v) : u(_u), v(_v) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vertex normal is represented with a number fromn [-64,64], and then its
|
|
||||||
// divided by 64 to know the decimal number
|
|
||||||
struct VertexNormal {
|
struct VertexNormal {
|
||||||
int8_t x = 0;
|
int8_t x = 0;
|
||||||
int8_t y = 0;
|
int8_t y = 0;
|
||||||
@ -35,6 +33,15 @@ namespace Deer {
|
|||||||
VertexNormal(int8_t _x, int8_t _y, int8_t _z) : x(_x), y(_y), z(_z) {}
|
VertexNormal(int8_t _x, int8_t _y, int8_t _z) : x(_x), y(_y), z(_z) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexColor {
|
||||||
|
uint8_t r = 0;
|
||||||
|
uint8_t g = 0;
|
||||||
|
uint8_t b = 0;
|
||||||
|
|
||||||
|
VertexColor() = default;
|
||||||
|
VertexColor(uint8_t _r, uint8_t _g, uint8_t _b) : r(_r), g(_g), b(_b) {}
|
||||||
|
};
|
||||||
|
|
||||||
struct MeshData {
|
struct MeshData {
|
||||||
public:
|
public:
|
||||||
void createVertices(uint32_t count) {
|
void createVertices(uint32_t count) {
|
||||||
@ -42,15 +49,20 @@ namespace Deer {
|
|||||||
vertexNormalData = MakeScope<VertexNormal[]>(count);
|
vertexNormalData = MakeScope<VertexNormal[]>(count);
|
||||||
vertexCount = count;
|
vertexCount = count;
|
||||||
}
|
}
|
||||||
void createUVData() { vertexUVData = MakeScope<VertexUV[]>(vertexCount); }
|
|
||||||
void createIndices(uint32_t count) {
|
void createIndices(uint32_t count) {
|
||||||
indexData = MakeScope<uint32_t[]>(count);
|
indexData = MakeScope<uint32_t[]>(count);
|
||||||
indexCount = count;
|
indexCount = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createUVData() { vertexUVData = MakeScope<VertexUV[]>(vertexCount); }
|
||||||
|
void createColorData() { vertexColorData = MakeScope<VertexColor[]>(vertexCount); }
|
||||||
|
void createAuxData() { vertexAuxData = MakeScope<uint8_t[]>(vertexCount); }
|
||||||
|
|
||||||
inline VertexPosition* getVertexPosition() const { return vertexPositionsData.get(); }
|
inline VertexPosition* getVertexPosition() const { return vertexPositionsData.get(); }
|
||||||
inline VertexNormal* getVertexNormal() const { return vertexNormalData.get(); }
|
inline VertexNormal* getVertexNormal() const { return vertexNormalData.get(); }
|
||||||
inline VertexUV* getVertexUV() const { return vertexUVData.get(); }
|
inline VertexUV* getVertexUV() const { return vertexUVData.get(); }
|
||||||
|
inline VertexColor* getVertexColor() const { return vertexColorData.get(); }
|
||||||
|
inline uint8_t* getVertexAuxData() const { return vertexAuxData.get(); }
|
||||||
inline uint32_t* getIndexData() const { return indexData.get(); }
|
inline uint32_t* getIndexData() const { return indexData.get(); }
|
||||||
|
|
||||||
inline uint32_t getVertexCount() const { return vertexCount; }
|
inline uint32_t getVertexCount() const { return vertexCount; }
|
||||||
@ -61,6 +73,8 @@ namespace Deer {
|
|||||||
Scope<VertexPosition[]> vertexPositionsData;
|
Scope<VertexPosition[]> vertexPositionsData;
|
||||||
Scope<VertexNormal[]> vertexNormalData;
|
Scope<VertexNormal[]> vertexNormalData;
|
||||||
Scope<VertexUV[]> vertexUVData;
|
Scope<VertexUV[]> vertexUVData;
|
||||||
|
Scope<VertexColor[]> vertexColorData;
|
||||||
|
Scope<uint8_t[]> vertexAuxData;
|
||||||
|
|
||||||
uint32_t indexCount = 0;
|
uint32_t indexCount = 0;
|
||||||
Scope<uint32_t[]> indexData;
|
Scope<uint32_t[]> indexData;
|
||||||
@ -77,21 +91,8 @@ namespace Deer {
|
|||||||
static Scope<GPUMesh> buildResource(const BaseDataType& baseData);
|
static Scope<GPUMesh> buildResource(const BaseDataType& baseData);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MeshManager {
|
namespace Builtin {
|
||||||
uint16_t loadModel(const Path&);
|
Resource<GPUMesh> cube();
|
||||||
uint16_t loadModel(const MeshData&, const Path&);
|
Resource<GPUMesh> sphere();
|
||||||
VertexArray& getModel(uint16_t model_id);
|
} // namespace Builtin
|
||||||
const Path& getModelName(uint16_t model_id);
|
|
||||||
|
|
||||||
void unloadAllModels();
|
|
||||||
} // namespace MeshManager
|
|
||||||
|
|
||||||
namespace DataStore {
|
|
||||||
void saveModel(const MeshData&, const Path& name);
|
|
||||||
void loadModel(MeshData&, const Path& name);
|
|
||||||
|
|
||||||
void saveBinModel(const MeshData&, const Path& name);
|
|
||||||
|
|
||||||
void createExampleMeshData();
|
|
||||||
} // namespace DataStore
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "DeerCore/Log.h"
|
||||||
|
#include "DeerRender/Resource.h"
|
||||||
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
enum class TextureBufferType {
|
enum class TextureBufferType {
|
||||||
RGBA8,
|
RGBA8,
|
||||||
RED_INTEGER
|
RED_INTEGER,
|
||||||
|
GBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrameBufferSpecification {
|
struct FrameBufferSpecification {
|
||||||
@ -40,5 +41,4 @@ namespace Deer {
|
|||||||
|
|
||||||
static FrameBuffer* create(const FrameBufferSpecification& spec);
|
static FrameBuffer* create(const FrameBufferSpecification& spec);
|
||||||
};
|
};
|
||||||
}
|
} // namespace Deer
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "DeerRender/Render/FrameBuffer.h"
|
|
||||||
#include "DeerRender/Tools/Memory.h"
|
|
||||||
#include "DeerRender/Enviroment.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class RenderPiperline {
|
|
||||||
public:
|
|
||||||
RenderPiperline(RenderPiperline&) = delete;
|
|
||||||
RenderPiperline(PiperlineOptions);
|
|
||||||
|
|
||||||
void render(const Environment&);
|
|
||||||
private:
|
|
||||||
Scope<FrameBuffer> resultImage;
|
|
||||||
PiperlineOptions options;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PiperlineOptions {
|
|
||||||
int width = 100;
|
|
||||||
int height = 100;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "DeerRender/DataManagment.h"
|
|
||||||
#include "DeerRender/Log.h"
|
#include "DeerRender/Log.h"
|
||||||
#include "DeerRender/Tools/Memory.h"
|
#include "DeerRender/Tools/Memory.h"
|
||||||
#include "DeerRender/Tools/Path.h"
|
#include "DeerRender/Tools/Path.h"
|
||||||
@ -12,27 +11,36 @@
|
|||||||
namespace Deer {
|
namespace Deer {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ResourceManager;
|
class ResourceManager;
|
||||||
|
typedef uint32_t ResourceId;
|
||||||
|
|
||||||
|
ResourceId generatePhyisicalResourceId();
|
||||||
|
ResourceId generateRuntimeResourceId();
|
||||||
|
|
||||||
|
template <typename DataSource>
|
||||||
|
class StorageBackend {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
static Scope<T> load(ResourceId storageId);
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Resource {
|
class Resource {
|
||||||
public:
|
public:
|
||||||
int32_t getResourceId() const { return resourceId; }
|
int32_t getResourceIndex() const { return resourceId; }
|
||||||
|
ResourceId getResourceId() const { return ResourceManager<T>::getResourceId(*this); }
|
||||||
|
|
||||||
bool isValid() const { return ResourceManager<T>::isValid(*this); }
|
bool isValid() const { return ResourceManager<T>::isValid(*this); }
|
||||||
T& getData() { return ResourceManager<T>::getResourceData(*this); }
|
T& getData() { return ResourceManager<T>::getResourceData(*this); }
|
||||||
|
|
||||||
const std::string& getStorageId() const { return ResourceManager<T>::getStorageId(); }
|
|
||||||
|
|
||||||
inline explicit operator bool() const { return resourceId >= 0; }
|
|
||||||
|
|
||||||
static Resource<T> unsafeFromId(int32_t id) {
|
static Resource<T> unsafeFromId(int32_t id) {
|
||||||
Resource<T> res;
|
Resource<T> res;
|
||||||
res.resourceId = id;
|
res.resourceId = id;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline explicit operator bool() const { return resourceId >= 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// -1 = no resource loaded
|
|
||||||
int32_t resourceId = -1;
|
int32_t resourceId = -1;
|
||||||
friend ResourceManager<T>;
|
friend ResourceManager<T>;
|
||||||
};
|
};
|
||||||
@ -52,45 +60,60 @@ namespace Deer {
|
|||||||
private:
|
private:
|
||||||
struct ResourceData {
|
struct ResourceData {
|
||||||
public:
|
public:
|
||||||
ResourceData(const std::string& _resourceId, Scope<T>&& _data)
|
Scope<T> data = nullptr;
|
||||||
: storageId(_resourceId), data(std::move(_data)) {}
|
ResourceId storageId = 0;
|
||||||
|
|
||||||
Scope<T> data;
|
|
||||||
const std::string storageId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<ResourceData> resources;
|
static std::vector<ResourceData> resources;
|
||||||
static std::unordered_map<std::string, Resource<T>> resourceCache;
|
static std::unordered_map<ResourceId, Resource<T>> resourceCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename DataSource>
|
template <typename DataSource>
|
||||||
static Resource<T> loadResource(const std::string& storageId) {
|
static Resource<T> loadResource(ResourceId storageId) {
|
||||||
if (resourceCache.contains(storageId))
|
if (resourceCache.contains(storageId))
|
||||||
return resourceCache[storageId];
|
return resourceCache[storageId];
|
||||||
|
|
||||||
using ResourceBuilderBaseDataType = typename ResourceBuilder<T>::BaseDataType;
|
using ResourceBaseType = typename ResourceBuilder<T>::BaseDataType;
|
||||||
Scope<T> data;
|
Scope<T> data;
|
||||||
|
|
||||||
if constexpr (!std::is_void_v<ResourceBuilderBaseDataType>) {
|
Scope<ResourceBaseType> baseData = StorageBackend<DataSource>::template load<ResourceBaseType>(storageId);
|
||||||
Scope<ResourceBuilderBaseDataType> baseData = DataManager<DataSource>::template load<ResourceBuilderBaseDataType>(storageId);
|
|
||||||
if (!baseData) {
|
|
||||||
const char* baseDataType = abi::__cxa_demangle(typeid(ResourceBuilderBaseDataType).name(), 0, 0, nullptr);
|
|
||||||
const char* dataType = abi::__cxa_demangle(typeid(T).name(), 0, 0, nullptr);
|
|
||||||
DEER_CORE_ERROR("Error loading base resource {} for resource {} with id {}", baseDataType, dataType, storageId.c_str());
|
|
||||||
return Resource<T>();
|
|
||||||
}
|
|
||||||
data = ResourceBuilder<T>::buildResource(*baseData.get());
|
data = ResourceBuilder<T>::buildResource(*baseData.get());
|
||||||
} else {
|
|
||||||
data = ResourceBuilder<T>::buildResource(); // No base data
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||||
resources.push_back({storageId, std::move(data)});
|
resources.push_back({});
|
||||||
|
|
||||||
|
ResourceData& rd = resources.back();
|
||||||
|
rd.data = std::move(data);
|
||||||
|
rd.storageId = storageId;
|
||||||
|
|
||||||
resourceCache[storageId] = resource;
|
resourceCache[storageId] = resource;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Resource<T> getResource(ResourceId storageId) {
|
||||||
|
if (resourceCache.contains(storageId))
|
||||||
|
return resourceCache[storageId];
|
||||||
|
|
||||||
|
return Resource<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, ResourceId storageId) {
|
||||||
|
if (resourceCache.contains(storageId))
|
||||||
|
return resourceCache[storageId];
|
||||||
|
|
||||||
|
Scope<T> data = ResourceBuilder<T>::buildResource(resourceData);
|
||||||
|
|
||||||
|
Resource<T> resource = Resource<T>::unsafeFromId(resources.size());
|
||||||
|
resources.push_back({});
|
||||||
|
|
||||||
|
ResourceData& rd = resources.back();
|
||||||
|
rd.data = std::move(data);
|
||||||
|
rd.storageId = storageId;
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
static void unloadResources() {
|
static void unloadResources() {
|
||||||
resourceCache.clear();
|
resourceCache.clear();
|
||||||
resources.clear();
|
resources.clear();
|
||||||
@ -100,10 +123,9 @@ namespace Deer {
|
|||||||
return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size());
|
return res.resourceId >= 0 && res.resourceId < static_cast<int32_t>(resources.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const std::string& getStorageId(Resource<T> res) {
|
static inline ResourceId getResourceId(Resource<T> res) {
|
||||||
const static std::string invalid("NULL");
|
|
||||||
if (!isValid(res))
|
if (!isValid(res))
|
||||||
return invalid;
|
return 0;
|
||||||
|
|
||||||
return resources[res.resourceId].storageId;
|
return resources[res.resourceId].storageId;
|
||||||
}
|
}
|
||||||
@ -116,5 +138,11 @@ namespace Deer {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources;
|
std::vector<typename ResourceManager<T>::ResourceData> ResourceManager<T>::resources;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::unordered_map<std::string, Resource<T>> ResourceManager<T>::resourceCache;
|
std::unordered_map<ResourceId, Resource<T>> ResourceManager<T>::resourceCache;
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
|
|
||||||
|
// BUILTIN RESOURCE IDS
|
||||||
|
|
||||||
|
#define RESOURCE_CUBE_ID 0x1
|
||||||
|
#define RESOURCE_SPHERE_ID 0x2
|
||||||
|
#define RESOURCE_BASIC_SHADER_ID 0x3
|
||||||
7
Deer/Include/DeerRender/Scripting.h
Normal file
7
Deer/Include/DeerRender/Scripting.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Scripting.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Scripting {
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
#include "DeerRender/Render/Shader.h"
|
#include "DeerRender/Render/Shader.h"
|
||||||
#include "DeerRender/Resource.h"
|
#include "DeerRender/Resource.h"
|
||||||
|
|
||||||
@ -22,6 +22,11 @@ namespace Deer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace RenderUtils {
|
||||||
|
void initializeRenderUtils();
|
||||||
|
void deinitializeRenderUtils();
|
||||||
|
} // namespace RenderUtils
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class ResourceBuilder<Shader> {
|
class ResourceBuilder<Shader> {
|
||||||
public:
|
public:
|
||||||
@ -32,4 +37,9 @@ namespace Deer {
|
|||||||
namespace DataStore {
|
namespace DataStore {
|
||||||
void loadShader(ShaderData& data, const Path& name);
|
void loadShader(ShaderData& data, const Path& name);
|
||||||
} // namespace DataStore
|
} // namespace DataStore
|
||||||
|
|
||||||
|
namespace Builtin {
|
||||||
|
Resource<Shader> simpleShader();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Memory.h"
|
#include "DeerCore/Tools/Memory.h"
|
||||||
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/SmallVector.h"
|
#include "DeerCore/Tools/SmallVector.h"
|
||||||
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/TypeDefs.h"
|
#include "DeerCore/Tools/TypeDefs.h"
|
||||||
2
Deer/Include/DeerRender/Universe.h
Normal file
2
Deer/Include/DeerRender/Universe.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "DeerCore/Universe.h"
|
||||||
94
Deer/Include/DeerRender/Voxel.h
Executable file → Normal file
94
Deer/Include/DeerRender/Voxel.h
Executable file → Normal file
@ -1,33 +1,81 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Voxel.h"
|
#include "DeerCore/Voxel.h"
|
||||||
|
|
||||||
#define LIGHT_PROPAGATION_COMPLEX_DIRS 18
|
#include "DeerRender/Mesh.h"
|
||||||
#define LIGHT_PROPAGATION_COMPLEX_DIR(id, dir) lightPropagationComplexDir[id + dir * 2]
|
#include "glm/glm.hpp"
|
||||||
#define LIGHT_PROPAGATION_SIMPLE_FALL 16
|
|
||||||
#define LIGHT_PROPAGATION_COMPLEX_FALL 23
|
|
||||||
|
|
||||||
#define NORMAL_VERTEX_POS(axis, id, normal) normalFacePositions[axis + id * 3 + normal * 3 * 4]
|
#include <array>
|
||||||
#define VERTEX_UV(axis, id) uvFace[axis + id * 2]
|
#include <vector>
|
||||||
#define AMBIENT_OCCLUSION_VERTEX(axis, id, vertex, normal) ambientOcclusionVertex[axis + id * 3 + vertex * 3 * 2 + normal * 3 * 2 * 4]
|
|
||||||
#define LAYER_CHECK_DIRS(axis, id) layerCheckDirections[axis + id * 2]
|
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
struct VoxelLight;
|
struct VoxelVertex {
|
||||||
extern VoxelLight lightVoxel;
|
VoxelVertex() = default;
|
||||||
|
VoxelVertex(glm::vec3 _position) : position(_position) {}
|
||||||
|
|
||||||
extern int lightPropagationComplexDir[12 * 2];
|
glm::vec3 position;
|
||||||
extern int normalFacePositions[3 * 4 * 6];
|
};
|
||||||
extern int uvFace[2 * 4];
|
|
||||||
// 6 Dirs * 4 vertices * 2 checks * 3 dirs
|
|
||||||
extern int ambientOcclusionVertex[6 * 4 * 2 * 3];
|
|
||||||
extern int layerCheckDirections[2 * 8];
|
|
||||||
|
|
||||||
struct VoxelLight {
|
struct VoxelFaceData {
|
||||||
uint8_t r_light;
|
// Basic construction
|
||||||
uint8_t g_light;
|
std::vector<VoxelVertex> vertices;
|
||||||
uint8_t b_light;
|
std::vector<uint32_t> triangles;
|
||||||
uint8_t ambient_light;
|
|
||||||
|
|
||||||
VoxelLight(uint8_t _ambient_light = 0) : r_light(0), g_light(0), b_light(0), ambient_light(_ambient_light) {}
|
std::array<std::vector<uint32_t>, 4> connections;
|
||||||
|
std::array<uint32_t, 4> edges;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VoxelBuilder {
|
||||||
|
public:
|
||||||
|
Resource<GPUMesh> buildCluster(int x, int y, int z);
|
||||||
|
|
||||||
|
VoxelBuilder(VoxelEnvironment* env) : environment(env) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct VoxelData {
|
||||||
|
int16_t vertexIndexFace[6] = {-1, -1, -1, -1, -1, -1};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexData {
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec3 tangent;
|
||||||
|
glm::vec2 uv;
|
||||||
|
float AO;
|
||||||
|
float extrussion;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addFace(VoxelFaceData& data, glm::vec3 origin, glm::vec3 up, glm::vec3 right);
|
||||||
|
void calculateNormals();
|
||||||
|
|
||||||
|
void buildVertices();
|
||||||
|
void buildFaceVertices(int x, int y, int z, int face);
|
||||||
|
|
||||||
|
void buildConnections();
|
||||||
|
void buildAxisConnections(int x, int y, int z);
|
||||||
|
void connectVertices(VoxelFaceData& face1, int edgeIndex1, int face1VertexOffset, VoxelFaceData& face2, int edgeIndex2, int face2VertexOffset);
|
||||||
|
|
||||||
|
void buildMarchingCubesCorners();
|
||||||
|
void buildMarchingVoxel(int x, int y, int z, uint8_t marchingCubeId);
|
||||||
|
int getVertexIdCorner(int x, int y, int z, int edge);
|
||||||
|
|
||||||
|
float getAmbientOclusion(int x, int y, int z);
|
||||||
|
|
||||||
|
VoxelData& getVoxelData(int x, int y, int z);
|
||||||
|
void clearVoxelData();
|
||||||
|
|
||||||
|
bool hasBlock(int x, int y, int z);
|
||||||
|
|
||||||
|
std::vector<VertexData> vertices;
|
||||||
|
std::vector<u_int32_t> indices;
|
||||||
|
|
||||||
|
int voxelXOffset;
|
||||||
|
int voxelYOffset;
|
||||||
|
int voxelZOffset;
|
||||||
|
|
||||||
|
VoxelEnvironment* environment;
|
||||||
|
VoxelData voxelData[CLUSTER_SIZE + 2][CLUSTER_SIZE + 2][CLUSTER_SIZE + 2];
|
||||||
|
|
||||||
|
friend VoxelEnvironment;
|
||||||
};
|
};
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file VoxelAspect.h
|
|
||||||
* @author chewico@frostdeer.com
|
|
||||||
* @brief File to save the voxel aspect data
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2025
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
#define VOXEL_TEXTURE_SIZE_X 128
|
|
||||||
#define VOXEL_TEXTURE_SIZE_Y 128
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
struct VoxelTextureFaceDefinition {
|
|
||||||
std::string textureFaces[6];
|
|
||||||
|
|
||||||
inline std::string& operator[](size_t index) {
|
|
||||||
return textureFaces[index];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VoxelColorEmission {
|
|
||||||
uint8_t r_value = 0;
|
|
||||||
uint8_t g_value = 0;
|
|
||||||
uint8_t b_value = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VoxelAspectDefinition {
|
|
||||||
std::string voxelName;
|
|
||||||
VoxelTextureFaceDefinition textureFaces;
|
|
||||||
VoxelColorEmission colorEmission;
|
|
||||||
|
|
||||||
VoxelAspectDefinition() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VoxelAspect {
|
|
||||||
VoxelAspectDefinition definition;
|
|
||||||
uint16_t textureFacesIDs[6]{};
|
|
||||||
|
|
||||||
inline bool isLightSource() {
|
|
||||||
return definition.colorEmission.r_value || definition.colorEmission.g_value || definition.colorEmission.b_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the texture id for the voxel face
|
|
||||||
*
|
|
||||||
* @param face face of the texture defined in the enum NormalDirection of Voxel.h
|
|
||||||
* @return uint16_t texture id in the texture atlas
|
|
||||||
*/
|
|
||||||
inline uint16_t getTextureID(uint8_t face) { return textureFacesIDs[face]; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
#include "DeerRender/Events/Event.h"
|
#include "DeerRender/Events/Event.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -12,7 +12,7 @@ namespace Deer {
|
|||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
|
||||||
WindowProps(const std::string& _title = "Deer Engine",
|
WindowProps(const std::string& _title = "Deer Engine",
|
||||||
unsigned int _width = 1280,
|
unsigned int _width = 900,
|
||||||
unsigned int _height = 720)
|
unsigned int _height = 720)
|
||||||
: title(_title), width(_width), height(_height) {
|
: title(_title), width(_width), height(_height) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/Scene.h"
|
#include "DeerCore/World.h"
|
||||||
#include "DeerRender/Components.h"
|
#include "DeerRender/Components.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
struct SceneCamera {
|
struct WorldCamera {
|
||||||
TransformComponent transform;
|
TransformComponent transform;
|
||||||
CameraComponent camera;
|
CameraComponent camera;
|
||||||
|
|
||||||
SceneCamera() {}
|
WorldCamera() {}
|
||||||
SceneCamera(TransformComponent _transform, CameraComponent _camera) : transform(_transform), camera(_camera) {}
|
WorldCamera(TransformComponent _transform, CameraComponent _camera) : transform(_transform), camera(_camera) {}
|
||||||
};
|
};
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -1,61 +0,0 @@
|
|||||||
#include "Deer/Application.h"
|
|
||||||
#include <functional>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace Application {
|
|
||||||
// Implemented in DeerRender/Application
|
|
||||||
void runRender(float deltaTime);
|
|
||||||
void resolveEvents();
|
|
||||||
|
|
||||||
Function tickCallback;
|
|
||||||
bool running;
|
|
||||||
|
|
||||||
const double targetUpdateTime = 1.0 / 60.0; // Fixed 60 FPS update
|
|
||||||
double targetRenderTime = 1.0 / 160.0; // User-defined render FPS
|
|
||||||
|
|
||||||
void setTickCallback(Function _tick) {
|
|
||||||
tickCallback = _tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void run() {
|
|
||||||
running = true;
|
|
||||||
|
|
||||||
auto previousTime = std::chrono::high_resolution_clock::now();
|
|
||||||
double accumulatedUpdateTime = 0.0;
|
|
||||||
double accumulatedRenderTime = 0.0;
|
|
||||||
|
|
||||||
while (running) {
|
|
||||||
// Time handling
|
|
||||||
auto currentTime = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> deltaTime = currentTime - previousTime;
|
|
||||||
previousTime = currentTime;
|
|
||||||
|
|
||||||
accumulatedUpdateTime += deltaTime.count();
|
|
||||||
accumulatedRenderTime += deltaTime.count();
|
|
||||||
|
|
||||||
// Fixed Update loop (60 FPS)
|
|
||||||
while (accumulatedUpdateTime >= targetUpdateTime) {
|
|
||||||
Timestep timestep = (float)targetUpdateTime;
|
|
||||||
accumulatedUpdateTime -= targetUpdateTime;
|
|
||||||
|
|
||||||
if (tickCallback)
|
|
||||||
tickCallback();
|
|
||||||
|
|
||||||
}
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
if (accumulatedRenderTime >= targetRenderTime) {
|
|
||||||
runRender((float)targetRenderTime);
|
|
||||||
accumulatedRenderTime -= targetRenderTime;
|
|
||||||
}
|
|
||||||
resolveEvents();
|
|
||||||
#endif
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shutdown() {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
#include "Deer/Log.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
std::shared_ptr<spdlog::logger> Log::coreLogger;
|
|
||||||
std::shared_ptr<spdlog::logger> Log::clientLogger;
|
|
||||||
std::shared_ptr<spdlog::logger> Log::scriptLogger;
|
|
||||||
std::shared_ptr<spdlog::logger> Log::EditorEngineLogger;
|
|
||||||
|
|
||||||
void Log::init()
|
|
||||||
{
|
|
||||||
spdlog::set_pattern("%^[%T] %n: %v%$");
|
|
||||||
|
|
||||||
coreLogger = spdlog::stdout_color_mt("Core");
|
|
||||||
clientLogger = spdlog::stdout_color_mt("Client");
|
|
||||||
scriptLogger = spdlog::stdout_color_mt("Script");
|
|
||||||
EditorEngineLogger = spdlog::stdout_color_mt("UI Engine");
|
|
||||||
|
|
||||||
coreLogger->set_level(spdlog::level::level_enum::trace);
|
|
||||||
clientLogger->set_level(spdlog::level::level_enum::trace);
|
|
||||||
scriptLogger->set_level(spdlog::level::level_enum::trace);
|
|
||||||
EditorEngineLogger->set_level(spdlog::level::level_enum::trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::shutdown() {
|
|
||||||
coreLogger.reset();
|
|
||||||
clientLogger.reset();
|
|
||||||
scriptLogger.reset();
|
|
||||||
EditorEngineLogger.reset();
|
|
||||||
|
|
||||||
spdlog::drop_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::coreTrace(const char* msg)
|
|
||||||
{
|
|
||||||
//coreLogger->trace(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
#include "Deer/DataStore.h"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/Tools/Path.h"
|
|
||||||
|
|
||||||
#include "cereal/archives/portable_binary.hpp"
|
|
||||||
#include "cereal/cereal.hpp"
|
|
||||||
#include "cereal/types/unordered_map.hpp"
|
|
||||||
|
|
||||||
#include "Deer/DataStore/DataStructure.h"
|
|
||||||
#include "Deer/DataStore/DataStructureSerialization.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <ostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <streambuf>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace DataStore {
|
|
||||||
Path rootPath = "./";
|
|
||||||
std::unordered_map<std::string, DirectoryData> dirData_cache;
|
|
||||||
} // namespace DataStore
|
|
||||||
|
|
||||||
const DirectoryData& DataStore::getDirData(const Path& id,
|
|
||||||
const Path& subDir,
|
|
||||||
const char* extension) {
|
|
||||||
std::string dirId = std::string(id) + "&" + std::string(subDir) + "&" +
|
|
||||||
std::string(extension);
|
|
||||||
if (dirData_cache.contains(dirId)) {
|
|
||||||
return dirData_cache[dirId];
|
|
||||||
}
|
|
||||||
|
|
||||||
Path idPath = rootPath / id;
|
|
||||||
|
|
||||||
Path searchPath = idPath / subDir;
|
|
||||||
|
|
||||||
DirectoryData& dirData = dirData_cache[dirId];
|
|
||||||
for (const auto& entry :
|
|
||||||
std::filesystem::directory_iterator(searchPath)) {
|
|
||||||
if (entry.is_directory())
|
|
||||||
dirData.dirs.push_back(entry.path().lexically_relative(idPath));
|
|
||||||
else if (entry.path().extension() == extension) {
|
|
||||||
Path ent = entry.path().lexically_relative(idPath);
|
|
||||||
dirData.elements.push_back(ent.parent_path() / ent.stem());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirData;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataStore::loadFileData(const Path& id, const Path& name,
|
|
||||||
uint8_t** data, uint32_t* size) {
|
|
||||||
Path filePath = rootPath / id / name;
|
|
||||||
std::ifstream file(filePath, std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
file.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.seekg(0, std::ios::end);
|
|
||||||
*size = (size_t)file.tellg();
|
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
|
|
||||||
*data = new uint8_t[*size];
|
|
||||||
|
|
||||||
if (!file.read(reinterpret_cast<char*>(*data), *size)) {
|
|
||||||
DEER_CORE_ERROR("Failed to read file: {0}",
|
|
||||||
filePath.generic_string().c_str());
|
|
||||||
delete[] *data;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataStore::loadGlobalFileData(const Path& id, const Path& name,
|
|
||||||
uint8_t** data, uint32_t* size) {
|
|
||||||
Path filePath = rootPath / id;
|
|
||||||
for (auto& f :
|
|
||||||
std::filesystem::recursive_directory_iterator(filePath)) {
|
|
||||||
if (f.path().stem() == name) {
|
|
||||||
std::ifstream file(f.path(), std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
file.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.seekg(0, std::ios::end);
|
|
||||||
*size = (size_t)file.tellg();
|
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
|
|
||||||
*data = new uint8_t[*size];
|
|
||||||
|
|
||||||
if (!file.read(reinterpret_cast<char*>(*data), *size)) {
|
|
||||||
DEER_CORE_ERROR("Failed to read file: {0}",
|
|
||||||
filePath.generic_string().c_str());
|
|
||||||
delete[] *data;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEER_CORE_ERROR("File {0} not found", filePath.string().c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::freeFileData(uint8_t* data) { delete[] data; }
|
|
||||||
|
|
||||||
void DataStore::deleteFile(const Path& path) {
|
|
||||||
Path filePath = rootPath / toLowerCasePath(path);
|
|
||||||
std::filesystem::remove(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* DataStore::readFile(const Path& path, uint32_t* size) {
|
|
||||||
Path filePath = rootPath / path;
|
|
||||||
std::ifstream file(filePath, std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
file.close();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.seekg(0, std::ios::end);
|
|
||||||
*size = (size_t)file.tellg();
|
|
||||||
file.seekg(0, std::ios::beg);
|
|
||||||
|
|
||||||
uint8_t* buffer = new uint8_t[*size];
|
|
||||||
|
|
||||||
if (!file.read(reinterpret_cast<char*>(buffer), *size)) {
|
|
||||||
DEER_CORE_ERROR("Failed to read file: {0}",
|
|
||||||
filePath.generic_string().c_str());
|
|
||||||
delete[] buffer;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::saveFile(const Path& path, uint8_t* data, uint32_t size) {
|
|
||||||
Path filePath = rootPath / toLowerCasePath(path);
|
|
||||||
std::filesystem::create_directories(filePath.parent_path());
|
|
||||||
|
|
||||||
std::ofstream file(filePath, std::ios::out | std::ios::binary);
|
|
||||||
|
|
||||||
DEER_CORE_ASSERT(file, "Error when writing file {0}",
|
|
||||||
filePath.generic_string().c_str());
|
|
||||||
|
|
||||||
file.write(reinterpret_cast<const char*>(data), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::compressFiles(std::vector<Path> files, const Path& path) {
|
|
||||||
std::unordered_map<Path, DataStructure> dataStructure;
|
|
||||||
std::vector<uint8_t> combinedData;
|
|
||||||
|
|
||||||
for (const Path& inputPath : files) {
|
|
||||||
uint32_t fileSize = 0;
|
|
||||||
uint8_t* fileData = readFile(inputPath, &fileSize);
|
|
||||||
|
|
||||||
uint32_t start = combinedData.size();
|
|
||||||
|
|
||||||
combinedData.insert(combinedData.end(), fileData,
|
|
||||||
fileData + fileSize);
|
|
||||||
dataStructure[inputPath] = DataStructure{.dataPath = inputPath,
|
|
||||||
.dataStart = start,
|
|
||||||
.dataSize = fileSize};
|
|
||||||
|
|
||||||
delete[] fileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
Path compressedPath = path;
|
|
||||||
compressedPath += ".deer";
|
|
||||||
Path metaPath = path;
|
|
||||||
metaPath += ".deer.meta";
|
|
||||||
|
|
||||||
std::stringstream buffer;
|
|
||||||
{
|
|
||||||
cereal::PortableBinaryOutputArchive archive(buffer);
|
|
||||||
archive(dataStructure);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveFile(compressedPath, combinedData.data(), combinedData.size());
|
|
||||||
saveFile(metaPath, (uint8_t*)buffer.str().c_str(), buffer.str().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Path> DataStore::getFiles(const Path& path, const std::string& extension) {
|
|
||||||
std::vector<Path> files;
|
|
||||||
Path lookPath = rootPath / path;
|
|
||||||
|
|
||||||
for (const auto& entry :
|
|
||||||
std::filesystem::recursive_directory_iterator(lookPath)) {
|
|
||||||
if (std::filesystem::is_regular_file(entry) &&
|
|
||||||
entry.path().extension() == extension) {
|
|
||||||
files.push_back(entry.path().lexically_relative(rootPath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::createFolder(const Path& path) {
|
|
||||||
std::filesystem::create_directories(path);
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
#include "Deer/Components.h"
|
|
||||||
#include "glm/gtc/matrix_transform.hpp"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
glm::mat4 TransformComponent::getMatrix() const{
|
|
||||||
glm::mat4 scaleMat = glm::scale(glm::mat4(1.0f), scale);
|
|
||||||
glm::mat4 roatationMat = glm::mat4(rotation);
|
|
||||||
glm::mat4 positionMat = glm::translate(glm::mat4(1.0f), position);
|
|
||||||
|
|
||||||
return positionMat * roatationMat * scaleMat;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
#include "Deer/Scene.h"
|
|
||||||
|
|
||||||
#include "Deer/Components.h"
|
|
||||||
#include "Deer/Enviroment.h"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
#include "Deer/Voxels/Chunk.h"
|
|
||||||
#include "Deer/Voxels/Layer.h"
|
|
||||||
#include "Deer/Voxels/VoxelWorldData.h"
|
|
||||||
|
|
||||||
#include "Deer/Enviroment.h"
|
|
||||||
#include "Deer/Scene/SceneData.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/FrameBuffer.h"
|
|
||||||
#include "DeerRender/Mesh.h"
|
|
||||||
#include "DeerRender/Shader.h"
|
|
||||||
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
void Scene::clear() {
|
|
||||||
environment.clear();
|
|
||||||
VoxelWorld::clear();
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
ResourceManager<Shader>::unloadResources();
|
|
||||||
ResourceManager<GPUMesh>::unloadResources();
|
|
||||||
FrameBufferManager::unloadAllFrameBuffer();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Scene::getExecutingState() {
|
|
||||||
return isExecuting;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::initExecution() {
|
|
||||||
DEER_CORE_ASSERT(!isExecuting, "Deer scene is already executing");
|
|
||||||
isExecuting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::tickExecution() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::endExecution() {
|
|
||||||
DEER_CORE_ASSERT(isExecuting, "Deer scene is not executing");
|
|
||||||
isExecuting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
#include "Deer/Enviroment.h"
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/GizmoRenderer.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace Scene {
|
|
||||||
Environment environment;
|
|
||||||
bool isExecuting = false;
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
GizmoRenderer gizmoRenderer;
|
|
||||||
#endif
|
|
||||||
} // namespace Scene
|
|
||||||
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/GizmoRenderer.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Environment;
|
|
||||||
|
|
||||||
namespace Scene {
|
|
||||||
extern Environment environment;
|
|
||||||
extern bool isExecuting;
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
extern GizmoRenderer gizmoRenderer;
|
|
||||||
#endif
|
|
||||||
} // namespace Scene
|
|
||||||
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Components.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
// RELATIONSHIP COMPONENT
|
|
||||||
template <class Archive>
|
|
||||||
void serialize(Archive& archive, RelationshipComponent& relationship) {
|
|
||||||
archive(cereal::make_nvp("parentId", relationship.parent_id));
|
|
||||||
|
|
||||||
archive(cereal::make_size_tag(
|
|
||||||
static_cast<cereal::size_type>(relationship.getChildCount())));
|
|
||||||
for (int i = 0; i < relationship.getChildCount(); i++)
|
|
||||||
archive(relationship.getChildId(i));
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Components.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
|
|
||||||
// TRANSFORM COMPONENT
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& archive,
|
|
||||||
TransformComponent& transform) {
|
|
||||||
|
|
||||||
archive(cereal::make_nvp("position", transform.position));
|
|
||||||
archive(cereal::make_nvp("scale", transform.scale));
|
|
||||||
archive(cereal::make_nvp("rotation", transform.rotation));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Deer/Components.h"
|
|
||||||
#include "Deer/Enviroment.h"
|
|
||||||
#include "Deer/Scene/Serialization/SerializationGlobalVars.h"
|
|
||||||
#include "EntitySerializationStruct.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
template <class Archive, typename T>
|
|
||||||
void saveComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
|
||||||
bool hasComponent = m_entity.hasComponent<T>();
|
|
||||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
|
||||||
if (hasComponent) {
|
|
||||||
const T& component = m_entity.getComponent<T>();
|
|
||||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive, typename T>
|
|
||||||
void loadComponent(Archive& archive, const std::string& componentName, Entity const& m_entity) {
|
|
||||||
bool hasComponent;
|
|
||||||
archive(cereal::make_nvp(("has_" + componentName).c_str(), hasComponent));
|
|
||||||
if (hasComponent) {
|
|
||||||
T& component = m_entity.addComponent<T>();
|
|
||||||
archive(cereal::make_nvp(componentName.c_str(), component));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ENTITY
|
|
||||||
template <class Archive>
|
|
||||||
void save(Archive& archive, EntitySerializationStruct const& m_entity) {
|
|
||||||
const Entity& entity = m_entity.env->getEntity(m_entity.entityID);
|
|
||||||
|
|
||||||
const TagComponent& name = entity.getComponent<TagComponent>();
|
|
||||||
archive(cereal::make_nvp("id", m_entity.entityID));
|
|
||||||
archive(cereal::make_nvp("name", name.tag));
|
|
||||||
|
|
||||||
const TransformComponent& transform = entity.getComponent<TransformComponent>();
|
|
||||||
archive(cereal::make_nvp("transform", transform));
|
|
||||||
|
|
||||||
const RelationshipComponent& relation = entity.getComponent<RelationshipComponent>();
|
|
||||||
archive(cereal::make_nvp("relationship", relation));
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
if (!is_server_serialization) {
|
|
||||||
saveComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
|
|
||||||
saveComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void load(Archive& archive, EntitySerializationStruct& m_entity) {
|
|
||||||
uint16_t id;
|
|
||||||
std::string name;
|
|
||||||
archive(cereal::make_nvp("id", id));
|
|
||||||
archive(cereal::make_nvp("name", name));
|
|
||||||
|
|
||||||
Entity& entity = m_entity.env->createEntityWithId(id);
|
|
||||||
archive(cereal::make_nvp("transform", entity.getComponent<TransformComponent>()));
|
|
||||||
|
|
||||||
RelationshipComponent& rc = entity.getComponent<RelationshipComponent>();
|
|
||||||
archive(cereal::make_nvp("relationship", rc));
|
|
||||||
entity.setParent(m_entity.env->getEntity(rc.parent_id));
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
if (!is_server_serialization) {
|
|
||||||
loadComponent<Archive, MeshComponent>(archive, "meshRenderComponent", entity);
|
|
||||||
loadComponent<Archive, CameraComponent>(archive, "cameraComponent", entity);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Environment;
|
|
||||||
struct EntitySerializationStruct {
|
|
||||||
uint16_t entityID;
|
|
||||||
Environment* env;
|
|
||||||
};
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Deer/Enviroment.h"
|
|
||||||
#include "EntitySerializationStruct.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
struct EnvironmentEntity {
|
|
||||||
Environment& environment;
|
|
||||||
EnvironmentEntity(Environment& env) : environment(env) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void save(Archive& archive, const Deer::Environment& environment) {
|
|
||||||
EnvironmentEntity envEnt(const_cast<Deer::Environment&>(environment));
|
|
||||||
archive(cereal::make_nvp("entities", envEnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void load(Archive& archive, Deer::Environment& environment) {
|
|
||||||
EnvironmentEntity envEnt(environment);
|
|
||||||
archive(cereal::make_nvp("entities", envEnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void save(Archive& archive, EnvironmentEntity const& m_entities) {
|
|
||||||
archive(cereal::make_size_tag(static_cast<cereal::size_type>(
|
|
||||||
m_entities.environment.getEntityCount())));
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < m_entities.environment.getEntityCount(); i++) {
|
|
||||||
while (!m_entities.environment.entityExists(i)) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntitySerializationStruct serializationStruct;
|
|
||||||
serializationStruct.env =
|
|
||||||
const_cast<Environment*>(&m_entities.environment);
|
|
||||||
serializationStruct.entityID = i;
|
|
||||||
|
|
||||||
archive(serializationStruct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void load(Archive& archive, EnvironmentEntity& m_entities) {
|
|
||||||
cereal::size_type size;
|
|
||||||
archive(cereal::make_size_tag(size));
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
EntitySerializationStruct serializationStruct;
|
|
||||||
serializationStruct.env = &m_entities.environment;
|
|
||||||
|
|
||||||
archive(serializationStruct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
namespace Deer {
|
|
||||||
bool is_server_serialization = false;
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cereal/cereal.hpp"
|
|
||||||
#include "cereal/types/string.hpp"
|
|
||||||
#include "cereal/types/vector.hpp"
|
|
||||||
|
|
||||||
// Serialization Vars
|
|
||||||
#include "Deer/Scene/Serialization/SerializationGlobalVars.h"
|
|
||||||
|
|
||||||
// GENERICS
|
|
||||||
#include "Deer/Scene/Serialization/QuatSerialization.h"
|
|
||||||
#include "Deer/Scene/Serialization/Vec3Serialization.h"
|
|
||||||
|
|
||||||
// SCENE SPECIFIC
|
|
||||||
#include "Deer/Scene/Serialization/EntitySerialization.h"
|
|
||||||
#include "Deer/Scene/Serialization/EnvironmentSerialization.h"
|
|
||||||
|
|
||||||
// COMPONENTS SPECIFIC
|
|
||||||
#include "Deer/Scene/Serialization/Components/RelationshipComponentSerialization.h"
|
|
||||||
#include "Deer/Scene/Serialization/Components/TransformComponentSerialization.h"
|
|
||||||
|
|
||||||
// RENDER SPECIFIC
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/Scene/Serialization/Components/CameraSerializationComponent.h"
|
|
||||||
#include "DeerRender/Scene/Serialization/Components/MeshRenderComponentSerialization.h"
|
|
||||||
#include "DeerRender/Scene/Serialization/Components/TextureBindingSerializationComponent.h"
|
|
||||||
#endif
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
#include "SerializationGlobalVars.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
|
|
||||||
bool is_server_serialization = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
extern bool is_server_serialization;
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
#include "Chunk.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
Chunk::~Chunk() {
|
|
||||||
if (m_voxels) {
|
|
||||||
delete[] m_voxels;
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
delete[] m_lightInfo;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::loadVoxels() {
|
|
||||||
if (!m_voxels) {
|
|
||||||
m_voxels = new Voxel[CHUNK_VOXELS]();
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
m_lightInfo = new VoxelLight[CHUNK_VOXELS]();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "DeerRender/Voxel.h"
|
|
||||||
#include "DeerRender/VoxelAspect.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Chunk {
|
|
||||||
public:
|
|
||||||
Chunk() = default;
|
|
||||||
~Chunk();
|
|
||||||
|
|
||||||
inline Voxel readVoxel(ChunkVoxelID id) {
|
|
||||||
if (m_voxels)
|
|
||||||
return m_voxels[VOXEL_POSITION(id)];
|
|
||||||
return emptyVoxel;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Voxel& modVoxel(ChunkVoxelID id) {
|
|
||||||
if (!m_voxels)
|
|
||||||
loadVoxels();
|
|
||||||
return m_voxels[VOXEL_POSITION(id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void fillVoxels(ChunkVoxelID min, ChunkVoxelID max, Voxel info) {
|
|
||||||
if (!m_voxels)
|
|
||||||
loadVoxels();
|
|
||||||
|
|
||||||
ChunkVoxelID voxelID;
|
|
||||||
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
|
|
||||||
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
|
|
||||||
for (voxelID.z = min.z; voxelID.z <= max.x; voxelID.z++) {
|
|
||||||
m_voxels[VOXEL_POSITION(voxelID)] = info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void remplaceVoxels(ChunkVoxelID min, ChunkVoxelID max,
|
|
||||||
Voxel ref, Voxel value) {
|
|
||||||
if (!m_voxels)
|
|
||||||
loadVoxels();
|
|
||||||
|
|
||||||
ChunkVoxelID voxelID;
|
|
||||||
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
|
|
||||||
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
|
|
||||||
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
|
|
||||||
Voxel& currentVoxel = m_voxels[VOXEL_POSITION(voxelID)];
|
|
||||||
|
|
||||||
if (currentVoxel.id == ref.id)
|
|
||||||
currentVoxel = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t calculateLayerVoxelHeight(LayerVoxelID layerVoxelID) {
|
|
||||||
if (!m_voxels)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ChunkVoxelID voxelID(layerVoxelID.x, CHUNK_SIZE_Y - 1,
|
|
||||||
layerVoxelID.z);
|
|
||||||
for (int y = CHUNK_SIZE_Y - 1; y >= 0; y--) {
|
|
||||||
voxelID.y = y;
|
|
||||||
|
|
||||||
if (m_voxels[VOXEL_POSITION(voxelID)].id != 0)
|
|
||||||
return voxelID.y + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Voxel* m_voxels = nullptr;
|
|
||||||
|
|
||||||
void loadVoxels();
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
public:
|
|
||||||
inline VoxelLight readLight(ChunkVoxelID id) {
|
|
||||||
if (m_voxels)
|
|
||||||
return m_lightInfo[VOXEL_POSITION(id)];
|
|
||||||
return VoxelLight();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VoxelLight& modLight(ChunkVoxelID id) {
|
|
||||||
if (!m_voxels)
|
|
||||||
loadVoxels();
|
|
||||||
return m_lightInfo[VOXEL_POSITION(id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void clearVoxelLight(ChunkVoxelID min, ChunkVoxelID max) {
|
|
||||||
ChunkVoxelID voxelID;
|
|
||||||
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
|
|
||||||
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
|
|
||||||
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].b_light = 0;
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].r_light = 0;
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].g_light = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is the same as clear Voxel Light but it also checks if
|
|
||||||
// there is a source of light
|
|
||||||
inline void clearVoxelLightAndSaveSources(
|
|
||||||
ChunkVoxelID min, ChunkVoxelID max, ChunkID chunkID,
|
|
||||||
std::vector<VoxelCordinates>& sources) {
|
|
||||||
if (!m_voxels)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ChunkVoxelID voxelID;
|
|
||||||
for (voxelID.x = min.x; voxelID.x <= max.x; voxelID.x++) {
|
|
||||||
for (voxelID.y = min.y; voxelID.y <= max.y; voxelID.y++) {
|
|
||||||
for (voxelID.z = min.z; voxelID.z <= max.z; voxelID.z++) {
|
|
||||||
Voxel voxel = m_voxels[VOXEL_POSITION(voxelID)];
|
|
||||||
VoxelAspect& voxelAspect =
|
|
||||||
DataStore::voxelsAspect[voxel.id];
|
|
||||||
if (voxelAspect.isLightSource()) {
|
|
||||||
sources.push_back(VoxelCordinates(
|
|
||||||
voxelID.x + chunkID.x * CHUNK_SIZE_X,
|
|
||||||
voxelID.y + chunkID.y * CHUNK_SIZE_Y,
|
|
||||||
voxelID.z + chunkID.z * CHUNK_SIZE_Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].b_light = 0;
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].r_light = 0;
|
|
||||||
m_lightInfo[VOXEL_POSITION(voxelID)].g_light = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
VoxelLight* m_lightInfo = nullptr;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
#include "Layer.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
Layer::~Layer() {
|
|
||||||
if (m_layerInfo)
|
|
||||||
delete[] m_layerInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::loadData() {
|
|
||||||
m_layerInfo = new LayerVoxel[LAYER_VOXELS]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
class Layer {
|
|
||||||
public:
|
|
||||||
Layer() = default;
|
|
||||||
~Layer();
|
|
||||||
|
|
||||||
inline LayerVoxel readLayerVoxel(LayerVoxelID id) {
|
|
||||||
if (!m_layerInfo)
|
|
||||||
return LayerVoxel();
|
|
||||||
return m_layerInfo[LAYER_VOXEL_POSITION(id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LayerVoxel& modLayerVoxel(LayerVoxelID id) {
|
|
||||||
if (!m_layerInfo)
|
|
||||||
loadData();
|
|
||||||
return m_layerInfo[LAYER_VOXEL_POSITION(id)];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void fillVoxelLayerMaxHeight(LayerVoxelID min, LayerVoxelID max, uint8_t maxHeight) {
|
|
||||||
if (!m_layerInfo)
|
|
||||||
loadData();
|
|
||||||
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
for (layerVoxelID.x = min.x; layerVoxelID.x <= max.x; layerVoxelID.x++) {
|
|
||||||
for (layerVoxelID.z = min.x; layerVoxelID.z <= max.z; layerVoxelID.z++) {
|
|
||||||
int id = LAYER_VOXEL_POSITION(layerVoxelID);
|
|
||||||
if (m_layerInfo[id].height <= maxHeight)
|
|
||||||
m_layerInfo[id].height = maxHeight + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void loadData();
|
|
||||||
|
|
||||||
LayerVoxel* m_layerInfo = nullptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
|
|
||||||
#include "cereal/cereal.hpp"
|
|
||||||
#include "cereal/types/string.hpp"
|
|
||||||
|
|
||||||
namespace Deer{
|
|
||||||
template<class Archive>
|
|
||||||
void save(Archive & archive, VoxelInfo const & block) {
|
|
||||||
archive(cereal::make_nvp("name", block.name));
|
|
||||||
|
|
||||||
// To avoid breaking things we set it up to Air
|
|
||||||
const char* blockTypeChar = VOXEL_INFO_TYPE_AIR;
|
|
||||||
switch (block.type)
|
|
||||||
{
|
|
||||||
case VoxelInfoType::Air :
|
|
||||||
blockTypeChar = VOXEL_INFO_TYPE_AIR;
|
|
||||||
break;
|
|
||||||
case VoxelInfoType::Voxel :
|
|
||||||
blockTypeChar = VOXEL_INFO_TYPE_VOXEL;
|
|
||||||
break;
|
|
||||||
case VoxelInfoType::TransparentVoxel :
|
|
||||||
blockTypeChar = VOXEL_INFO_TYPE_TRANSPARENT_VOXEL;
|
|
||||||
break;
|
|
||||||
case VoxelInfoType::Custom :
|
|
||||||
blockTypeChar = VOXEL_INFO_TYPE_CUSTOM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string blockTypeString(blockTypeChar);
|
|
||||||
archive(cereal::make_nvp("type", blockTypeString));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void load(Archive & archive, VoxelInfo & block) {archive(cereal::make_nvp("name", block.name));
|
|
||||||
std::string blockTypeString;
|
|
||||||
|
|
||||||
archive(cereal::make_nvp("name", block.name));
|
|
||||||
archive(cereal::make_nvp("type", blockTypeString));
|
|
||||||
|
|
||||||
if (blockTypeString == VOXEL_INFO_TYPE_AIR)
|
|
||||||
block.type = VoxelInfoType::Air;
|
|
||||||
else if (blockTypeString == VOXEL_INFO_TYPE_VOXEL)
|
|
||||||
block.type = VoxelInfoType::Voxel;
|
|
||||||
else if (blockTypeString == VOXEL_INFO_TYPE_TRANSPARENT_VOXEL)
|
|
||||||
block.type = VoxelInfoType::TransparentVoxel;
|
|
||||||
else if (blockTypeString == VOXEL_INFO_TYPE_CUSTOM)
|
|
||||||
block.type = VoxelInfoType::Custom;
|
|
||||||
else {
|
|
||||||
block.type = VoxelInfoType::Air;
|
|
||||||
DEER_CORE_ERROR("Failed to resolve voxel type for {0}, unknown type : {1}",
|
|
||||||
block.name.c_str(), blockTypeString.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
#include "Deer/Voxel.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
// This means the voxel is null
|
|
||||||
Voxel nullVoxel(65535);
|
|
||||||
Voxel emptyVoxel;
|
|
||||||
|
|
||||||
LayerVoxel nullLayerVoxel(65535);
|
|
||||||
|
|
||||||
int normalDirs[3 * 6] = {
|
|
||||||
-1, 0, 0,
|
|
||||||
1, 0, 0,
|
|
||||||
0, -1, 0,
|
|
||||||
0, 1, 0,
|
|
||||||
0, 0, -1,
|
|
||||||
0, 0, 1
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Deer/DataStore.h"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/Voxel.h"
|
|
||||||
#include "Deer/Voxels/Serialization/VoxelInfoSerialization.h"
|
|
||||||
#include "cereal/archives/json.hpp"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace DataStore {
|
|
||||||
std::vector<VoxelInfo> voxelsInfo;
|
|
||||||
std::unordered_map<std::string, uint32_t> blockIDMap;
|
|
||||||
} // namespace DataStore
|
|
||||||
|
|
||||||
int32_t DataStore::getVoxelID(const std::string& name) {
|
|
||||||
if (blockIDMap.contains(name))
|
|
||||||
return blockIDMap[name];
|
|
||||||
DEER_CORE_WARN("Voxel Info {0} Not Found!", name.c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::loadVoxelsData() {
|
|
||||||
voxelsInfo.clear();
|
|
||||||
blockIDMap.clear();
|
|
||||||
|
|
||||||
VoxelInfo airVoxelInfo;
|
|
||||||
airVoxelInfo.name = VOXEL_INFO_TYPE_AIR;
|
|
||||||
|
|
||||||
voxelsInfo.push_back(airVoxelInfo);
|
|
||||||
blockIDMap[VOXEL_INFO_TYPE_AIR] = 0;
|
|
||||||
|
|
||||||
std::vector<Path> voxelsData;
|
|
||||||
voxelsData = DataStore::getFiles(DEER_VOXEL_DATA_PATH, ".voxel");
|
|
||||||
|
|
||||||
DEER_CORE_TRACE("Loading voxels");
|
|
||||||
for (Path& voxel : voxelsData) {
|
|
||||||
VoxelInfo voxelData;
|
|
||||||
|
|
||||||
uint32_t dataSize;
|
|
||||||
uint8_t* data = DataStore::readFile(voxel, &dataSize);
|
|
||||||
|
|
||||||
std::string dataString((char*)data, dataSize);
|
|
||||||
std::istringstream dataInputStream(dataString);
|
|
||||||
{
|
|
||||||
cereal::JSONInputArchive archive(dataInputStream);
|
|
||||||
archive(cereal::make_nvp("voxel", voxelData));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voxelData.name.empty()) {
|
|
||||||
DEER_CORE_ERROR("{0} has an empty name",
|
|
||||||
voxel.generic_string().c_str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blockIDMap.contains(voxelData.name)) {
|
|
||||||
DEER_CORE_ERROR("{0} with name {1} has dupplicated name id",
|
|
||||||
voxel.generic_string().c_str(),
|
|
||||||
voxelData.name.c_str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// DEER_CORE_TRACE(" {0} - {1}",
|
|
||||||
// voxel.filename().generic_string().c_str(),
|
|
||||||
// voxelData.name);
|
|
||||||
|
|
||||||
uint32_t id = voxelsInfo.size();
|
|
||||||
|
|
||||||
voxelsInfo.push_back(voxelData);
|
|
||||||
blockIDMap[voxelData.name] = id;
|
|
||||||
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataStore::createExampleVoxelData() {
|
|
||||||
VoxelInfo block;
|
|
||||||
|
|
||||||
std::stringstream data;
|
|
||||||
{
|
|
||||||
cereal::JSONOutputArchive archive(data);
|
|
||||||
archive(cereal::make_nvp("voxel", block));
|
|
||||||
}
|
|
||||||
|
|
||||||
DataStore::saveFile(Path(DEER_VOXEL_PATH) / "voxel.example",
|
|
||||||
(uint8_t*)(data.str().c_str()), data.str().size());
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
#include "Deer/Voxels/VoxelWorldData.h"
|
|
||||||
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/Voxels/Chunk.h"
|
|
||||||
#include "Deer/Voxels/Layer.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
void VoxelWorld::initialize(const VoxelWorldProps& props) {
|
|
||||||
clear();
|
|
||||||
|
|
||||||
worldProps = props;
|
|
||||||
|
|
||||||
chunks = MakeScope<Chunk[]>(worldProps.getChunkCount());
|
|
||||||
layers = MakeScope<Layer[]>(worldProps.getLayerCount());
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
initializeRenderVars(props);
|
|
||||||
#endif
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelWorld::clear() {
|
|
||||||
chunks.reset();
|
|
||||||
layers.reset();
|
|
||||||
|
|
||||||
initialized = false;
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
clearRenderVars();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const VoxelWorldProps& VoxelWorld::getWorldProps() {
|
|
||||||
return worldProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t VoxelWorld::calculateLayerVoxelHeight(int x, int z) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
LayerID layerID;
|
|
||||||
|
|
||||||
extractLayerCordinates(x, z, layerID, layerVoxelID);
|
|
||||||
ChunkID chunkID(layerID.x, 0, layerID.z);
|
|
||||||
|
|
||||||
for (int y = worldProps.chunkSizeY - 1; y >= 0; y--) {
|
|
||||||
chunkID.y = y;
|
|
||||||
|
|
||||||
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
|
|
||||||
uint8_t chunkVoxelHeight =
|
|
||||||
chunk.calculateLayerVoxelHeight(layerVoxelID);
|
|
||||||
|
|
||||||
if (chunkVoxelHeight != 0) {
|
|
||||||
return chunkVoxelHeight + chunkID.y * CHUNK_SIZE_Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
#include "Deer/Voxels/VoxelWorldData.h"
|
|
||||||
#include "Deer/Voxels/Chunk.h"
|
|
||||||
#include "Deer/Voxels/Layer.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace VoxelWorld {
|
|
||||||
VoxelWorldProps worldProps;
|
|
||||||
|
|
||||||
Scope<Chunk[]> chunks;
|
|
||||||
Scope<Layer[]> layers;
|
|
||||||
|
|
||||||
bool initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VoxelWorld::isInitialized() {
|
|
||||||
return initialized;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Deer/Tools/Memory.h"
|
|
||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
namespace VoxelWorld {
|
|
||||||
extern VoxelWorldProps worldProps;
|
|
||||||
|
|
||||||
extern Scope<Chunk[]> chunks;
|
|
||||||
extern Scope<Layer[]> layers;
|
|
||||||
extern bool initialized;
|
|
||||||
} // namespace VoxelWorld
|
|
||||||
} // namespace Deer
|
|
||||||
@ -1,159 +0,0 @@
|
|||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/Voxels/Chunk.h"
|
|
||||||
#include "Deer/Voxels/Layer.h"
|
|
||||||
#include "Deer/Voxels/VoxelWorldData.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <cmath>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
VoxelRayResult VoxelWorld::rayCast(glm::vec3 position, glm::vec3 dir, float maxDistance) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
VoxelRayResult result;
|
|
||||||
|
|
||||||
result.hitPos.x = (int32_t)std::floor(position.x);
|
|
||||||
result.hitPos.y = (int32_t)std::floor(position.y);
|
|
||||||
result.hitPos.z = (int32_t)std::floor(position.z);
|
|
||||||
|
|
||||||
result.distance = 0;
|
|
||||||
|
|
||||||
if (dir.x == 0 && dir.y == 0 && dir.z == 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir = glm::normalize(dir);
|
|
||||||
|
|
||||||
glm::vec3 stepAxis = glm::vec3(maxDistance, maxDistance, maxDistance);
|
|
||||||
glm::vec3 distanceAxis = glm::vec3(maxDistance, maxDistance, maxDistance);
|
|
||||||
|
|
||||||
int8_t directionAxis[3] = { 1, 1, 1 };
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (dir[i] < 0) {
|
|
||||||
stepAxis[i] = -1.0f / dir[i];
|
|
||||||
directionAxis[i] = -1;
|
|
||||||
distanceAxis[i] = stepAxis[i] * ((float)position[i] - (float)(&result.hitPos.x)[i]);
|
|
||||||
}
|
|
||||||
else if (dir[i] > 0) {
|
|
||||||
stepAxis[i] = 1.0f / dir[i];
|
|
||||||
distanceAxis[i] = stepAxis[i] * (1 - (float)position[i] + (float)(&result.hitPos.x)[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (result.distance < maxDistance) {
|
|
||||||
float minDistance = distanceAxis[0];
|
|
||||||
for (int i = 1; i < 3; i++) {
|
|
||||||
if (distanceAxis[i] < minDistance)
|
|
||||||
minDistance = distanceAxis[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
result.distance = minDistance;
|
|
||||||
if (result.distance > maxDistance)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (minDistance == distanceAxis[i]) {
|
|
||||||
result.hitPos[i] += directionAxis[i];
|
|
||||||
distanceAxis[i] = minDistance + stepAxis[i];
|
|
||||||
|
|
||||||
Voxel hitVoxel = readVoxel(result.hitPos);
|
|
||||||
|
|
||||||
if (hitVoxel == nullVoxel)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (hitVoxel != 0) {
|
|
||||||
result.face = i * 2;
|
|
||||||
|
|
||||||
if (directionAxis[i] == -1)
|
|
||||||
result.face++;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.distance = maxDistance;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
VoxelRayResult VoxelWorld::rayCast_editor(glm::vec3 position, glm::vec3 dir, float maxDistance) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
VoxelRayResult result;
|
|
||||||
|
|
||||||
result.hitPos.x = (int32_t)std::floor(position.x);
|
|
||||||
result.hitPos.y = (int32_t)std::floor(position.y);
|
|
||||||
result.hitPos.z = (int32_t)std::floor(position.z);
|
|
||||||
|
|
||||||
result.distance = 0;
|
|
||||||
|
|
||||||
if (dir.x == 0 && dir.y == 0 && dir.z == 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir = glm::normalize(dir);
|
|
||||||
|
|
||||||
glm::vec3 stepAxis = glm::vec3(maxDistance, maxDistance, maxDistance);
|
|
||||||
glm::vec3 distanceAxis = glm::vec3(maxDistance, maxDistance, maxDistance);
|
|
||||||
|
|
||||||
int8_t directionAxis[3] = { 1, 1, 1 };
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (dir[i] < 0) {
|
|
||||||
stepAxis[i] = -1.0f / dir[i];
|
|
||||||
directionAxis[i] = -1;
|
|
||||||
distanceAxis[i] = stepAxis[i] * ((float)position[i] - (float)result.hitPos[i]);
|
|
||||||
}
|
|
||||||
else if (dir[i] > 0) {
|
|
||||||
stepAxis[i] = 1.0f / dir[i];
|
|
||||||
distanceAxis[i] = stepAxis[i] * (1 - (float)position[i] + (float)result.hitPos[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Voxel hitVoxel = readVoxel(result.hitPos);
|
|
||||||
bool has_exit_inner_walls = hitVoxel.id == 0;
|
|
||||||
while (result.distance < maxDistance) {
|
|
||||||
float minDistance = distanceAxis[0];
|
|
||||||
for (int i = 1; i < 3; i++) {
|
|
||||||
if (distanceAxis[i] < minDistance)
|
|
||||||
minDistance = distanceAxis[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
result.distance = minDistance;
|
|
||||||
if (result.distance > maxDistance)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (minDistance == distanceAxis[i]) {
|
|
||||||
result.hitPos[i] += directionAxis[i];
|
|
||||||
distanceAxis[i] = minDistance + stepAxis[i];
|
|
||||||
|
|
||||||
Voxel hitVoxel = readVoxel(result.hitPos);
|
|
||||||
|
|
||||||
if (hitVoxel.id == 0) {
|
|
||||||
if (has_exit_inner_walls && result.hitPos.y == -1 && directionAxis[1] == -1 && i == 1) {
|
|
||||||
result.face = NORMAL_UP;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
has_exit_inner_walls = true;
|
|
||||||
} else if (hitVoxel.id != 0 && has_exit_inner_walls) {
|
|
||||||
result.face = i * 2;
|
|
||||||
|
|
||||||
if (directionAxis[i] == -1)
|
|
||||||
result.face++;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.distance = maxDistance;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,255 +0,0 @@
|
|||||||
#include "Deer/Log.h"
|
|
||||||
#include "Deer/VoxelWorld.h"
|
|
||||||
#include "Deer/Voxels/Chunk.h"
|
|
||||||
#include "Deer/Voxels/Layer.h"
|
|
||||||
|
|
||||||
#include "Deer/Voxels/VoxelWorldData.h"
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
#include "DeerRender/Voxels/VoxelWorldRenderData.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Deer {
|
|
||||||
Voxel VoxelWorld::readVoxel(VoxelCordinates coords) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
ChunkID chunkID;
|
|
||||||
ChunkVoxelID chunkVoxelID;
|
|
||||||
|
|
||||||
extractChunkCordinates(coords, chunkID, chunkVoxelID);
|
|
||||||
if (!worldProps.isValid(chunkID)) return emptyVoxel;
|
|
||||||
|
|
||||||
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
|
|
||||||
return chunk.readVoxel(chunkVoxelID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelWorld::setVoxel(VoxelCordinates coords, Voxel info) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
ChunkID chunkID;
|
|
||||||
ChunkVoxelID chunkVoxelID;
|
|
||||||
|
|
||||||
extractChunkCordinates(coords, chunkID, chunkVoxelID);
|
|
||||||
if (!worldProps.isValid(chunkID)) return;
|
|
||||||
|
|
||||||
Chunk& chunk = chunks[worldProps.getWorldChunkID(chunkID)];
|
|
||||||
chunk.modVoxel(chunkVoxelID) = info;
|
|
||||||
|
|
||||||
LayerID layerID;
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
|
|
||||||
extractLayerCordinates(coords.x, coords.z, layerID, layerVoxelID);
|
|
||||||
|
|
||||||
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
|
|
||||||
LayerVoxel& layerVoxel = layer.modLayerVoxel(layerVoxelID);
|
|
||||||
|
|
||||||
if (!info.isVoxelType())
|
|
||||||
layerVoxel.height = calculateLayerVoxelHeight(coords.x, coords.z);
|
|
||||||
else if (coords.y >= layerVoxel.height)
|
|
||||||
layerVoxel.height = coords.y + 1;
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
chunkQueue.addChunk(chunkID);
|
|
||||||
// For every axis, X & Y & Z
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (chunkVoxelID[i] == 0 && chunkID[i] != 0) {
|
|
||||||
ChunkID nextChunk = chunkID;
|
|
||||||
nextChunk[i]--;
|
|
||||||
chunkQueue.addChunk(nextChunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunkVoxelID[i] == CHUNK_SIZE(i) &&
|
|
||||||
chunkID[i] != worldProps[i] - 1) {
|
|
||||||
ChunkID nextChunk = chunkID;
|
|
||||||
nextChunk[i]++;
|
|
||||||
chunkQueue.addChunk(nextChunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we should update the lighting
|
|
||||||
bakeAmbientLightFromPoint(coords.x, coords.z);
|
|
||||||
bakeVoxelLightFromPoint(coords);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelWorld::fillVoxels(VoxelCordinates min, VoxelCordinates max, Voxel info) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
ChunkID minChunkID;
|
|
||||||
ChunkID maxChunkID;
|
|
||||||
ChunkVoxelID minChunkVoxelID;
|
|
||||||
ChunkVoxelID maxChunkVoxelID;
|
|
||||||
|
|
||||||
worldProps.clampAndSetMinMax(min, max);
|
|
||||||
|
|
||||||
extractChunkCordinates(min, minChunkID, minChunkVoxelID);
|
|
||||||
extractChunkCordinates(max, maxChunkID, maxChunkVoxelID);
|
|
||||||
for (int chunkX = minChunkID.x; chunkX <= maxChunkID.x; chunkX++) {
|
|
||||||
for (int chunkY = minChunkID.y; chunkY <= maxChunkID.y; chunkY++) {
|
|
||||||
for (int chunkZ = minChunkID.z; chunkZ <= maxChunkID.z;
|
|
||||||
chunkZ++) {
|
|
||||||
ChunkID workingChunkID(chunkX, chunkY, chunkZ);
|
|
||||||
LayerID workingLayerID(chunkX, chunkZ);
|
|
||||||
Chunk& workingChunk =
|
|
||||||
chunks[worldProps.getWorldChunkID(workingChunkID)];
|
|
||||||
Layer& workingLayer =
|
|
||||||
layers[worldProps.getWorldLayerID(workingLayerID)];
|
|
||||||
|
|
||||||
ChunkVoxelID workingMin(0, 0, 0);
|
|
||||||
ChunkVoxelID workingMax(CHUNK_SIZE_X - 1, CHUNK_SIZE_Y - 1,
|
|
||||||
CHUNK_SIZE_Z - 1);
|
|
||||||
|
|
||||||
if (chunkX == minChunkID.x)
|
|
||||||
workingMin.x = minChunkVoxelID.x;
|
|
||||||
if (chunkY == minChunkID.y)
|
|
||||||
workingMin.y = minChunkVoxelID.y;
|
|
||||||
if (chunkZ == minChunkID.z)
|
|
||||||
workingMin.z = minChunkVoxelID.z;
|
|
||||||
|
|
||||||
if (chunkX == maxChunkID.x)
|
|
||||||
workingMax.x = maxChunkVoxelID.x;
|
|
||||||
if (chunkY == maxChunkID.y)
|
|
||||||
workingMax.y = maxChunkVoxelID.y;
|
|
||||||
if (chunkZ == maxChunkID.z)
|
|
||||||
workingMax.z = maxChunkVoxelID.z;
|
|
||||||
|
|
||||||
LayerVoxelID workingMinLayer(workingMin.x, workingMin.z);
|
|
||||||
LayerVoxelID workingMaxLayer(workingMax.x, workingMax.z);
|
|
||||||
|
|
||||||
workingChunk.fillVoxels(workingMin, workingMax, info);
|
|
||||||
workingLayer.fillVoxelLayerMaxHeight(
|
|
||||||
workingMinLayer, workingMaxLayer, max.y);
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
chunkQueue.addChunk(workingChunkID);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
VoxelCordinates minLightModification = min;
|
|
||||||
VoxelCordinates maxLightModification = max;
|
|
||||||
// We want to add a 16 layer border
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
minLightModification[i] -= 16;
|
|
||||||
maxLightModification[i] += 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
worldProps.clampCordinates(minLightModification);
|
|
||||||
worldProps.clampCordinates(maxLightModification);
|
|
||||||
|
|
||||||
bakeAmbientLight(minLightModification.x, maxLightModification.x,
|
|
||||||
minLightModification.z, maxLightModification.z);
|
|
||||||
bakeVoxelLight(minLightModification, maxLightModification);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelWorld::remplaceVoxels(VoxelCordinates min, VoxelCordinates max,
|
|
||||||
Voxel ref, Voxel value) {
|
|
||||||
DEER_CORE_ASSERT(initialized, "Voxel World is not initialized");
|
|
||||||
|
|
||||||
ChunkID minChunkID;
|
|
||||||
ChunkID maxChunkID;
|
|
||||||
ChunkVoxelID minChunkVoxelID;
|
|
||||||
ChunkVoxelID maxChunkVoxelID;
|
|
||||||
|
|
||||||
worldProps.clampAndSetMinMax(min, max);
|
|
||||||
|
|
||||||
extractChunkCordinates(min, minChunkID, minChunkVoxelID);
|
|
||||||
extractChunkCordinates(max, maxChunkID, maxChunkVoxelID);
|
|
||||||
for (int chunkX = minChunkID.x; chunkX <= maxChunkID.x; chunkX++) {
|
|
||||||
for (int chunkY = minChunkID.y; chunkY <= maxChunkID.y; chunkY++) {
|
|
||||||
for (int chunkZ = minChunkID.z; chunkZ <= maxChunkID.z;
|
|
||||||
chunkZ++) {
|
|
||||||
ChunkID workingChunkID(chunkX, chunkY, chunkZ);
|
|
||||||
Chunk& workingChunk =
|
|
||||||
chunks[worldProps.getWorldChunkID(workingChunkID)];
|
|
||||||
|
|
||||||
ChunkVoxelID workingMin(0, 0, 0);
|
|
||||||
ChunkVoxelID workingMax(CHUNK_SIZE_X - 1, CHUNK_SIZE_Y - 1,
|
|
||||||
CHUNK_SIZE_Z - 1);
|
|
||||||
|
|
||||||
if (chunkX == minChunkID.x)
|
|
||||||
workingMin.x = minChunkVoxelID.x;
|
|
||||||
if (chunkY == minChunkID.y)
|
|
||||||
workingMin.y = minChunkVoxelID.y;
|
|
||||||
if (chunkZ == minChunkID.z)
|
|
||||||
workingMin.z = minChunkVoxelID.z;
|
|
||||||
|
|
||||||
if (chunkX == maxChunkID.x)
|
|
||||||
workingMax.x = maxChunkVoxelID.x;
|
|
||||||
if (chunkY == maxChunkID.y)
|
|
||||||
workingMax.y = maxChunkVoxelID.y;
|
|
||||||
if (chunkZ == maxChunkID.z)
|
|
||||||
workingMax.z = maxChunkVoxelID.z;
|
|
||||||
|
|
||||||
workingChunk.remplaceVoxels(workingMin, workingMax, ref,
|
|
||||||
value);
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
chunkQueue.addChunk(workingChunkID);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int xPos = min.x; xPos <= max.x; xPos++) {
|
|
||||||
for (int zPos = min.z; zPos <= max.z; zPos++) {
|
|
||||||
LayerID layerID;
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
|
|
||||||
extractLayerCordinates(xPos, zPos, layerID, layerVoxelID);
|
|
||||||
int worldLayerID = worldProps.getWorldLayerID(layerID);
|
|
||||||
|
|
||||||
layers[worldLayerID].modLayerVoxel(layerVoxelID).height =
|
|
||||||
calculateLayerVoxelHeight(xPos, zPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEER_RENDER
|
|
||||||
VoxelCordinates minLightModification = min;
|
|
||||||
VoxelCordinates maxLightModification = max;
|
|
||||||
// We want to add a 16 layer border
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
minLightModification[i] -= 16;
|
|
||||||
maxLightModification[i] += 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
worldProps.clampCordinates(minLightModification);
|
|
||||||
worldProps.clampCordinates(maxLightModification);
|
|
||||||
|
|
||||||
bakeAmbientLight(minLightModification.x, maxLightModification.x,
|
|
||||||
minLightModification.z, maxLightModification.z);
|
|
||||||
bakeVoxelLight(minLightModification, maxLightModification);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerVoxel VoxelWorld::readLayerVoxel(int x, int z) {
|
|
||||||
LayerID layerID;
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
|
|
||||||
extractLayerCordinates(x, z, layerID, layerVoxelID);
|
|
||||||
if (!worldProps.isValid(layerID)) return LayerVoxel();
|
|
||||||
|
|
||||||
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
|
|
||||||
return layer.readLayerVoxel(layerVoxelID);
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerVoxel& VoxelWorld::modLayerVoxel(int x, int z) {
|
|
||||||
LayerID layerID;
|
|
||||||
LayerVoxelID layerVoxelID;
|
|
||||||
|
|
||||||
extractLayerCordinates(x, z, layerID, layerVoxelID);
|
|
||||||
if (!worldProps.isValid(layerID)) return nullLayerVoxel;
|
|
||||||
|
|
||||||
Layer& layer = layers[worldProps.getWorldLayerID(layerID)];
|
|
||||||
return layer.modLayerVoxel(layerVoxelID);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Deer
|
|
||||||
52
Deer/src/DeerCore/Core/Engine.cpp
Normal file
52
Deer/src/DeerCore/Core/Engine.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef DEER_RENDER
|
||||||
|
#include "DeerCore/Engine.h"
|
||||||
|
#include "DeerCore/Log.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Engine {
|
||||||
|
Function renderCallback = nullptr;
|
||||||
|
Function updateCallback = nullptr;
|
||||||
|
} // namespace Engine
|
||||||
|
|
||||||
|
void Engine::setUpdateCallback(Function _update) {
|
||||||
|
updateCallback = _update;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::init() {
|
||||||
|
Log::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::shutdown() {
|
||||||
|
Log::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::execute() {
|
||||||
|
bool running = true;
|
||||||
|
|
||||||
|
auto previousTime = std::chrono::high_resolution_clock::now();
|
||||||
|
double accumulatedUpdateTime = 0.0;
|
||||||
|
double accumulatedRenderTime = 0.0;
|
||||||
|
|
||||||
|
double targetUpdateTime = 1.0f / 50.0f;
|
||||||
|
double targetRenderTime = 1.0f / 144.0f;
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
auto currentTime = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> deltaTime = currentTime - previousTime;
|
||||||
|
previousTime = currentTime;
|
||||||
|
|
||||||
|
accumulatedUpdateTime += deltaTime.count();
|
||||||
|
accumulatedRenderTime += deltaTime.count();
|
||||||
|
|
||||||
|
while (accumulatedUpdateTime >= targetUpdateTime) {
|
||||||
|
float timestep = targetUpdateTime;
|
||||||
|
accumulatedUpdateTime -= targetUpdateTime;
|
||||||
|
|
||||||
|
updateCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
|
#endif
|
||||||
50
Deer/src/DeerCore/Core/Log.cpp
Executable file
50
Deer/src/DeerCore/Core/Log.cpp
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
#include "DeerCore/Log.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Log {
|
||||||
|
std::shared_ptr<spdlog::logger> coreLogger;
|
||||||
|
std::shared_ptr<spdlog::logger> clientLogger;
|
||||||
|
std::shared_ptr<spdlog::logger> scriptLogger;
|
||||||
|
std::shared_ptr<spdlog::logger> EditorEngineLogger;
|
||||||
|
} // namespace Log
|
||||||
|
|
||||||
|
void Log::init() {
|
||||||
|
// spdlog::set_pattern("%^[%T] %n: %v%$");
|
||||||
|
spdlog::set_pattern("%v%$");
|
||||||
|
|
||||||
|
coreLogger = spdlog::stdout_color_mt("Core");
|
||||||
|
clientLogger = spdlog::stdout_color_mt("Client");
|
||||||
|
scriptLogger = spdlog::stdout_color_mt("Script");
|
||||||
|
EditorEngineLogger = spdlog::stdout_color_mt("UI Engine");
|
||||||
|
|
||||||
|
coreLogger->set_level(spdlog::level::level_enum::trace);
|
||||||
|
clientLogger->set_level(spdlog::level::level_enum::trace);
|
||||||
|
scriptLogger->set_level(spdlog::level::level_enum::trace);
|
||||||
|
EditorEngineLogger->set_level(spdlog::level::level_enum::trace);
|
||||||
|
}
|
||||||
|
spdlog::logger* Log::getCoreLogger() {
|
||||||
|
return coreLogger.get();
|
||||||
|
}
|
||||||
|
spdlog::logger* Log::getClientLogger() {
|
||||||
|
return clientLogger.get();
|
||||||
|
}
|
||||||
|
spdlog::logger* Log::getScriptLogger() {
|
||||||
|
return scriptLogger.get();
|
||||||
|
}
|
||||||
|
spdlog::logger* Log::getEditorEngineLogger() {
|
||||||
|
return EditorEngineLogger.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::shutdown() {
|
||||||
|
coreLogger.reset();
|
||||||
|
clientLogger.reset();
|
||||||
|
scriptLogger.reset();
|
||||||
|
EditorEngineLogger.reset();
|
||||||
|
|
||||||
|
spdlog::drop_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::coreTrace(const char* msg) {
|
||||||
|
// coreLogger->trace(msg);
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
struct DataStructure {
|
struct DataStructure {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Deer/DataStore/DataStructure.h"
|
#include "DeerCore/DataStore/DataStructure.h"
|
||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
|
|
||||||
#include "cereal/cereal.hpp"
|
#include "cereal/cereal.hpp"
|
||||||
#include "cereal/types/string.hpp"
|
#include "cereal/types/string.hpp"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "Deer/Tools/Path.h"
|
#include "DeerCore/Tools/Path.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
Deer::Path Deer::toLowerCasePath(const Path& inputPath) {
|
Deer::Path Deer::toLowerCasePath(const Path& inputPath) {
|
||||||
96
Deer/src/DeerCore/Network/Server.cpp
Normal file
96
Deer/src/DeerCore/Network/Server.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#include "DeerCore/Log.h"
|
||||||
|
#include "DeerCore/Network.h"
|
||||||
|
|
||||||
|
#include "enet/enet.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Network {
|
||||||
|
ServerSettings serverSettings;
|
||||||
|
ENetHost* enetServer;
|
||||||
|
|
||||||
|
void clientConnect(ENetPeer* refPeer);
|
||||||
|
void clientDisconnect(ENetPeer* refPeer);
|
||||||
|
void clientData(ENetPeer* peer, ENetPacket* packet);
|
||||||
|
|
||||||
|
// Fixed array of clients, defined by max player count
|
||||||
|
Scope<DeerClient[]> clients;
|
||||||
|
} // namespace Network
|
||||||
|
|
||||||
|
void Network::initServer(const ServerSettings& config) {
|
||||||
|
serverSettings = config;
|
||||||
|
if (enet_initialize() != 0) {
|
||||||
|
DEER_CORE_ERROR("An error ocurred while initing enet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ENetAddress serverAddress;
|
||||||
|
|
||||||
|
serverAddress.host = ENET_HOST_ANY;
|
||||||
|
serverAddress.port = config.port;
|
||||||
|
|
||||||
|
enetServer = enet_host_create(&serverAddress, config.maxClients, 2, config.maxOutgoingBand, config.maxIncomingBand);
|
||||||
|
if (!enetServer) {
|
||||||
|
DEER_CORE_ERROR("An error ocurred while initing server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clients = MakeScope<DeerClient[]>(serverSettings.maxClients);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::shutdownServer() {
|
||||||
|
enet_deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::flushServerEvents() {
|
||||||
|
ENetEvent event;
|
||||||
|
while (enet_host_service(enetServer, &event, 0) > 0) {
|
||||||
|
switch (event.type) {
|
||||||
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
|
clientConnect(event.peer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
|
clientData(event.peer, event.packet);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
|
clientDisconnect(event.peer);
|
||||||
|
break;
|
||||||
|
case ENET_EVENT_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::clientConnect(ENetPeer* peer) {
|
||||||
|
DeerClient* client = nullptr;
|
||||||
|
int clientId = -1;
|
||||||
|
for (int i = 0; i < serverSettings.maxClients; i++) {
|
||||||
|
if (clients[i].clientState == DeerClientState::NotConnected) {
|
||||||
|
client = &client[i];
|
||||||
|
clientId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
DEER_CORE_ERROR("Server full, critical error");
|
||||||
|
enet_peer_disconnect(peer, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->clientState = DeerClientState::Connected;
|
||||||
|
client->internalPeer = peer;
|
||||||
|
peer->data = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::clientDisconnect(ENetPeer* peer) {
|
||||||
|
DeerClient& client = *(DeerClient*)peer->data;
|
||||||
|
client.clientState = DeerClientState::NotConnected;
|
||||||
|
client.internalPeer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::clientData(ENetPeer* peer, ENetPacket* packetData) {
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
@ -1,9 +1,8 @@
|
|||||||
#include "DeerStudio/AngelScriptEngine/ErrorHandle.h"
|
#include "DeerCore/Scripting/Helpers.h"
|
||||||
|
|
||||||
#include "angelscript.h"
|
#include "angelscript.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace AngelScriptEngine {
|
namespace Scripting {
|
||||||
const char* getAngelScriptReturnCodeString(int code) {
|
const char* getAngelScriptReturnCodeString(int code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case asSUCCESS:
|
case asSUCCESS:
|
||||||
@ -53,7 +52,7 @@ namespace Deer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AngelScriptEngine::ImplementsInterface(asITypeInfo* type, asITypeInfo* iface) {
|
bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface) {
|
||||||
for (uint32_t i = 0; i < type->GetInterfaceCount(); i++) {
|
for (uint32_t i = 0; i < type->GetInterfaceCount(); i++) {
|
||||||
if (type->GetInterface(i) == iface)
|
if (type->GetInterface(i) == iface)
|
||||||
return true;
|
return true;
|
||||||
@ -61,5 +60,5 @@ namespace Deer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace AngelScriptEngine
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -3,31 +3,66 @@
|
|||||||
#include "angelscript.h"
|
#include "angelscript.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace AngelScriptEngine {
|
namespace Scripting {
|
||||||
const char* getAngelScriptReturnCodeString(int code);
|
const char* getAngelScriptReturnCodeString(int code);
|
||||||
bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface);
|
bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface);
|
||||||
}
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
|
|
||||||
|
#define REGISTER_GLOBAL_FUNC(scriptEngine, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterGlobalFunction( \
|
||||||
|
funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL))
|
||||||
|
|
||||||
|
#define REGISTER_OBJECT_METHOD(scriptEngine, clasdef, funcdef, clas, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asMETHOD(clas, func), asCALL_THISCALL))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_METHOD(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectMethod( \
|
||||||
|
clasdef, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_GENERIC))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_CONSTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_DESTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_DESTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
|
#define REGISTER_EXT_OBJECT_DESTRUCTOR(scriptEngine, clasdef, funcdef, func) \
|
||||||
|
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
|
||||||
|
clasdef, asBEHAVE_DESTRUCT, funcdef, \
|
||||||
|
asFUNCTION(func), asCALL_CDECL_OBJLAST))
|
||||||
|
|
||||||
#define AS_CHECK(f) \
|
#define AS_CHECK(f) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::AngelScriptEngine::getAngelScriptReturnCodeString(__r)); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define AS_CHECK_ADDITIONAL_INFO(f, i) \
|
#define AS_CHECK_ADDITIONAL_INFO(f, i) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::AngelScriptEngine::getAngelScriptReturnCodeString(__r), i); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r), i); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define AS_RET_CHECK(f) \
|
#define AS_RET_CHECK(f) \
|
||||||
{ \
|
{ \
|
||||||
int __r = f; \
|
int __r = f; \
|
||||||
if (__r < 0) { \
|
if (__r < 0) { \
|
||||||
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::AngelScriptEngine::getAngelScriptReturnCodeString(__r)); \
|
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
#include "DeerStudio/StudioAPI/Engine.h"
|
#include "DeerCore/Scripting/InternalAPI/Engine.h"
|
||||||
#include "DeerRender/Tools/Path.h"
|
#include "DeerRender/Tools/Path.h"
|
||||||
#include "DeerStudio/AngelScriptEngine.h"
|
|
||||||
|
|
||||||
#include "angelscript.h"
|
#include "angelscript.h"
|
||||||
#include "scriptarray.h"
|
#include "scriptarray.h"
|
||||||
@ -9,7 +8,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace StudioAPI {
|
namespace Scripting {
|
||||||
|
extern asIScriptEngine* scriptEngine;
|
||||||
|
|
||||||
std::string getParentPath(std::string& path) {
|
std::string getParentPath(std::string& path) {
|
||||||
return Path(path).parent_path().string();
|
return Path(path).parent_path().string();
|
||||||
}
|
}
|
||||||
@ -23,7 +24,8 @@ namespace Deer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CScriptArray* dividePath_angelscript(std::string& path_s) {
|
CScriptArray* dividePath_angelscript(std::string& path_s) {
|
||||||
CScriptArray* array = CScriptArray::Create(AngelScriptEngine::arrayStringBaseType);
|
asITypeInfo* arrayStringType = scriptEngine->GetTypeInfoByDecl("array<string>");
|
||||||
|
CScriptArray* array = CScriptArray::Create(arrayStringType);
|
||||||
|
|
||||||
Path path_p(path_s);
|
Path path_p(path_s);
|
||||||
for (const auto& part : path_p) {
|
for (const auto& part : path_p) {
|
||||||
@ -35,5 +37,5 @@ namespace Deer {
|
|||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
} // namespace StudioAPI
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -4,11 +4,10 @@
|
|||||||
class CScriptArray;
|
class CScriptArray;
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace StudioAPI {
|
namespace Scripting {
|
||||||
// ANGELSCRIPT SPECIFIC
|
|
||||||
CScriptArray* dividePath_angelscript(std::string&);
|
CScriptArray* dividePath_angelscript(std::string&);
|
||||||
std::string getParentPath(std::string&);
|
std::string getParentPath(std::string&);
|
||||||
std::string getParentPathName(std::string&);
|
std::string getParentPathName(std::string&);
|
||||||
std::string getPathName(std::string&);
|
std::string getPathName(std::string&);
|
||||||
} // namespace StudioAPI
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
265
Deer/src/DeerCore/Scripting/InternalAPI/Entity.cpp
Normal file
265
Deer/src/DeerCore/Scripting/InternalAPI/Entity.cpp
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
#include "DeerCore/Scripting/InternalAPI/Entity.h"
|
||||||
|
#include "DeerCore/Scripting/ScriptEnvironmentContextData.h"
|
||||||
|
|
||||||
|
#include "DeerCore/EntityEnviroment.h"
|
||||||
|
#include "angelscript.h"
|
||||||
|
#include "scriptarray.h"
|
||||||
|
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
#include "DeerRender/Mesh.h"
|
||||||
|
#include "DeerRender/Shader.h"
|
||||||
|
#include "DeerRender/Texture.h"
|
||||||
|
#include "DeerRender/World.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Scripting {
|
||||||
|
extern asIScriptEngine* scriptEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity& Scripting::getContextEntity(EntityHandle handle) {
|
||||||
|
asIScriptContext* context = asGetActiveContext();
|
||||||
|
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
|
||||||
|
|
||||||
|
return environmentData->world->entityEnvironment->getEntity(handle.entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityEnvironment& Scripting::getContextEntityEnvironment(EntityHandle handle) {
|
||||||
|
asIScriptContext* context = asGetActiveContext();
|
||||||
|
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
|
||||||
|
|
||||||
|
return *environmentData->world->entityEnvironment.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& Scripting::getContextEntityComponent(EntityHandle handle) {
|
||||||
|
asIScriptContext* context = asGetActiveContext();
|
||||||
|
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
|
||||||
|
|
||||||
|
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityHandle Scripting::entity_getSelf(EntityHandle& handle) {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Scripting::entity_getName(EntityHandle& handle) {
|
||||||
|
return getContextEntity(handle).getComponent<TagComponent>().tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scripting::entity_getId(EntityHandle& handle) {
|
||||||
|
return handle.entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_setName(std::string& name, EntityHandle& handle) {
|
||||||
|
getContextEntity(handle).getComponent<TagComponent>().tag = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scripting::entity_exists(EntityHandle& handle) {
|
||||||
|
return getContextEntityEnvironment(handle).entityExists(handle.entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scripting::entity_isRoot(EntityHandle& handle) {
|
||||||
|
return handle.entityId == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_destroy(EntityHandle& handle) {
|
||||||
|
getContextEntity(handle).destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 Scripting::entity_getWorldMatrix(EntityHandle& handle) {
|
||||||
|
Entity& entity = getContextEntity(handle);
|
||||||
|
return entity.getWorldMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scripting::entity_getNetworkBehaviour(EntityHandle& handle) {
|
||||||
|
return (int)getContextEntityComponent<TagComponent>(handle).networkBehaviour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_setNetworkBehaviour(int value, EntityHandle& handle) {
|
||||||
|
getContextEntityComponent<TagComponent>(handle).networkBehaviour = (EntityNetworkBehaviour)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scripting::entity_getForcedNetworkBehaviour(EntityHandle& handle) {
|
||||||
|
return (int)getContextEntity(handle).getForcedNetworkBehaviour();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scripting::entity_isValidNetworkBehaviour(EntityHandle& handle) {
|
||||||
|
return getContextEntity(handle).isValidNetworkBehaviour();
|
||||||
|
}
|
||||||
|
|
||||||
|
CScriptArray* Scripting::entity_getChildrens(EntityHandle& handle) {
|
||||||
|
Entity& entity = getContextEntity(handle);
|
||||||
|
|
||||||
|
asITypeInfo* arrayStringType = scriptEngine->GetTypeInfoByDecl("array<Entity>");
|
||||||
|
CScriptArray* array = CScriptArray::Create(arrayStringType);
|
||||||
|
|
||||||
|
RelationshipComponent& relationship = entity.getComponent<RelationshipComponent>();
|
||||||
|
size_t childCount = relationship.getChildCount();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < childCount; i++) {
|
||||||
|
EntityHandle entity(relationship.getChildId(i));
|
||||||
|
|
||||||
|
array->Resize(array->GetSize() + 1);
|
||||||
|
array->SetValue(array->GetSize() - 1, &entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityHandle Scripting::entity_createChild(std::string& childName, EntityHandle& handle) {
|
||||||
|
Entity& child = getContextEntityEnvironment(handle).createEntity();
|
||||||
|
Entity& self = getContextEntity(handle);
|
||||||
|
|
||||||
|
child.setParent(self);
|
||||||
|
child.getComponent<TagComponent>().tag = childName;
|
||||||
|
return EntityHandle(child.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_setParent(EntityHandle other_handle, EntityHandle& self_handle) {
|
||||||
|
Entity& child = getContextEntity(other_handle);
|
||||||
|
Entity& self = getContextEntity(self_handle);
|
||||||
|
|
||||||
|
self.setParent(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityHandle Scripting::entity_getParent(EntityHandle& handle) {
|
||||||
|
return EntityHandle(getContextEntity(handle).getParentId());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scripting::entity_isDescendantOf(EntityHandle other_handle, EntityHandle& self_handle) {
|
||||||
|
Entity& child = getContextEntity(other_handle);
|
||||||
|
Entity& self = getContextEntity(self_handle);
|
||||||
|
|
||||||
|
return self.isDescendantOf(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scripting::entity_opEquals(EntityHandle& other, EntityHandle& self_handle) {
|
||||||
|
return other.entityId == self_handle.entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_addGenericComponent(asIScriptGeneric* generic) {
|
||||||
|
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
|
||||||
|
std::string componentName = componentType->GetName();
|
||||||
|
|
||||||
|
EntityHandle handle = *(EntityHandle*)generic->GetObject();
|
||||||
|
Entity& self_entity = getContextEntity(handle);
|
||||||
|
|
||||||
|
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
|
||||||
|
*return_handle = handle;
|
||||||
|
|
||||||
|
if (componentName == "TransformComponent") {
|
||||||
|
self_entity.addComponent<TransformComponent>();
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
} else if (componentName == "MeshComponent") {
|
||||||
|
self_entity.addComponent<MeshComponent>();
|
||||||
|
} else if (componentName == "CameraComponent") {
|
||||||
|
self_entity.addComponent<CameraComponent>();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_removeGenericComponent(asIScriptGeneric* generic) {
|
||||||
|
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
|
||||||
|
std::string componentName = componentType->GetName();
|
||||||
|
|
||||||
|
EntityHandle handle = *(EntityHandle*)generic->GetObject();
|
||||||
|
Entity& self_entity = getContextEntity(handle);
|
||||||
|
|
||||||
|
if (componentName == "TransformComponent") {
|
||||||
|
self_entity.removeComponent<TransformComponent>();
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
} else if (componentName == "MeshComponent") {
|
||||||
|
self_entity.removeComponent<MeshComponent>();
|
||||||
|
} else if (componentName == "CameraComponent") {
|
||||||
|
self_entity.removeComponent<CameraComponent>();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_getGenericComponent(asIScriptGeneric* generic) {
|
||||||
|
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
|
||||||
|
std::string componentName = componentType->GetName();
|
||||||
|
|
||||||
|
EntityHandle handle = *(EntityHandle*)generic->GetObject();
|
||||||
|
Entity& self_entity = getContextEntity(handle);
|
||||||
|
|
||||||
|
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
|
||||||
|
*return_handle = handle;
|
||||||
|
|
||||||
|
if (componentName == "TransformComponent") {
|
||||||
|
// Some checks
|
||||||
|
} else if (componentName == "MeshComponent") {
|
||||||
|
// Some checks
|
||||||
|
} else if (componentName == "CameraComponent") {
|
||||||
|
// Some checks
|
||||||
|
} else {
|
||||||
|
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::entity_hasGenericComponent(asIScriptGeneric* generic) {
|
||||||
|
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
|
||||||
|
std::string componentName = componentType->GetName();
|
||||||
|
|
||||||
|
EntityHandle handle = *(EntityHandle*)generic->GetObject();
|
||||||
|
Entity& self_entity = getContextEntity(handle);
|
||||||
|
|
||||||
|
if (componentName == "TransformComponent") {
|
||||||
|
generic->SetReturnByte(self_entity.hasComponent<TransformComponent>());
|
||||||
|
#ifdef DEER_RENDER
|
||||||
|
} else if (componentName == "MeshComponent") {
|
||||||
|
generic->SetReturnByte(self_entity.hasComponent<MeshComponent>());
|
||||||
|
} else if (componentName == "CameraComponent") {
|
||||||
|
generic->SetReturnByte(self_entity.hasComponent<CameraComponent>());
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SPECIFIC TRANSFORM SECTION
|
||||||
|
glm::vec3 Scripting::transform_getPosition(EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
return transformComponent.position;
|
||||||
|
}
|
||||||
|
glm::vec3 Scripting::transform_getScale(EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
return transformComponent.scale;
|
||||||
|
}
|
||||||
|
glm::quat Scripting::transform_getRotation(EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
return transformComponent.rotation;
|
||||||
|
}
|
||||||
|
glm::vec3 Scripting::transform_getEuler(EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
return transformComponent.getEulerAngles();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::transform_setPosition(glm::vec3 position, EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
transformComponent.position = position;
|
||||||
|
}
|
||||||
|
void Scripting::transform_setScale(glm::vec3 scale, EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
transformComponent.scale = scale;
|
||||||
|
}
|
||||||
|
void Scripting::transform_setRotation(glm::quat rotation, EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
transformComponent.rotation = rotation;
|
||||||
|
}
|
||||||
|
void Scripting::transform_setEuler(glm::vec3 rotation, EntityHandle& handle) {
|
||||||
|
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
|
||||||
|
transformComponent.setEulerAngles(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::constructEntityStruct(void* memory) {
|
||||||
|
new (memory) EntityHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::destructEntityStruct(void* memory) {}
|
||||||
|
} // namespace Deer
|
||||||
67
Deer/src/DeerCore/Scripting/InternalAPI/Entity.h
Normal file
67
Deer/src/DeerCore/Scripting/InternalAPI/Entity.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class asIScriptGeneric;
|
||||||
|
class CScriptArray;
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
class Entity;
|
||||||
|
class EntityEnvironment;
|
||||||
|
|
||||||
|
struct EntityHandle {
|
||||||
|
uint32_t entityId;
|
||||||
|
EntityHandle(uint32_t _id = 0) : entityId(_id) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Scripting {
|
||||||
|
// SPECIFIC ENTITY SECTION
|
||||||
|
Entity& getContextEntity(EntityHandle);
|
||||||
|
EntityEnvironment& getContextEntityEnvironment(EntityHandle);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& getContextEntityComponent(EntityHandle handle);
|
||||||
|
|
||||||
|
EntityHandle entity_getSelf(EntityHandle&);
|
||||||
|
std::string entity_getName(EntityHandle&);
|
||||||
|
int entity_getId(EntityHandle&);
|
||||||
|
void entity_setName(std::string&, EntityHandle&);
|
||||||
|
bool entity_exists(EntityHandle&);
|
||||||
|
bool entity_isRoot(EntityHandle&);
|
||||||
|
void entity_destroy(EntityHandle&);
|
||||||
|
CScriptArray* entity_getChildrens(EntityHandle&);
|
||||||
|
|
||||||
|
glm::mat4 entity_getWorldMatrix(EntityHandle&);
|
||||||
|
|
||||||
|
int entity_getNetworkBehaviour(EntityHandle&);
|
||||||
|
void entity_setNetworkBehaviour(int, EntityHandle&);
|
||||||
|
int entity_getForcedNetworkBehaviour(EntityHandle&);
|
||||||
|
bool entity_isValidNetworkBehaviour(EntityHandle&);
|
||||||
|
|
||||||
|
EntityHandle entity_createChild(std::string&, EntityHandle&);
|
||||||
|
void entity_setParent(EntityHandle, EntityHandle&);
|
||||||
|
EntityHandle entity_getParent(EntityHandle&);
|
||||||
|
|
||||||
|
bool entity_isDescendantOf(EntityHandle, EntityHandle&);
|
||||||
|
bool entity_opEquals(EntityHandle& other, EntityHandle&);
|
||||||
|
|
||||||
|
void entity_addGenericComponent(asIScriptGeneric* generic);
|
||||||
|
void entity_removeGenericComponent(asIScriptGeneric* generic);
|
||||||
|
void entity_getGenericComponent(asIScriptGeneric* generic);
|
||||||
|
void entity_hasGenericComponent(asIScriptGeneric* generic);
|
||||||
|
|
||||||
|
// SPECIFIC TRANSFORM SECTION
|
||||||
|
glm::vec3 transform_getPosition(EntityHandle&);
|
||||||
|
glm::vec3 transform_getScale(EntityHandle&);
|
||||||
|
glm::quat transform_getRotation(EntityHandle&);
|
||||||
|
glm::vec3 transform_getEuler(EntityHandle&);
|
||||||
|
void transform_setPosition(glm::vec3, EntityHandle&);
|
||||||
|
void transform_setScale(glm::vec3, EntityHandle&);
|
||||||
|
void transform_setRotation(glm::quat, EntityHandle&);
|
||||||
|
void transform_setEuler(glm::vec3, EntityHandle&);
|
||||||
|
|
||||||
|
void constructEntityStruct(void* memory);
|
||||||
|
void destructEntityStruct(void* memory);
|
||||||
|
} // namespace Scripting
|
||||||
|
} // namespace Deer
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
#include "DeerCore/Scripting/InternalAPI/InternalFunctions.h"
|
||||||
|
#include "DeerRender/Log.h"
|
||||||
|
#include "angelscript.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
void Scripting::errorCallback_angelscript(const asSMessageInfo* msg, void* param) {
|
||||||
|
if (msg->type == asMSGTYPE_WARNING) {
|
||||||
|
DEER_EDITOR_ENGINE_WARN("{0}:{1}:{2} : {3}", msg->section, msg->row, msg->col, msg->message);
|
||||||
|
} else if (msg->type == asMSGTYPE_INFORMATION) {
|
||||||
|
DEER_EDITOR_ENGINE_INFO("{0}:{1}:{2} : {3}", msg->section, msg->row, msg->col, msg->message);
|
||||||
|
} else if (msg->type == asMSGTYPE_ERROR) {
|
||||||
|
DEER_EDITOR_ENGINE_ERROR("{0}:{1}:{2} : {3}", msg->section, msg->row, msg->col, msg->message);
|
||||||
|
} else {
|
||||||
|
DEER_EDITOR_ENGINE_INFO("{0}:{1}:{2} : {3}", msg->section, msg->row, msg->col, msg->message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scripting::print(std::string& msg) {
|
||||||
|
DEER_EDITOR_ENGINE_INFO("{0}", msg.c_str());
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "string"
|
struct asSMessageInfo;
|
||||||
|
|
||||||
class asSMessageInfo;
|
#include <string>
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace StudioAPI {
|
namespace Scripting {
|
||||||
void errorCallback_angelscript(const asSMessageInfo* msg, void* param);
|
void errorCallback_angelscript(const asSMessageInfo* msg, void* param);
|
||||||
void print(std::string& msg);
|
void print(std::string& msg);
|
||||||
} // namespace StudioAPI
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
104
Deer/src/DeerCore/Scripting/InternalAPI/Math.cpp
Normal file
104
Deer/src/DeerCore/Scripting/InternalAPI/Math.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include "DeerCore/Scripting/InternalAPI/Math.h"
|
||||||
|
#include "glm/glm.hpp"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Scripting {
|
||||||
|
void vec3_constructor(void* mem) {
|
||||||
|
new (mem) glm::vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat4_constructor(void* mem) {
|
||||||
|
new (mem) glm::mat4(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 mat4_getRelativeMatrix(glm::mat4& other, glm::mat4& self) {
|
||||||
|
return glm::inverse(other) * self;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 mat4_getPosition(glm::mat4& matrix) {
|
||||||
|
return glm::vec3(matrix[3][0], matrix[3][1], matrix[3][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat mat4_getRotation(glm::mat4& m) {
|
||||||
|
glm::vec3 scale = mat4_getScale(m);
|
||||||
|
|
||||||
|
// Avoid division by zero
|
||||||
|
glm::mat3 rotationMatrix;
|
||||||
|
rotationMatrix[0] = glm::vec3(m[0]) / scale.x;
|
||||||
|
rotationMatrix[1] = glm::vec3(m[1]) / scale.y;
|
||||||
|
rotationMatrix[2] = glm::vec3(m[2]) / scale.z;
|
||||||
|
|
||||||
|
return glm::quat_cast(rotationMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 mat4_getScale(glm::mat4& m) {
|
||||||
|
glm::vec3 scale;
|
||||||
|
|
||||||
|
scale.x = glm::length(glm::vec3(m[0]));
|
||||||
|
scale.y = glm::length(glm::vec3(m[1]));
|
||||||
|
scale.z = glm::length(glm::vec3(m[2]));
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vec3_constructor_params(float x, float y, float z, void* mem) {
|
||||||
|
new (mem) glm::vec3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 vec3_add(glm::vec3& value, glm::vec3& self) {
|
||||||
|
return self + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 vec3_sub(const glm::vec3& value, glm::vec3& self) {
|
||||||
|
return self - value;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 vec3_neg(glm::vec3& self) {
|
||||||
|
return -self;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 vec3_mult(float value, glm::vec3& self) {
|
||||||
|
return self * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void quat_construct(glm::quat* mem) {
|
||||||
|
new (mem) glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void quat_copyConstruct(glm::quat* data, glm::quat* mem) {
|
||||||
|
new (mem) glm::quat(*data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void quat_constructFromValue(float x, float y, float z, float w, glm::quat* mem) {
|
||||||
|
new (mem) glm::quat(x, y, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 quat_getEuler(glm::quat* mem) {
|
||||||
|
return glm::degrees(glm::eulerAngles(*mem));
|
||||||
|
}
|
||||||
|
|
||||||
|
void quat_setEuler(glm::vec3 euler, glm::quat* mem) {
|
||||||
|
new (mem) glm::quat(glm::radians(euler));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat quat_multiply(glm::quat* data, glm::quat* mem) {
|
||||||
|
return *mem * *data;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 transform_relative(glm::vec3 pos, TransformComponent* transform) {
|
||||||
|
return transform->getMatrix() * glm::vec4(pos, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform_construct(TransformComponent* mem) {
|
||||||
|
new (mem) TransformComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void camera_construct(CameraComponent* mem) {
|
||||||
|
new (mem) CameraComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sceneCamera_Construct(WorldCamera* mem) {
|
||||||
|
new (mem) WorldCamera();
|
||||||
|
}
|
||||||
|
} // namespace Scripting
|
||||||
|
} // namespace Deer
|
||||||
@ -3,13 +3,19 @@
|
|||||||
#include "glm/gtc/quaternion.hpp"
|
#include "glm/gtc/quaternion.hpp"
|
||||||
|
|
||||||
#include "DeerRender/Components.h"
|
#include "DeerRender/Components.h"
|
||||||
#include "DeerRender/Scene.h"
|
#include "DeerRender/World.h"
|
||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
namespace StudioAPI {
|
namespace Scripting {
|
||||||
void vec3_constructor(void*);
|
void vec3_constructor(void*);
|
||||||
void vec3_constructor_params(float, float, float, void*);
|
void vec3_constructor_params(float, float, float, void*);
|
||||||
|
|
||||||
|
void mat4_constructor(void*);
|
||||||
|
glm::mat4 mat4_getRelativeMatrix(glm::mat4&, glm::mat4&);
|
||||||
|
glm::vec3 mat4_getPosition(glm::mat4&);
|
||||||
|
glm::quat mat4_getRotation(glm::mat4&);
|
||||||
|
glm::vec3 mat4_getScale(glm::mat4&);
|
||||||
|
|
||||||
glm::vec3 vec3_add(glm::vec3&, glm::vec3&);
|
glm::vec3 vec3_add(glm::vec3&, glm::vec3&);
|
||||||
glm::vec3 vec3_sub(const glm::vec3&, glm::vec3&);
|
glm::vec3 vec3_sub(const glm::vec3&, glm::vec3&);
|
||||||
glm::vec3 vec3_neg(glm::vec3&);
|
glm::vec3 vec3_neg(glm::vec3&);
|
||||||
@ -17,7 +23,6 @@ namespace Deer {
|
|||||||
|
|
||||||
void quat_construct(glm::quat*);
|
void quat_construct(glm::quat*);
|
||||||
void quat_copyConstruct(glm::quat*, glm::quat*);
|
void quat_copyConstruct(glm::quat*, glm::quat*);
|
||||||
void quat_destruct(glm::quat*);
|
|
||||||
void quat_constructFromValue(float, float, float, float, glm::quat*);
|
void quat_constructFromValue(float, float, float, float, glm::quat*);
|
||||||
|
|
||||||
glm::vec3 quat_getEuler(glm::quat*);
|
glm::vec3 quat_getEuler(glm::quat*);
|
||||||
@ -26,10 +31,10 @@ namespace Deer {
|
|||||||
|
|
||||||
void transform_construct(TransformComponent*);
|
void transform_construct(TransformComponent*);
|
||||||
void camera_construct(CameraComponent*);
|
void camera_construct(CameraComponent*);
|
||||||
void sceneCamera_Construct(SceneCamera*);
|
void sceneCamera_Construct(WorldCamera*);
|
||||||
|
|
||||||
glm::vec3 transform_relative(glm::vec3, TransformComponent*);
|
glm::vec3 transform_relative(glm::vec3, TransformComponent*);
|
||||||
|
|
||||||
void emptyDestructor();
|
void emptyDestructor();
|
||||||
} // namespace StudioAPI
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user