feat: add vec3 type to nhollman json / fix: scene serialisation stuff
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <destrum/Graphics/RenderContext.h>
|
||||
#include <destrum/ObjectModel/Transform.h>
|
||||
#include <destrum/Serialization/GlmJson.h>
|
||||
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
@@ -54,7 +55,7 @@ void LightComponent::Render(const RenderContext& ctx)
|
||||
nlohmann::json LightComponent::Serialize() const {
|
||||
return {
|
||||
{"type", static_cast<std::uint32_t>(m_Type)},
|
||||
{"color", {m_Color.x, m_Color.y, m_Color.z}},
|
||||
{"color", m_Color},
|
||||
{"intensity", m_Intensity},
|
||||
{"range", m_Range},
|
||||
{"innerConeAngle", m_InnerConeAngle},
|
||||
@@ -70,10 +71,7 @@ void LightComponent::Deserialize(const nlohmann::json& data) {
|
||||
m_Type = static_cast<LightType>(type);
|
||||
}
|
||||
}
|
||||
if (data.contains("color")) {
|
||||
const auto& value = data.at("color");
|
||||
m_Color = {value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()};
|
||||
}
|
||||
m_Color = data.value("color", m_Color);
|
||||
if (data.contains("intensity")) {
|
||||
SetIntensity(data.at("intensity").get<float>());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <destrum/Components/MeshRendererComponent.h>
|
||||
#include <destrum/Assets/AssetReference.h>
|
||||
#include <destrum/Graphics/GfxDevice.h>
|
||||
#include <destrum/Graphics/Resources/PrimitiveMeshes.h>
|
||||
#include <destrum/Graphics/Renderer.h>
|
||||
#include <destrum/ObjectModel/Transform.h>
|
||||
|
||||
@@ -10,8 +11,11 @@
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
MeshRendererComponent::MeshRendererComponent(GameObject& parent): Component(parent, "MeshRendererComponent") {
|
||||
|
||||
}
|
||||
@@ -54,27 +58,39 @@ void MeshRendererComponent::Update(float) {
|
||||
}
|
||||
|
||||
nlohmann::json MeshRendererComponent::Serialize() const {
|
||||
// Only keys are saved, mesh and material ids are cache slots that change between runs
|
||||
std::string savedMeshKey = meshKey;
|
||||
std::string savedMaterialKey = materialKey;
|
||||
if (GameState::GetInstance().HasRenderer()) {
|
||||
if (const auto* resources = GameState::GetInstance().Renderer().getResources()) {
|
||||
if (savedMeshKey.empty() && meshID != NULL_MESH_ID) {
|
||||
savedMeshKey = resources->meshes().getMeshKey(meshID);
|
||||
}
|
||||
if (savedMaterialKey.empty() && materialID != NULL_MATERIAL_ID) {
|
||||
savedMaterialKey = resources->materials().getMaterialKey(materialID);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (savedMeshKey.empty() && meshID != NULL_MESH_ID) {
|
||||
throw std::runtime_error("MeshRendererComponent has a mesh without a key, it cannot be saved");
|
||||
}
|
||||
if (savedMaterialKey.empty() && materialID != NULL_MATERIAL_ID) {
|
||||
throw std::runtime_error("MeshRendererComponent has a material without a key, it cannot be saved");
|
||||
}
|
||||
|
||||
return {
|
||||
{"meshId", meshID},
|
||||
{"materialId", materialID},
|
||||
{"meshKey", meshKey},
|
||||
{"materialKey", materialKey}
|
||||
{"meshKey", savedMeshKey},
|
||||
{"materialKey", savedMaterialKey}
|
||||
};
|
||||
}
|
||||
|
||||
void MeshRendererComponent::Deserialize(const nlohmann::json& data) {
|
||||
if (data.contains("meshId")) {
|
||||
meshID = data.at("meshId").get<MeshID>();
|
||||
}
|
||||
if (data.contains("materialId")) {
|
||||
materialID = data.at("materialId").get<MaterialID>();
|
||||
}
|
||||
if (data.contains("meshKey")) {
|
||||
meshKey = data.at("meshKey").get<std::string>();
|
||||
}
|
||||
if (data.contains("materialKey")) {
|
||||
materialKey = data.at("materialKey").get<std::string>();
|
||||
}
|
||||
meshKey = data.value("meshKey", std::string{});
|
||||
materialKey = data.value("materialKey", std::string{});
|
||||
|
||||
// Older scenes also stored raw ids, only trust them when there is no key
|
||||
meshID = meshKey.empty() ? data.value("meshId", NULL_MESH_ID) : NULL_MESH_ID;
|
||||
materialID = materialKey.empty() ? data.value("materialId", NULL_MATERIAL_ID) : NULL_MATERIAL_ID;
|
||||
}
|
||||
|
||||
void MeshRendererComponent::ResolveReferences(const ObjectMap&) {
|
||||
@@ -89,7 +105,9 @@ void MeshRendererComponent::ResolveReferences(const ObjectMap&) {
|
||||
|
||||
const auto loadAssetForKey = [&](const std::string& key) {
|
||||
const auto asset = AssetReference::fromCacheKey(key);
|
||||
if (!asset) {
|
||||
// Runtime-only keys such as "BulbMaterial#2" also contain a '#', they are not files
|
||||
if (!asset || (asset->path.find("://") == std::string::npos &&
|
||||
!std::filesystem::exists(asset->path))) {
|
||||
return;
|
||||
}
|
||||
if (!GameState::GetInstance().HasGfxDevice()) {
|
||||
@@ -102,6 +120,20 @@ void MeshRendererComponent::ResolveReferences(const ObjectMap&) {
|
||||
|
||||
if (!meshKey.empty()) {
|
||||
auto resolved = resources->meshes().findMeshByKey(meshKey);
|
||||
if (!resolved && PrimitiveMeshes::IsPrimitiveKey(meshKey)) {
|
||||
resolved = resources->meshes().findMeshByKey(PrimitiveMeshes::StripDuplicateSuffix(meshKey));
|
||||
if (!resolved) {
|
||||
auto primitive = PrimitiveMeshes::MakeFromKey(meshKey);
|
||||
if (!primitive) {
|
||||
throw std::runtime_error("Invalid primitive mesh key: " + meshKey);
|
||||
}
|
||||
if (!GameState::GetInstance().HasGfxDevice()) {
|
||||
throw std::runtime_error("Cannot build primitive mesh without a graphics device: " + meshKey);
|
||||
}
|
||||
resolved = resources->meshes().addMesh(GameState::GetInstance().Gfx(), *primitive);
|
||||
}
|
||||
meshKey = resources->meshes().getMeshKey(*resolved);
|
||||
}
|
||||
if (!resolved) {
|
||||
loadAssetForKey(meshKey);
|
||||
resolved = resources->meshes().findMeshByKey(meshKey);
|
||||
@@ -129,11 +161,15 @@ void MeshRendererComponent::ResolveReferences(const ObjectMap&) {
|
||||
resolved = resources->materials().findMaterialByName(materialKey);
|
||||
}
|
||||
|
||||
if (!resolved) {
|
||||
throw std::runtime_error("Material resource not found: " + materialKey);
|
||||
if (resolved) {
|
||||
materialID = *resolved;
|
||||
materialKey = resources->materials().getMaterialKey(*resolved);
|
||||
} else {
|
||||
// Keep the key so saving again does not lose which material was meant
|
||||
spdlog::warn("Material \"{}\" on \"{}\" not found, using the placeholder material",
|
||||
materialKey, GetGameObject()->GetName());
|
||||
materialID = resources->materials().getPlaceholderMaterialId();
|
||||
}
|
||||
materialID = *resolved;
|
||||
materialKey = resources->materials().getMaterialKey(*resolved);
|
||||
}
|
||||
|
||||
if (meshID != NULL_MESH_ID && meshKey.empty()) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "destrum/ObjectModel/GameObject.h"
|
||||
#include "destrum/ObjectModel/Transform.h"
|
||||
#include "destrum/Components/MeshRendererComponent.h"
|
||||
#include "destrum/Serialization/GlmJson.h"
|
||||
#include "destrum/Util/GameState.h"
|
||||
#include "destrum/Util/DeltaTime.h"
|
||||
#include "destrum/Util/ImGuiUtils.h"
|
||||
@@ -128,8 +129,8 @@ void OrbitAndSpin::Start() {
|
||||
nlohmann::json OrbitAndSpin::Serialize() const {
|
||||
return {
|
||||
{"radius", m_Radius},
|
||||
{"center", {m_Center.x, m_Center.y, m_Center.z}},
|
||||
{"orbitAxis", {m_OrbitAxis.x, m_OrbitAxis.y, m_OrbitAxis.z}},
|
||||
{"center", m_Center},
|
||||
{"orbitAxis", m_OrbitAxis},
|
||||
{"orbitSpeed", m_OrbitSpeed},
|
||||
{"orbitAngle", m_OrbitAngle},
|
||||
{"orbitPhase", m_OrbitPhase},
|
||||
@@ -137,38 +138,27 @@ nlohmann::json OrbitAndSpin::Serialize() const {
|
||||
{"growSpeed", m_GrowSpeed},
|
||||
{"growMin", m_GrowMin},
|
||||
{"growMax", m_GrowMax},
|
||||
{"spinAxis", {m_SpinAxis.x, m_SpinAxis.y, m_SpinAxis.z}},
|
||||
{"spinAxis", m_SpinAxis},
|
||||
{"spinSpeed", m_SpinSpeed},
|
||||
{"baseScale", {m_BaseScale.x, m_BaseScale.y, m_BaseScale.z}},
|
||||
{"materialId", m_MaterialID}
|
||||
{"baseScale", m_BaseScale}
|
||||
};
|
||||
}
|
||||
|
||||
void OrbitAndSpin::Deserialize(const nlohmann::json& data) {
|
||||
const auto readVec3 = [&data](const char* key, glm::vec3& value) {
|
||||
if (!data.contains(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& array = data.at(key);
|
||||
value = {array.at(0).get<float>(), array.at(1).get<float>(), array.at(2).get<float>()};
|
||||
};
|
||||
|
||||
if (data.contains("radius")) m_Radius = data.at("radius").get<float>();
|
||||
readVec3("center", m_Center);
|
||||
readVec3("orbitAxis", m_OrbitAxis);
|
||||
if (data.contains("orbitSpeed")) m_OrbitSpeed = data.at("orbitSpeed").get<float>();
|
||||
if (data.contains("orbitAngle")) m_OrbitAngle = data.at("orbitAngle").get<float>();
|
||||
if (data.contains("orbitPhase")) m_OrbitPhase = data.at("orbitPhase").get<float>();
|
||||
if (data.contains("growPhase")) m_GrowPhase = data.at("growPhase").get<float>();
|
||||
if (data.contains("growSpeed")) m_GrowSpeed = data.at("growSpeed").get<float>();
|
||||
if (data.contains("growMin")) m_GrowMin = data.at("growMin").get<float>();
|
||||
if (data.contains("growMax")) m_GrowMax = data.at("growMax").get<float>();
|
||||
readVec3("spinAxis", m_SpinAxis);
|
||||
readVec3("baseScale", m_BaseScale);
|
||||
m_Radius = data.value("radius", m_Radius);
|
||||
m_Center = data.value("center", m_Center);
|
||||
m_OrbitAxis = data.value("orbitAxis", m_OrbitAxis);
|
||||
m_OrbitSpeed = data.value("orbitSpeed", m_OrbitSpeed);
|
||||
m_OrbitAngle = data.value("orbitAngle", m_OrbitAngle);
|
||||
m_OrbitPhase = data.value("orbitPhase", m_OrbitPhase);
|
||||
m_GrowPhase = data.value("growPhase", m_GrowPhase);
|
||||
m_GrowSpeed = data.value("growSpeed", m_GrowSpeed);
|
||||
m_GrowMin = data.value("growMin", m_GrowMin);
|
||||
m_GrowMax = data.value("growMax", m_GrowMax);
|
||||
m_SpinAxis = data.value("spinAxis", m_SpinAxis);
|
||||
m_BaseScale = data.value("baseScale", m_BaseScale);
|
||||
m_BaseScaleLoaded = data.contains("baseScale");
|
||||
if (data.contains("spinSpeed")) m_SpinSpeed = data.at("spinSpeed").get<float>();
|
||||
if (data.contains("materialId")) m_MaterialID = data.at("materialId").get<MaterialID>();
|
||||
m_SpinSpeed = data.value("spinSpeed", m_SpinSpeed);
|
||||
|
||||
if (m_GrowMin > m_GrowMax) {
|
||||
std::swap(m_GrowMin, m_GrowMax);
|
||||
|
||||
@@ -11,19 +11,14 @@ void BoxCollider::DrawDebugLines(const glm::vec4& color) const {
|
||||
|
||||
nlohmann::json BoxCollider::Serialize() const {
|
||||
auto data = SerializeCollider();
|
||||
data["halfExtents"] = {m_HalfExtents.x, m_HalfExtents.y, m_HalfExtents.z};
|
||||
data["halfExtents"] = m_HalfExtents;
|
||||
return data;
|
||||
}
|
||||
|
||||
void BoxCollider::Deserialize(const nlohmann::json& data) {
|
||||
DeserializeCollider(data);
|
||||
if (data.contains("halfExtents")) {
|
||||
const auto& extents = data.at("halfExtents");
|
||||
SetHalfExtents({
|
||||
extents.at(0).get<float>(),
|
||||
extents.at(1).get<float>(),
|
||||
extents.at(2).get<float>()
|
||||
});
|
||||
SetHalfExtents(data.at("halfExtents").get<glm::vec3>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <cmath>
|
||||
#include <glm/gtc/quaternion.hpp> // glm::quat, glm::angleAxis
|
||||
#include <glm/gtx/quaternion.hpp> // operator*(quat, vec3)
|
||||
#include <destrum/Serialization/GlmJson.h>
|
||||
#include <destrum/Util/DeltaTime.h>
|
||||
#include <destrum/Util/ImGuiUtils.h>
|
||||
|
||||
@@ -102,34 +103,21 @@ nlohmann::json Rotator::Serialize() const {
|
||||
{"distance", m_Distance},
|
||||
{"speed", m_Speed},
|
||||
{"currentAngle", m_CurrentAngle},
|
||||
{"pivot", {m_Pivot.x, m_Pivot.y, m_Pivot.z}},
|
||||
{"axis", {m_Axis.x, m_Axis.y, m_Axis.z}},
|
||||
{"initialOffset", {m_InitialOffset.x, m_InitialOffset.y, m_InitialOffset.z}}
|
||||
{"pivot", m_Pivot},
|
||||
{"axis", m_Axis},
|
||||
{"initialOffset", m_InitialOffset}
|
||||
};
|
||||
}
|
||||
|
||||
void Rotator::Deserialize(const nlohmann::json& data) {
|
||||
if (data.contains("distance")) {
|
||||
m_Distance = data.at("distance").get<float>();
|
||||
}
|
||||
if (data.contains("speed")) {
|
||||
m_Speed = data.at("speed").get<float>();
|
||||
}
|
||||
if (data.contains("currentAngle")) {
|
||||
m_CurrentAngle = data.at("currentAngle").get<float>();
|
||||
}
|
||||
if (data.contains("pivot")) {
|
||||
const auto& value = data.at("pivot");
|
||||
m_Pivot = {value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()};
|
||||
}
|
||||
m_Distance = data.value("distance", m_Distance);
|
||||
m_Speed = data.value("speed", m_Speed);
|
||||
m_CurrentAngle = data.value("currentAngle", m_CurrentAngle);
|
||||
m_Pivot = data.value("pivot", m_Pivot);
|
||||
if (data.contains("axis")) {
|
||||
const auto& value = data.at("axis");
|
||||
SetAxis({value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()});
|
||||
}
|
||||
if (data.contains("initialOffset")) {
|
||||
const auto& value = data.at("initialOffset");
|
||||
m_InitialOffset = {value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()};
|
||||
SetAxis(data.at("axis").get<glm::vec3>());
|
||||
}
|
||||
m_InitialOffset = data.value("initialOffset", m_InitialOffset);
|
||||
}
|
||||
|
||||
void Rotator::ImGuiInspector() {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "destrum/ObjectModel/Transform.h"
|
||||
#include "destrum/Serialization/GlmJson.h"
|
||||
#include "destrum/Util/DeltaTime.h"
|
||||
#include "destrum/Util/ImGuiUtils.h"
|
||||
|
||||
@@ -18,7 +19,7 @@ void Spinner::Update(float dt)
|
||||
|
||||
nlohmann::json Spinner::Serialize() const {
|
||||
return {
|
||||
{"axis", {m_Axis.x, m_Axis.y, m_Axis.z}},
|
||||
{"axis", m_Axis},
|
||||
{"speed", m_Speed},
|
||||
{"angle", m_Angle}
|
||||
};
|
||||
@@ -26,15 +27,10 @@ nlohmann::json Spinner::Serialize() const {
|
||||
|
||||
void Spinner::Deserialize(const nlohmann::json& data) {
|
||||
if (data.contains("axis")) {
|
||||
const auto& value = data.at("axis");
|
||||
SetAxis({value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()});
|
||||
}
|
||||
if (data.contains("speed")) {
|
||||
m_Speed = data.at("speed").get<float>();
|
||||
}
|
||||
if (data.contains("angle")) {
|
||||
m_Angle = data.at("angle").get<float>();
|
||||
SetAxis(data.at("axis").get<glm::vec3>());
|
||||
}
|
||||
m_Speed = data.value("speed", m_Speed);
|
||||
m_Angle = data.value("angle", m_Angle);
|
||||
}
|
||||
|
||||
void Spinner::ImGuiInspector() {
|
||||
|
||||
Reference in New Issue
Block a user