Mesh format working

This commit is contained in:
Arnau Alier Torres 2025-04-24 17:51:15 +02:00
parent 769cc6842f
commit 423e41efda
22 changed files with 466 additions and 2844 deletions

View File

@ -13,33 +13,68 @@ namespace Deer {
struct PositionAxis { struct PositionAxis {
uint8_t integerPart = 0; uint8_t integerPart = 0;
uint8_t decimalPart = 0; uint8_t decimalPart = 0;
PositionAxis() = default;
PositionAxis(uint8_t ip, uint8_t dp)
: integerPart(ip), decimalPart(dp) {}
}; };
struct VertexPosition { struct VertexPosition {
PositionAxis x; PositionAxis x;
PositionAxis y; PositionAxis y;
PositionAxis z; PositionAxis z;
VertexPosition() = default;
VertexPosition(PositionAxis _x, PositionAxis _y, PositionAxis _z)
: x(_x), y(_y), z(_z) {}
}; };
// Vertex normal is represented with a number fromn [-64,64], and then its // Vertex normal is represented with a number fromn [-64,64], and then its
// divided by 64 to know the decimal number // divided by 64 to know the decimal number
struct VertexNormal { struct VertexNormal {
int8_t x; int8_t x = 0;
int8_t y; int8_t y = 0;
int8_t z; int8_t z = 0;
VertexNormal() = default;
VertexNormal(int8_t _x, int8_t _y, int8_t _z) : x(_x), y(_y), z(_z) {}
}; };
struct ModelData { struct MeshData {
uint16_t vertexCount = 0; uint16_t vertexCount = 0;
VertexPosition* vertexPositionsData = nullptr; VertexPosition* vertexPositionsData = nullptr;
VertexNormal* vertexNormalData = nullptr; VertexNormal* vertexNormalData = nullptr;
uint16_t indexCount = 0; uint16_t indexCount = 0;
uint16_t* indexData = nullptr; uint16_t* indexData = nullptr;
MeshData() = default;
~MeshData() {
delete[] vertexPositionsData;
delete[] vertexNormalData;
delete[] indexData;
}
MeshData(const MeshData&) = delete;
MeshData& operator=(const MeshData&) = delete;
void freeData() {
delete[] vertexPositionsData;
vertexPositionsData = nullptr;
delete[] vertexNormalData;
vertexNormalData = nullptr;
delete[] indexData;
indexData = nullptr;
vertexCount = 0;
indexCount = 0;
}
}; };
namespace DataStore { namespace DataStore {
void saveModel(const ModelData&, const Path& name); void saveModel(const MeshData&, const Path& name);
ModelData loadModel(const Path& name); void loadModel(MeshData&, const Path& name);
void saveBinModel(const MeshData&, const Path& name);
void createExampleMeshData();
} // namespace DataStore } // namespace DataStore
} // namespace Deer } // namespace Deer

View File

@ -8,7 +8,6 @@
#include "cereal/archives/portable_binary.hpp" #include "cereal/archives/portable_binary.hpp"
namespace Deer { namespace Deer {
void DataStore::loadScene(Scene& scene, const Path& name) { void DataStore::loadScene(Scene& scene, const Path& name) {
Path realName; Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn"); realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");
@ -26,6 +25,7 @@ namespace Deer {
delete[] data; delete[] data;
} }
void DataStore::exportScene(const Scene& scene, const Path& name) { void DataStore::exportScene(const Scene& scene, const Path& name) {
Path realName; Path realName;
realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn"); realName = Path(DEER_SCENE_PATH) / (name.string() + ".dscn");

View File

@ -1,7 +1,56 @@
#include "Deer/DataStore.h"
#include "DeerRender/Mesh.h" #include "DeerRender/Mesh.h"
#include "DeerRender/Mesh/Serialization/MeshDataSerialization.h"
#include "cereal/archives/json.hpp" #include "cereal/archives/json.hpp"
#include "cereal/archives/portable_binary.hpp"
#include "cereal/cereal.hpp" #include "cereal/cereal.hpp"
namespace Deer { namespace Deer {
ModelData DataStore::loadModel(const Path& name) {} void DataStore::loadModel(MeshData& meshData, const Path& name) {
Path realName;
realName = Path(DEER_MESH_PATH) / (name.string() + ".dmesh");
uint32_t size;
uint8_t* data = DataStore::readFile(realName, &size);
std::string strData((char*)data, size);
std::istringstream stream(strData);
meshData.freeData();
{
cereal::JSONInputArchive archive(stream);
archive(cereal::make_nvp("mesh", meshData));
}
delete[] data;
}
void DataStore::saveModel(const MeshData& meshData, const Path& name) {
Path realName;
realName = Path(DEER_MESH_PATH) / (name.string() + ".dmesh");
std::stringstream output;
{
cereal::JSONOutputArchive archive(output);
archive(cereal::make_nvp("mesh", meshData));
}
std::string_view view = output.view();
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
void DataStore::saveBinModel(const MeshData& meshData, const Path& name) {
Path realName;
realName = Path(DEER_MESH_PATH) / (name.string() + ".dbmesh");
std::stringstream output;
{
cereal::PortableBinaryOutputArchive archive(output);
archive(cereal::make_nvp("mesh", meshData));
}
std::string_view view = output.view();
DataStore::saveFile(realName, (uint8_t*)view.data(), view.size());
}
} // namespace Deer } // namespace Deer

View File

@ -0,0 +1,26 @@
#include "DeerRender/Mesh.h"
namespace Deer {
void DataStore::createExampleMeshData() {
MeshData meshData;
meshData.vertexCount = 3;
// Triangle
meshData.vertexPositionsData = new VertexPosition[3]{
VertexPosition(PositionAxis(0 + 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 + 128, 0)),
VertexPosition(PositionAxis(0 + 128, 64), PositionAxis(0 + 128, 0),
PositionAxis(1 + 128, 0)),
VertexPosition(PositionAxis(1 + 128, 0), PositionAxis(0 + 128, 0),
PositionAxis(0 + 128, 0))};
meshData.vertexNormalData =
new VertexNormal[3]{VertexNormal(0, 64, 0), VertexNormal(0, 64, 0),
VertexNormal(0, 64, 0)};
meshData.indexCount = 3;
meshData.indexData = new uint16_t[3]{0, 1, 2};
DataStore::saveModel(meshData, "exampleTriangle");
DataStore::saveBinModel(meshData, "exampleTriangle");
}
} // namespace Deer

View File

@ -0,0 +1,92 @@
#pragma once
#include <cstdint>
#include "Deer/Log.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Mesh/Serialization/VertexNormalSerialization.h"
#include "DeerRender/Mesh/Serialization/VertexPositionSerialization.h"
#include "cereal/cereal.hpp"
namespace Deer {
template <class T>
struct SerializationArray {
T* data;
size_t size;
SerializationArray(T* _data, size_t _size) : data(_data), size(_size) {}
SerializationArray() = default;
template <class Archive>
void save(Archive& archive) const {
archive(cereal::make_size_tag(size));
for (size_t i = 0; i < size; i++) archive(data[i]);
}
template <class Archive>
void load(Archive& archive) {
archive(cereal::make_size_tag(size));
data = new T[size];
for (size_t i = 0; i < size; i++) archive(data[i]);
}
};
template <class Archive>
void save(Archive& archive, const MeshData& meshData) {
const bool hasNormalData = meshData.vertexNormalData != nullptr;
const size_t vertexCount = meshData.vertexCount;
const size_t indexCount = meshData.indexCount;
// GLOBAL VARS
archive(cereal::make_nvp("hasNormalData", hasNormalData));
// VERTEX POSITION
SerializationArray<VertexPosition> vertexPositionsArray(
meshData.vertexPositionsData, vertexCount);
archive(cereal::make_nvp("vertexPositions", vertexPositionsArray));
// VERTEX NORMAL
if (hasNormalData) {
SerializationArray<VertexNormal> vertexNormalArray(
meshData.vertexNormalData, vertexCount);
archive(cereal::make_nvp("vertexNormals", vertexNormalArray));
if (indexCount != vertexNormalArray.size) {
DEER_CORE_ERROR(
"Error while loading mesh, vertex normal array is not the "
"same lenght as vertex positions");
}
}
// INDICES
SerializationArray<uint16_t> indexArray(meshData.indexData, indexCount);
archive(cereal::make_nvp("indices", indexArray));
}
template <class Archive>
void load(Archive& archive, MeshData& meshData) {
bool hasNormalData;
size_t vertexCount;
size_t indexCount;
// GLOBAL VARS
archive(cereal::make_nvp("hasNormalData", hasNormalData));
// VERTEX POSITION
SerializationArray<VertexPosition> vertexPositionsArray;
archive(cereal::make_nvp("vertexPositions", vertexPositionsArray));
meshData.vertexPositionsData = vertexPositionsArray.data;
meshData.vertexCount = vertexPositionsArray.size;
// VERTEX NORMAL
if (hasNormalData) {
SerializationArray<VertexNormal> vertexNormalArray;
archive(cereal::make_nvp("vertexNormals", vertexNormalArray));
meshData.vertexNormalData = vertexNormalArray.data;
}
// INDICES
SerializationArray<uint16_t> indexArray;
archive(cereal::make_nvp("indices", indexArray));
meshData.indexData = indexArray.data;
meshData.indexCount = indexArray.size;
}
} // namespace Deer

View File

@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include "DeerRender/Mesh.h"
#include "cereal/cereal.hpp"
namespace Deer {
template <class Archive>
void serialize(Archive& archive, VertexNormal& vertexNormal) {
archive(cereal::make_nvp("x", vertexNormal.x));
archive(cereal::make_nvp("y", vertexNormal.y));
archive(cereal::make_nvp("z", vertexNormal.z));
}
} // namespace Deer

View File

@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include "DeerRender/Mesh.h"
#include "cereal/cereal.hpp"
namespace Deer {
template <class Archive>
void serialize(Archive& archive, PositionAxis& positionAxis) {
archive(cereal::make_nvp("int", positionAxis.integerPart));
archive(cereal::make_nvp("dec", positionAxis.decimalPart));
}
template <class Archive>
void serialize(Archive& archive, VertexPosition& vertexPosition) {
archive(cereal::make_nvp("x", vertexPosition.x));
archive(cereal::make_nvp("y", vertexPosition.y));
archive(cereal::make_nvp("z", vertexPosition.z));
}
} // namespace Deer

View File

@ -7,6 +7,7 @@
#include "Deer/ScriptEngine.h" #include "Deer/ScriptEngine.h"
#include "Deer/Voxel.h" #include "Deer/Voxel.h"
#include "Deer/VoxelWorld.h" #include "Deer/VoxelWorld.h"
#include "DeerRender/Mesh.h"
#include "DeerStudio/Editor/Fonts.h" #include "DeerStudio/Editor/Fonts.h"
#include "DeerStudio/Editor/GamePannel.h" #include "DeerStudio/Editor/GamePannel.h"
#include "DeerStudio/Editor/Icons.h" #include "DeerStudio/Editor/Icons.h"
@ -25,16 +26,16 @@ namespace Deer {
if (projectPath.empty()) return 1; if (projectPath.empty()) return 1;
DataStore::rootPath = projectPath; DataStore::rootPath = projectPath;
VoxelData::createExampleVoxelData(); DataStore::createExampleVoxelData();
VoxelData::createExampleVoxelAspect(); DataStore::createExampleVoxelAspect();
VoxelData::loadVoxelsData(); DataStore::loadVoxelsData();
VoxelData::loadVoxelsAspect(); DataStore::loadVoxelsAspect();
return 0; return 0;
} }
int DeerStudioApplication::onInit() { int DeerStudioApplication::onInit() {
VoxelData::generateTextureAtlas(); DataStore::generateTextureAtlas();
VoxelData::loadVoxelsShaders(); DataStore::loadVoxelsShaders();
ScriptEngine::compileScriptEngine(DataStore::rootPath / ScriptEngine::compileScriptEngine(DataStore::rootPath /
std::filesystem::path("scripts")); std::filesystem::path("scripts"));
@ -52,11 +53,10 @@ namespace Deer {
setNatureStyle(); setNatureStyle();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
auto m_gamePannel = Ref<GamePannel>(new GamePannel()); auto m_gamePannel = Ref<GamePannel>(new GamePannel());
pannels.push_back(m_gamePannel); pannels.push_back(m_gamePannel);
DataStore::createExampleMeshData();
return 0; return 0;
} }
@ -168,21 +168,21 @@ namespace Deer {
if (ImGui::MenuItem("New scene")) { if (ImGui::MenuItem("New scene")) {
// TODO // TODO
Project::m_scene.clear(); Project::m_scene.clear();
SceneDataStore::exportScene(Project::m_scene, "new_scene"); DataStore::exportScene(Project::m_scene, "new_scene");
} }
// if (Project::m_sceneSerializer->getCurrentScenePath() != // if (Project::m_sceneSerializer->getCurrentScenePath() !=
// "_NO_INITIALIZED_" && ImGui::MenuItem("Save scene")) { // "_NO_INITIALIZED_" && ImGui::MenuItem("Save scene")) {
// Project::m_sceneSerializer->serialize(Project::m_sceneSerializer->getCurrentScenePath()); // Project::m_sceneSerializer->serialize(Project::m_sceneSerializer->getCurrentScenePath());
// } // }
if (ImGui::MenuItem("Save scene")) { if (ImGui::MenuItem("Save scene")) {
SceneDataStore::exportScene(Project::m_scene, "saved_scene"); DataStore::exportScene(Project::m_scene, "saved_scene");
} }
if (ImGui::MenuItem("Save scene as...")) { if (ImGui::MenuItem("Save scene as...")) {
// TODO // TODO
} }
if (ImGui::MenuItem("Load scene")) { if (ImGui::MenuItem("Load scene")) {
// Project::m_scene.swap(SceneDataStore::loadScene("new_scene")); // Project::m_scene.swap(DataStore::loadScene("new_scene"));
// SceneDataStore::exportScene(Project::m_scene, // DataStore::exportScene(Project::m_scene,
// "new_scene"); // "new_scene");
} }
if (ImGui::MenuItem("Scene settings")) { if (ImGui::MenuItem("Scene settings")) {

View File

@ -30,13 +30,13 @@ namespace Deer {
if (!Project::m_scene.getExecutingState()) { if (!Project::m_scene.getExecutingState()) {
if (ScriptEngine::isCompilationValid() && if (ScriptEngine::isCompilationValid() &&
ImGui::Button("Execute")) { ImGui::Button("Execute")) {
SceneDataStore::exportRuntimeScene(Project::m_scene); DataStore::exportRuntimeScene(Project::m_scene);
Project::m_scene.beginExecution(); Project::m_scene.beginExecution();
} }
} else { } else {
if (ImGui::Button("Stop")) { if (ImGui::Button("Stop")) {
Project::m_scene.endExecution(); Project::m_scene.endExecution();
SceneDataStore::importRuntimeScene(Project::m_scene); DataStore::importRuntimeScene(Project::m_scene);
} }
} }
@ -78,13 +78,13 @@ namespace Deer {
if (!Project::m_scene.getExecutingState()) { if (!Project::m_scene.getExecutingState()) {
if (ScriptEngine::isCompilationValid() && if (ScriptEngine::isCompilationValid() &&
ImGui::Button("Execute")) { ImGui::Button("Execute")) {
SceneDataStore::exportRuntimeScene(Project::m_scene); DataStore::exportRuntimeScene(Project::m_scene);
Project::m_scene.beginExecution(); Project::m_scene.beginExecution();
} }
} else { } else {
if (ImGui::Button("Stop")) { if (ImGui::Button("Stop")) {
Project::m_scene.endExecution(); Project::m_scene.endExecution();
SceneDataStore::importRuntimeScene(Project::m_scene); DataStore::importRuntimeScene(Project::m_scene);
} }
} }

View File

@ -8,17 +8,20 @@
namespace Deer { namespace Deer {
namespace MeshExplorer { namespace MeshExplorer {
Path m_meshExplorerPath(DEER_MESH_PATH); Path m_meshExplorerPath(DEER_NULL_PATH);
void drawFolder(const Path& path); void drawFolder(const Path& path);
} // namespace MeshExplorer } // namespace MeshExplorer
void MeshExplorer::onImGui() { void MeshExplorer::onImGui() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 10)); if (m_meshExplorerPath == DEER_NULL_PATH) {
ImGui::Begin("Mesh Explorer", (bool*)0, ImGuiWindowFlags_MenuBar); DataStore::createFolder(DataStore::rootPath / DEER_MESH_PATH);
ImGui::PopStyleVar(); m_meshExplorerPath = DEER_MESH_PATH;
}
ImGui::Text("%s", m_meshExplorerPath.generic_string().c_str()); ImGui::Begin("Mesh Explorer", (bool*)0); // ImGuiWindowFlags_MenuBar
DataStore::createFolder(DEER_MESH_PATH);
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "%s",
m_meshExplorerPath.generic_string().c_str());
setupColumns(ICON_MIN_SIZE + 80); setupColumns(ICON_MIN_SIZE + 80);
@ -34,8 +37,8 @@ namespace Deer {
ImGui::NextColumn(); ImGui::NextColumn();
} }
for (const auto& entry : for (const auto& entry : std::filesystem::directory_iterator(
std::filesystem::directory_iterator(m_meshExplorerPath)) { DataStore::rootPath / m_meshExplorerPath)) {
if (entry.is_directory()) if (entry.is_directory())
drawFolder(entry.path()); drawFolder(entry.path());
else { else {

View File

@ -3,7 +3,6 @@
#include "Deer/Asset.h" #include "Deer/Asset.h"
#include "Deer/ScriptEngine.h" #include "Deer/ScriptEngine.h"
#include "DeerRender/Input.h" #include "DeerRender/Input.h"
#include "DeerRender/KeyCodes.h"
#include "DeerRender/Render/Texture.h" #include "DeerRender/Render/Texture.h"
#include "DeerStudio/Editor/Fonts.h" #include "DeerStudio/Editor/Fonts.h"
#include "DeerStudio/Project.h" #include "DeerStudio/Project.h"

View File

@ -47,8 +47,8 @@ namespace Deer {
if (m_currentSceneName == "") if (m_currentSceneName == "")
ImGui::OpenPopup("SAVE_SCENE_NAME"); ImGui::OpenPopup("SAVE_SCENE_NAME");
else else
SceneDataStore::exportScene(Project::m_scene, DataStore::exportScene(Project::m_scene,
m_currentSceneName); m_currentSceneName);
} }
if (ImGui::MenuItem("Save as")) { if (ImGui::MenuItem("Save as")) {
@ -176,7 +176,7 @@ namespace Deer {
void saveSceneBeforeLoadingPopup() { void saveSceneBeforeLoadingPopup() {
if (ImGui::BeginPopup("SAVE_SCENE_BEFORE_LOADING")) { if (ImGui::BeginPopup("SAVE_SCENE_BEFORE_LOADING")) {
if (m_currentSceneName == "") { if (m_currentSceneName == "") {
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName); DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName; m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -195,14 +195,13 @@ namespace Deer {
if (save) { if (save) {
ActiveEntity::clear(); ActiveEntity::clear();
SceneDataStore::exportScene(Project::m_scene, DataStore::exportScene(Project::m_scene, m_currentSceneName);
m_currentSceneName); DataStore::loadScene(Project::m_scene, m_loadSceneName);
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName; m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} else if (dont_save) { } else if (dont_save) {
ActiveEntity::clear(); ActiveEntity::clear();
SceneDataStore::loadScene(Project::m_scene, m_loadSceneName); DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName; m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
@ -254,7 +253,7 @@ namespace Deer {
correctInput; correctInput;
m_currentSceneName = fullName; m_currentSceneName = fullName;
SceneDataStore::exportScene(Project::m_scene, fullName); DataStore::exportScene(Project::m_scene, fullName);
} }
} }
void saveBeforeCreatingNew(bool save) { void saveBeforeCreatingNew(bool save) {
@ -264,8 +263,7 @@ namespace Deer {
return; return;
} else { } else {
ActiveEntity::clear(); ActiveEntity::clear();
SceneDataStore::exportScene(Project::m_scene, DataStore::exportScene(Project::m_scene, m_currentSceneName);
m_currentSceneName);
Project::m_scene.clear(); Project::m_scene.clear();
m_currentSceneName = Path(); m_currentSceneName = Path();
} }
@ -287,7 +285,7 @@ namespace Deer {
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) / m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
correctInput; correctInput;
SceneDataStore::exportScene(Project::m_scene, fullName); DataStore::exportScene(Project::m_scene, fullName);
ActiveEntity::clear(); ActiveEntity::clear();
Project::m_scene.clear(); Project::m_scene.clear();
m_currentSceneName = Path(); m_currentSceneName = Path();

View File

@ -106,8 +106,8 @@ namespace Deer {
min.z = selectedVoxelStart.z; min.z = selectedVoxelStart.z;
} }
int debugVoxel = VoxelData::getVoxelID("debug"); int debugVoxel = DataStore::getVoxelID("debug");
int debugInternal = VoxelData::getVoxelID("debug_internal"); int debugInternal = DataStore::getVoxelID("debug_internal");
// External faces // External faces
// Z Face // Z Face

View File

@ -86,7 +86,7 @@ namespace Deer {
Project::m_scene.createVoxelWorld(props); Project::m_scene.createVoxelWorld(props);
Project::m_scene.getVoxelWorld().fillVoxels( Project::m_scene.getVoxelWorld().fillVoxels(
VoxelCordinates(0, 0, 0), VoxelCordinates(31, 8, 31), VoxelCordinates(0, 0, 0), VoxelCordinates(31, 8, 31),
Voxel(VoxelData::getVoxelID("wood"))); Voxel(DataStore::getVoxelID("wood")));
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }

View File

@ -43,7 +43,7 @@ namespace Deer {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
Project::m_scene.getMainGizmoRenderer().drawVoxelFace( Project::m_scene.getMainGizmoRenderer().drawVoxelFace(
clampedCordinates.x, clampedCordinates.y, clampedCordinates.z, clampedCordinates.x, clampedCordinates.y, clampedCordinates.z,
VoxelData::getVoxelID("debug"), i, 0); DataStore::getVoxelID("debug"), i, 0);
} }
if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) { if (ImGui::GetMouseClickedCount(ImGuiMouseButton_Left)) {

View File

@ -79,13 +79,13 @@ namespace Deer {
VoxelCordinates(), VoxelCordinates(),
VoxelCordinates(32 * worldProps.chunkSizeX - 1, 16, VoxelCordinates(32 * worldProps.chunkSizeX - 1, 16,
32 * worldProps.chunkSizeZ - 1), 32 * worldProps.chunkSizeZ - 1),
Voxel(VoxelData::getVoxelID("wood"))); Voxel(DataStore::getVoxelID("wood")));
Project::m_scene.getVoxelWorld().fillVoxels( Project::m_scene.getVoxelWorld().fillVoxels(
VoxelCordinates(1, 8, 1), VoxelCordinates(1, 8, 1),
VoxelCordinates(32 * worldProps.chunkSizeX - 2, 15, VoxelCordinates(32 * worldProps.chunkSizeX - 2, 15,
32 * worldProps.chunkSizeZ - 2), 32 * worldProps.chunkSizeZ - 2),
Voxel(VoxelData::getVoxelID("air"))); Voxel(DataStore::getVoxelID("air")));
} }
deleteInputPopup<deleteVoxelWorld>( deleteInputPopup<deleteVoxelWorld>(

View File

@ -1,103 +1,106 @@
#include "TerrainEditor.h"
#include "Deer/Voxel.h" #include "Deer/Voxel.h"
#include "DeerRender/VoxelAspect.h"
#include "DeerRender/Render/Texture.h" #include "DeerRender/Render/Texture.h"
#include "DeerRender/VoxelAspect.h"
#include "DeerStudio/Editor/EditorUtils.h" #include "DeerStudio/Editor/EditorUtils.h"
#include "DeerStudio/Editor/Icons.h" #include "DeerStudio/Editor/Icons.h"
#include "TerrainEditor.h"
#include "imgui.h" #include "imgui.h"
namespace Deer { namespace Deer {
namespace TerrainEditor { namespace TerrainEditor {
char filterChar[256]; char filterChar[256];
} }
void TerrainEditor::voxelSelector() { void TerrainEditor::voxelSelector() {
int textureSize = VoxelData::getVoxelTextureAtlasSize(); int textureSize = DataStore::getVoxelTextureAtlasSize();
VoxelAspect& selectedVoxelAspect = VoxelData::voxelsAspect[selectedVoxelID]; VoxelAspect& selectedVoxelAspect =
DataStore::voxelsAspect[selectedVoxelID];
int selectedVoxel_posY = selectedVoxelAspect.textureFacesIDs[NORMAL_BACK] / textureSize; int selectedVoxel_posY =
int selectedVoxel_posX = selectedVoxelAspect.textureFacesIDs[NORMAL_BACK] - selectedVoxel_posY * textureSize; selectedVoxelAspect.textureFacesIDs[NORMAL_BACK] / textureSize;
int selectedVoxel_posX =
selectedVoxelAspect.textureFacesIDs[NORMAL_BACK] -
selectedVoxel_posY * textureSize;
float selectedVoxel_minX = (float)(selectedVoxel_posX + 0) / (float)textureSize; float selectedVoxel_minX =
float selectedVoxel_minY = (float)(selectedVoxel_posY + 0) / (float)textureSize; (float)(selectedVoxel_posX + 0) / (float)textureSize;
float selectedVoxel_maxX = (float)(selectedVoxel_posX + 1) / (float)textureSize; float selectedVoxel_minY =
float selectedVoxel_maxY = (float)(selectedVoxel_posY + 1) / (float)textureSize; (float)(selectedVoxel_posY + 0) / (float)textureSize;
float selectedVoxel_maxX =
(float)(selectedVoxel_posX + 1) / (float)textureSize;
float selectedVoxel_maxY =
(float)(selectedVoxel_posY + 1) / (float)textureSize;
ImGui::Spacing(); ImGui::Spacing();
ImGui::Text("Selected Voxel:"); ImGui::Text("Selected Voxel:");
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s", selectedVoxelAspect.definition.voxelName.c_str()); ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.6f, 1.0f), "%s",
selectedVoxelAspect.definition.voxelName.c_str());
iconButton( iconButton((ImTextureID)(uint64_t)DataStore::getVoxelColorTextureAtlas()
(ImTextureID)(uint64_t)VoxelData::getVoxelColorTextureAtlas()->getTextureID(), ->getTextureID(),
ICON_BTN_MIN_SIZE, ICON_BTN_MIN_SIZE, true,
true, ImVec2(selectedVoxel_minX, selectedVoxel_maxY),
ImVec2(selectedVoxel_minX, selectedVoxel_maxY), ImVec2(selectedVoxel_maxX, selectedVoxel_minY));
ImVec2(selectedVoxel_maxX, selectedVoxel_minY));
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::CollapsingHeader("Voxel")) { if (ImGui::CollapsingHeader("Voxel")) {
ImGui::Indent(); ImGui::Indent();
ImGui::Text("Filter: "); ImGui::Text("Filter: ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::InputText("##Filter", filterChar, 255); ImGui::InputText("##Filter", filterChar, 255);
if (filterChar[0] != 0) { if (filterChar[0] != 0) {
if (ImGui::Button("Clear filter")) { if (ImGui::Button("Clear filter")) {
filterChar[0] = 0; filterChar[0] = 0;
} }
} }
ImGui::BeginChild("VOXEL_SELECTOR_CHILD", ImVec2(0, 128), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_AlwaysVerticalScrollbar) ; ImGui::BeginChild("VOXEL_SELECTOR_CHILD", ImVec2(0, 128),
ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_AlwaysVerticalScrollbar);
setupColumns(ICON_BTN_MIN_SIZE + 32); setupColumns(ICON_BTN_MIN_SIZE + 32);
for (int id = 0; id < VoxelData::voxelsInfo.size(); id ++) { for (int id = 0; id < DataStore::voxelsInfo.size(); id++) {
VoxelInfo& vi = VoxelData::voxelsInfo[id]; VoxelInfo& vi = DataStore::voxelsInfo[id];
if (vi.type != VoxelInfoType::Voxel) if (vi.type != VoxelInfoType::Voxel) continue;
continue;
if (filterChar[0] != 0) { if (filterChar[0] != 0) {
if (vi.name.find(filterChar) == std::string::npos) if (vi.name.find(filterChar) == std::string::npos) continue;
continue; }
}
ImGui::PushID(id); ImGui::PushID(id);
VoxelAspect& va = VoxelData::voxelsAspect[id]; VoxelAspect& va = DataStore::voxelsAspect[id];
int textureID = va.textureFacesIDs[NORMAL_FRONT]; int textureID = va.textureFacesIDs[NORMAL_FRONT];
int posY = textureID / textureSize; int posY = textureID / textureSize;
int posX = textureID - posY * textureSize; int posX = textureID - posY * textureSize;
float minX = (float)(posX + 0) / (float)textureSize; float minX = (float)(posX + 0) / (float)textureSize;
float minY = (float)(posY + 0) / (float)textureSize; float minY = (float)(posY + 0) / (float)textureSize;
float maxX = (float)(posX + 1) / (float)textureSize; float maxX = (float)(posX + 1) / (float)textureSize;
float maxY = (float)(posY + 1) / (float)textureSize; float maxY = (float)(posY + 1) / (float)textureSize;
float wColor = (id == selectedVoxelID)? 1 : 0.6f; float wColor = (id == selectedVoxelID) ? 1 : 0.6f;
if (iconButton( if (iconButton((ImTextureID)(uint64_t)
(ImTextureID)(uint64_t)VoxelData::getVoxelColorTextureAtlas()->getTextureID(), DataStore::getVoxelColorTextureAtlas()
ICON_BTN_MIN_SIZE, ->getTextureID(),
selectedVoxelID == id, ICON_BTN_MIN_SIZE, selectedVoxelID == id,
ImVec2(minX, maxY), ImVec2(minX, maxY), ImVec2(maxX, minY))) {
ImVec2(maxX, minY))) { selectedVoxelID = id;
selectedVoxelID = id; }
} ImGui::Text("%s", va.definition.voxelName.c_str());
ImGui::Text("%s", va.definition.voxelName.c_str());
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::PopID(); ImGui::PopID();
} }
ImGui::Columns(); ImGui::Columns();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
ImGui::Unindent(); ImGui::Unindent();
} }
}
} } // namespace Deer
}

View File

@ -3,7 +3,6 @@
#include "Deer/Enviroment.h" #include "Deer/Enviroment.h"
#include "Deer/Scene.h" #include "Deer/Scene.h"
#include "DeerRender/Input.h" #include "DeerRender/Input.h"
#include "DeerRender/KeyCodes.h"
#include "DeerStudio/Editor/ActiveEntity.h" #include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Project.h" #include "DeerStudio/Project.h"
#include "imgui.h" #include "imgui.h"

2689
Doxyfile

File diff suppressed because it is too large Load Diff

View File

@ -9,32 +9,32 @@ Size=400,400
Collapsed=0 Collapsed=0
[Window][Properties] [Window][Properties]
Pos=888,24 Pos=911,24
Size=392,344 Size=369,214
Collapsed=0 Collapsed=0
DockId=0x00000004,0 DockId=0x00000009,0
[Window][Game Window] [Window][Game Window]
Pos=368,24 Pos=368,24
Size=518,344 Size=541,442
Collapsed=0 Collapsed=0
DockId=0x00000006,1 DockId=0x00000006,1
[Window][Tree Pannel] [Window][Tree Pannel]
Pos=0,24 Pos=0,24
Size=366,344 Size=366,442
Collapsed=0 Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
[Window][Terrain Editor] [Window][Terrain Editor]
Pos=888,24 Pos=911,240
Size=392,344 Size=369,226
Collapsed=0 Collapsed=0
DockId=0x00000004,1 DockId=0x0000000A,0
[Window][Viewport] [Window][Viewport]
Pos=368,24 Pos=368,24
Size=518,344 Size=541,442
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
@ -45,19 +45,21 @@ Collapsed=0
DockId=0x00000002,0 DockId=0x00000002,0
[Window][Mesh Explorer] [Window][Mesh Explorer]
Pos=0,370 Pos=0,468
Size=1280,350 Size=1280,252
Collapsed=0 Collapsed=0
DockId=0x00000008,0 DockId=0x00000008,0
[Docking][Data] [Docking][Data]
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,344 Split=Y DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,442 Split=Y
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1234,779 Split=X Selected=0x13926F0B DockNode ID=0x00000003 Parent=0x00000001 SizeRef=909,779 Split=X Selected=0x13926F0B
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=366,779 Selected=0xBD1B42A3 DockNode ID=0x00000005 Parent=0x00000003 SizeRef=366,779 Selected=0xBD1B42A3
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=866,779 CentralNode=1 Selected=0x13926F0B DockNode ID=0x00000006 Parent=0x00000003 SizeRef=541,779 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=392,779 Selected=0x2A2C795E DockNode ID=0x00000004 Parent=0x00000001 SizeRef=369,779 Split=Y Selected=0x199AB496
DockNode ID=0x00000009 Parent=0x00000004 SizeRef=392,214 Selected=0x199AB496
DockNode ID=0x0000000A Parent=0x00000004 SizeRef=392,226 Selected=0x2A2C795E
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702
DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,350 Selected=0x7F7E0F9C DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,252 Selected=0x7F7E0F9C

Binary file not shown.

View File

@ -0,0 +1,71 @@
{
"mesh": {
"hasNormalData": true,
"vertexPositions": [
{
"x": {
"int": 128,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 128,
"dec": 0
}
},
{
"x": {
"int": 128,
"dec": 64
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 129,
"dec": 0
}
},
{
"x": {
"int": 129,
"dec": 0
},
"y": {
"int": 128,
"dec": 0
},
"z": {
"int": 128,
"dec": 0
}
}
],
"vertexNormals": [
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
},
{
"x": 0,
"y": 64,
"z": 0
}
],
"indices": [
0,
1,
2
]
}
}