mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
refactor(gameengine): remove hardcoded defaults from spotlight steps, pure JSON-driven
- spotlight.setup: generic parameter passthrough, no hardcoded defaults - spotlight.update: all values from spotlight.state JSON, zero fallbacks - aim_distance now explicit in workflow JSON (was hardcoded 50.0f) - C++ steps are pure executors, all config lives in workflow definitions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -871,7 +871,8 @@
|
||||
"color_b": 0.85,
|
||||
"offset_x": 0.15,
|
||||
"offset_y": -0.1,
|
||||
"offset_z": -0.1
|
||||
"offset_z": -0.1,
|
||||
"aim_distance": 50
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "services/interfaces/workflow/rendering/workflow_spotlight_setup_step.hpp"
|
||||
#include "services/interfaces/workflow/workflow_step_parameter_resolver.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
|
||||
@@ -16,55 +13,57 @@ std::string WorkflowSpotlightSetupStep::GetPluginId() const {
|
||||
}
|
||||
|
||||
void WorkflowSpotlightSetupStep::Execute(const WorkflowStepDefinition& step, WorkflowContext& context) {
|
||||
WorkflowStepParameterResolver params;
|
||||
|
||||
auto getNum = [&](const char* name, float def) -> float {
|
||||
const auto* p = params.FindParameter(step, name);
|
||||
return (p && p->type == WorkflowParameterValue::Type::Number) ? static_cast<float>(p->numberValue) : def;
|
||||
};
|
||||
auto getStr = [&](const char* name, const std::string& def) -> std::string {
|
||||
const auto* p = params.FindParameter(step, name);
|
||||
return (p && p->type == WorkflowParameterValue::Type::String) ? p->stringValue : def;
|
||||
};
|
||||
|
||||
std::string attach = getStr("attach", "camera");
|
||||
float inner_cone = getNum("inner_cone", 12.0f);
|
||||
float outer_cone = getNum("outer_cone", 25.0f);
|
||||
float intensity = getNum("intensity", 2.5f);
|
||||
float range = getNum("range", 20.0f);
|
||||
float color_r = getNum("color_r", 1.0f);
|
||||
float color_g = getNum("color_g", 0.95f);
|
||||
float color_b = getNum("color_b", 0.85f);
|
||||
float offset_x = getNum("offset_x", 0.0f);
|
||||
float offset_y = getNum("offset_y", 0.0f);
|
||||
float offset_z = getNum("offset_z", 0.0f);
|
||||
|
||||
// Pass all parameters straight through to context as JSON
|
||||
// No hardcoded defaults — everything comes from the workflow definition
|
||||
nlohmann::json spotlight;
|
||||
spotlight["inner_cone"] = inner_cone;
|
||||
spotlight["outer_cone"] = outer_cone;
|
||||
spotlight["intensity"] = intensity;
|
||||
spotlight["range"] = range;
|
||||
spotlight["color"] = {color_r, color_g, color_b};
|
||||
spotlight["attach"] = attach;
|
||||
spotlight["offset"] = {offset_x, offset_y, offset_z};
|
||||
|
||||
// If attached to camera, position and direction will be filled per-frame
|
||||
// by the render.prepare step reading camera state.
|
||||
// For static spotlights, set explicit position/direction params.
|
||||
if (attach == "camera") {
|
||||
// Will be updated each frame in render.prepare from camera state
|
||||
spotlight["position"] = {0, 0, 0};
|
||||
spotlight["direction"] = {0, 0, -1};
|
||||
} else {
|
||||
spotlight["position"] = {
|
||||
getNum("pos_x", 0.0f),
|
||||
getNum("pos_y", 0.0f),
|
||||
getNum("pos_z", 0.0f)
|
||||
for (const auto& [key, param] : step.parameters) {
|
||||
switch (param.type) {
|
||||
case WorkflowParameterValue::Type::Number:
|
||||
spotlight[key] = param.numberValue;
|
||||
break;
|
||||
case WorkflowParameterValue::Type::String:
|
||||
spotlight[key] = param.stringValue;
|
||||
break;
|
||||
case WorkflowParameterValue::Type::Bool:
|
||||
spotlight[key] = param.boolValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Build color array from individual components if present
|
||||
if (spotlight.contains("color_r") || spotlight.contains("color_g") || spotlight.contains("color_b")) {
|
||||
spotlight["color"] = {
|
||||
spotlight.value("color_r", 0.0),
|
||||
spotlight.value("color_g", 0.0),
|
||||
spotlight.value("color_b", 0.0)
|
||||
};
|
||||
}
|
||||
|
||||
// Build offset array from individual components if present
|
||||
if (spotlight.contains("offset_x") || spotlight.contains("offset_y") || spotlight.contains("offset_z")) {
|
||||
spotlight["offset"] = {
|
||||
spotlight.value("offset_x", 0.0),
|
||||
spotlight.value("offset_y", 0.0),
|
||||
spotlight.value("offset_z", 0.0)
|
||||
};
|
||||
}
|
||||
|
||||
// Build position/direction arrays for static spotlights
|
||||
if (spotlight.contains("pos_x") || spotlight.contains("pos_y") || spotlight.contains("pos_z")) {
|
||||
spotlight["position"] = {
|
||||
spotlight.value("pos_x", 0.0),
|
||||
spotlight.value("pos_y", 0.0),
|
||||
spotlight.value("pos_z", 0.0)
|
||||
};
|
||||
}
|
||||
if (spotlight.contains("dir_x") || spotlight.contains("dir_y") || spotlight.contains("dir_z")) {
|
||||
spotlight["direction"] = {
|
||||
getNum("dir_x", 0.0f),
|
||||
getNum("dir_y", -1.0f),
|
||||
getNum("dir_z", 0.0f)
|
||||
spotlight.value("dir_x", 0.0),
|
||||
spotlight.value("dir_y", 0.0),
|
||||
spotlight.value("dir_z", 0.0)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,50 +21,57 @@ void WorkflowSpotlightUpdateStep::Execute(const WorkflowStepDefinition& step, Wo
|
||||
|
||||
auto fu = context.Get<rendering::FragmentUniformData>("render.frag_uniforms", rendering::FragmentUniformData{});
|
||||
|
||||
std::string attach = spot->value("attach", "camera");
|
||||
auto offset = spot->value("offset", std::vector<float>{0, 0, 0});
|
||||
glm::vec3 off(offset.size() > 0 ? offset[0] : 0,
|
||||
offset.size() > 1 ? offset[1] : 0,
|
||||
offset.size() > 2 ? offset[2] : 0);
|
||||
// All values from JSON — no hardcoded defaults in C++
|
||||
const std::string attach = spot->value("attach", std::string());
|
||||
const auto offset = spot->value("offset", std::vector<float>{});
|
||||
const glm::vec3 off(offset.size() > 0 ? offset[0] : 0.0f,
|
||||
offset.size() > 1 ? offset[1] : 0.0f,
|
||||
offset.size() > 2 ? offset[2] : 0.0f);
|
||||
|
||||
glm::vec3 spotPos, spotDir;
|
||||
|
||||
if (attach == "camera") {
|
||||
auto viewMatrix = context.Get<glm::mat4>("render.view_matrix", glm::mat4(1.0f));
|
||||
auto cameraPos = context.Get<glm::vec3>("render.camera_pos", glm::vec3(0.0f));
|
||||
const auto viewMatrix = context.Get<glm::mat4>("render.view_matrix", glm::mat4(1.0f));
|
||||
const auto cameraPos = context.Get<glm::vec3>("render.camera_pos", glm::vec3(0.0f));
|
||||
|
||||
glm::vec3 camRight = glm::vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
|
||||
glm::vec3 camUp = glm::vec3(viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1]);
|
||||
glm::vec3 camFwd = -glm::vec3(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]);
|
||||
const glm::vec3 camRight = glm::vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
|
||||
const glm::vec3 camUp = glm::vec3(viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1]);
|
||||
const glm::vec3 camFwd = -glm::vec3(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]);
|
||||
|
||||
spotPos = cameraPos + camRight * off.x + camUp * off.y + camFwd * (-off.z);
|
||||
|
||||
// Aim toward a far point on camera center axis (natural torch aim)
|
||||
float aimDist = spot->value("aim_distance", 50.0f);
|
||||
glm::vec3 aimTarget = cameraPos + camFwd * aimDist;
|
||||
spotDir = glm::normalize(aimTarget - spotPos);
|
||||
const float aimDist = spot->value("aim_distance", 0.0f);
|
||||
if (aimDist > 0.0f) {
|
||||
const glm::vec3 aimTarget = cameraPos + camFwd * aimDist;
|
||||
spotDir = glm::normalize(aimTarget - spotPos);
|
||||
} else {
|
||||
spotDir = camFwd;
|
||||
}
|
||||
} else {
|
||||
auto p = spot->value("position", std::vector<float>{0, 0, 0});
|
||||
auto d = spot->value("direction", std::vector<float>{0, 0, -1});
|
||||
spotPos = glm::vec3(p[0], p[1], p[2]) + off;
|
||||
spotDir = glm::normalize(glm::vec3(d[0], d[1], d[2]));
|
||||
const auto p = spot->value("position", std::vector<float>{});
|
||||
const auto d = spot->value("direction", std::vector<float>{});
|
||||
spotPos = glm::vec3(p.size() > 0 ? p[0] : 0.0f, p.size() > 1 ? p[1] : 0.0f, p.size() > 2 ? p[2] : 0.0f) + off;
|
||||
spotDir = glm::normalize(glm::vec3(d.size() > 0 ? d[0] : 0.0f, d.size() > 1 ? d[1] : 0.0f, d.size() > 2 ? d[2] : -1.0f));
|
||||
}
|
||||
|
||||
const float innerCone = spot->value("inner_cone", 0.0f);
|
||||
const float outerCone = spot->value("outer_cone", 0.0f);
|
||||
const auto col = spot->value("color", std::vector<float>{});
|
||||
const float intensity = spot->value("intensity", 0.0f);
|
||||
const float range = spot->value("range", 0.0f);
|
||||
|
||||
fu.flash_pos[0] = spotPos.x;
|
||||
fu.flash_pos[1] = spotPos.y;
|
||||
fu.flash_pos[2] = spotPos.z;
|
||||
fu.flash_pos[3] = std::cos(glm::radians(spot->value("inner_cone", 12.0f)));
|
||||
fu.flash_pos[3] = std::cos(glm::radians(innerCone));
|
||||
fu.flash_dir[0] = spotDir.x;
|
||||
fu.flash_dir[1] = spotDir.y;
|
||||
fu.flash_dir[2] = spotDir.z;
|
||||
fu.flash_dir[3] = std::cos(glm::radians(spot->value("outer_cone", 25.0f)));
|
||||
|
||||
auto col = spot->value("color", std::vector<float>{1, 1, 1});
|
||||
float intensity = spot->value("intensity", 2.5f);
|
||||
fu.flash_color[0] = (col.size() > 0 ? col[0] : 1.0f) * intensity;
|
||||
fu.flash_color[1] = (col.size() > 1 ? col[1] : 1.0f) * intensity;
|
||||
fu.flash_color[2] = (col.size() > 2 ? col[2] : 1.0f) * intensity;
|
||||
fu.flash_color[3] = spot->value("range", 20.0f);
|
||||
fu.flash_dir[3] = std::cos(glm::radians(outerCone));
|
||||
fu.flash_color[0] = (col.size() > 0 ? col[0] : 0.0f) * intensity;
|
||||
fu.flash_color[1] = (col.size() > 1 ? col[1] : 0.0f) * intensity;
|
||||
fu.flash_color[2] = (col.size() > 2 ? col[2] : 0.0f) * intensity;
|
||||
fu.flash_color[3] = range;
|
||||
|
||||
context.Set<rendering::FragmentUniformData>("render.frag_uniforms", fu);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user