120 lines
4.2 KiB
C++
120 lines
4.2 KiB
C++
#include "Deer/Voxel.h"
|
|
#include "Deer/Log.h"
|
|
#include "Deer/DataStore.h"
|
|
#include "DeerRender/Render/Shader.h"
|
|
#include "DeerRender/VoxelAspect.h"
|
|
|
|
#include "cereal/archives/json.hpp"
|
|
#include "DeerRender/Voxels/Serialization/VoxelAspect_Serialization.h"
|
|
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
namespace Deer{
|
|
namespace VoxelData {
|
|
std::vector<VoxelAspect> voxelsAspect;
|
|
std::unordered_map<std::string, uint16_t> texturesIDs;
|
|
Ref<Shader> solidVoxelShader;
|
|
}
|
|
|
|
void VoxelData::loadVoxelsAspect() {
|
|
std::vector<Path> voxelsAspectPath = DataStore::getFiles(DEER_VOXEL_ASPECT_PATH, ".vaspect");
|
|
voxelsAspect.clear();
|
|
voxelsAspect.resize(voxelsInfo.size());
|
|
|
|
voxelsAspect[0].definition.voxelName = VOXEL_INFO_TYPE_AIR;
|
|
|
|
DEER_CORE_INFO("=== Loading voxel aspect ===");
|
|
DEER_CORE_TRACE(" default - air");
|
|
for (Path& voxelAspectPath: voxelsAspectPath) {
|
|
uint32_t size;
|
|
uint8_t* data = DataStore::readFile(voxelAspectPath, &size);
|
|
|
|
std::string dataString((char*)data, size);
|
|
std::istringstream inputStream(dataString);
|
|
|
|
VoxelAspectDefinition aspectDefinition;
|
|
{
|
|
cereal::JSONInputArchive archive(inputStream);
|
|
archive(cereal::make_nvp("voxelAspect", aspectDefinition));
|
|
|
|
}
|
|
|
|
if (aspectDefinition.voxelName.empty()) {
|
|
DEER_CORE_ERROR("{0} has an empty name", voxelAspectPath.generic_string().c_str());
|
|
continue;
|
|
}
|
|
|
|
int16_t voxelID = getVoxelID(aspectDefinition.voxelName);
|
|
if (voxelID == -1) {
|
|
DEER_CORE_ERROR("Voxel aspect {0} references {1} but it does not exist",
|
|
voxelAspectPath.generic_string().c_str(), aspectDefinition.voxelName.c_str());
|
|
|
|
continue;
|
|
}
|
|
|
|
DEER_CORE_TRACE(" {0} - {1}",
|
|
voxelAspectPath.filename().generic_string().c_str(),
|
|
aspectDefinition.voxelName.c_str());
|
|
|
|
voxelsAspect[voxelID].definition = aspectDefinition;
|
|
}
|
|
|
|
DEER_CORE_INFO("=== Extracting textures ===");
|
|
for (VoxelAspect& voxelAspect : voxelsAspect) {
|
|
if (voxelsInfo[VoxelData::getVoxelID(voxelAspect.definition.voxelName)].type != VoxelInfoType::Voxel)
|
|
continue;
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
std::string& faceTextureString = voxelAspect.definition.textureFaces[i];
|
|
|
|
if (faceTextureString.empty()) {
|
|
DEER_CORE_WARN("{0} has an empty texture at position {1} this could cause unwanted behaviour!",
|
|
voxelAspect.definition.voxelName.c_str(), i);
|
|
|
|
voxelAspect.textureFacesIDs[i] = 0;
|
|
continue;
|
|
}
|
|
|
|
if (texturesIDs.contains(faceTextureString))
|
|
voxelAspect.textureFacesIDs[i] = texturesIDs[faceTextureString];
|
|
else {
|
|
uint16_t textureID = texturesIDs.size();
|
|
|
|
texturesIDs[faceTextureString] = textureID;
|
|
voxelAspect.textureFacesIDs[i] = textureID;
|
|
|
|
DEER_CORE_TRACE(" texture {0} - id: {1}",
|
|
faceTextureString.c_str(), textureID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void VoxelData::createExampleVoxelAspect() {
|
|
VoxelAspectDefinition voxelAspectDefinition;
|
|
|
|
std::ostringstream outputStream;
|
|
{
|
|
cereal::JSONOutputArchive archive(outputStream);
|
|
archive(cereal::make_nvp("voxelAspect", voxelAspectDefinition));
|
|
}
|
|
|
|
std::string restultString = outputStream.str();
|
|
DataStore::saveFile(Path(DEER_VOXEL_PATH) / "vaspect.example", (uint8_t*)restultString.c_str(), restultString.size());
|
|
}
|
|
|
|
void VoxelData::loadVoxelsShaders() {
|
|
uint32_t size;
|
|
uint8_t* data = DataStore::readFile(Path(DEER_VOXEL_SHADER_PATH) / "solid_voxel.glsl", &size);
|
|
|
|
solidVoxelShader = Shader::create(data, size);
|
|
|
|
delete[] data;
|
|
}
|
|
|
|
Ref<Shader>& VoxelData::getSolidVoxelShader() {
|
|
return solidVoxelShader;
|
|
}
|
|
} |