feat(web): wire Blender world lighting controls
This commit is contained in:
@@ -5192,6 +5192,13 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
||||
{"color", json::array({horizon_r, horizon_g, horizon_b})},
|
||||
{"exposure", exposure},
|
||||
{"backgroundVisible", true} };
|
||||
world["ambientOcclusionDistance"] = read_float(*blend.sdna, element, "aodist").value_or(10.0f);
|
||||
world["ambientOcclusionEnergy"] = read_float(*blend.sdna, element, "aoenergy").value_or(1.0f);
|
||||
world["sunThreshold"] = read_float(*blend.sdna, element, "sun_threshold").value_or(10.0f);
|
||||
world["sunAngle"] = read_float(*blend.sdna, element, "sun_angle").value_or(0.00918f);
|
||||
world["sunShadowMaximumResolution"] = read_float(*blend.sdna, element, "sun_shadow_maximum_resolution").value_or(0.001f);
|
||||
world["sunShadowJitterOverblur"] = read_float(*blend.sdna, element, "sun_shadow_jitter_overblur").value_or(10.0f);
|
||||
world["sunShadowFilterRadius"] = read_float(*blend.sdna, element, "sun_shadow_filter_radius").value_or(1.0f);
|
||||
if (const std::optional<uint64_t> lightgroup_pointer = read_pointer(*blend.sdna, element, "lightgroup")) {
|
||||
if (const std::optional<ElementRef> membership = element_for_pointer(blend, *lightgroup_pointer)) {
|
||||
const std::string lightgroup_name = read_string(*blend.sdna, *membership, "name");
|
||||
|
||||
@@ -5592,6 +5592,45 @@ bool web_engine_blend_main_set_light_clip_start(WebBlendMainState *state,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool web_engine_blend_main_set_world_lighting_controls(WebBlendMainState *state,
|
||||
const char *target_id,
|
||||
const float ao_distance,
|
||||
const float ao_energy,
|
||||
const float sun_threshold,
|
||||
const float sun_angle,
|
||||
const float sun_shadow_maximum_resolution,
|
||||
const float sun_shadow_jitter_overblur,
|
||||
const float sun_shadow_filter_radius,
|
||||
std::string &error)
|
||||
{
|
||||
if (state == nullptr || state->main == nullptr || target_id == nullptr) {
|
||||
error = "RENDER_PROPERTY_INVALID: world lighting target is missing";
|
||||
return false;
|
||||
}
|
||||
World *world = find_world(state->main, target_id);
|
||||
if (world == nullptr || world->id.lib != nullptr) {
|
||||
error = "LINKED_DATA_MUTATION_BLOCKED: World is not editable";
|
||||
return false;
|
||||
}
|
||||
const float values[] = {ao_distance, ao_energy, sun_threshold, sun_angle, sun_shadow_maximum_resolution, sun_shadow_jitter_overblur, sun_shadow_filter_radius};
|
||||
if (!std::all_of(std::begin(values), std::end(values), [](const float value) { return std::isfinite(value) && value >= 0.0f; }) ||
|
||||
ao_distance > 1.0e9f || ao_energy > 1.0e9f || sun_threshold > 1.0e9f || sun_angle > 3.14159265f ||
|
||||
sun_shadow_maximum_resolution < 0.0000001f || sun_shadow_maximum_resolution > 1.0e9f ||
|
||||
sun_shadow_jitter_overblur > 1.0e9f || sun_shadow_filter_radius > 1.0e9f) {
|
||||
error = "RENDER_PROPERTY_INVALID: world lighting control is outside the bounded range";
|
||||
return false;
|
||||
}
|
||||
world->aodist = ao_distance;
|
||||
world->aoenergy = ao_energy;
|
||||
world->sun_threshold = sun_threshold;
|
||||
world->sun_angle = sun_angle;
|
||||
world->sun_shadow_maximum_resolution = sun_shadow_maximum_resolution;
|
||||
world->sun_shadow_jitter_overblur = sun_shadow_jitter_overblur;
|
||||
world->sun_shadow_filter_radius = sun_shadow_filter_radius;
|
||||
world->id.recalc |= ID_RECALC_PARAMETERS;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool web_engine_blend_main_set_render_properties(WebBlendMainState *state,
|
||||
const char *target_id,
|
||||
const char *properties_json,
|
||||
@@ -5913,13 +5952,32 @@ bool web_engine_blend_main_set_render_properties(WebBlendMainState *state,
|
||||
if (strncmp(target_id, "world:", 6) == 0) {
|
||||
World *world = find_world(state->main, target_id);
|
||||
if (world == nullptr || world->id.lib != nullptr ||
|
||||
!reject_unknown({"color", "exposure", "mist"}) ||
|
||||
!reject_unknown({"color", "exposure", "ambientOcclusionDistance", "ambientOcclusionEnergy", "sunThreshold", "sunAngle", "sunShadowMaximumResolution", "sunShadowJitterOverblur", "sunShadowFilterRadius", "mist"}) ||
|
||||
!read_color("color", &world->horr) ||
|
||||
!read_float("exposure", -20.0f, 20.0f, world->exposure))
|
||||
{
|
||||
if (error.empty()) error = "LINKED_DATA_MUTATION_BLOCKED: World is not editable";
|
||||
return false;
|
||||
}
|
||||
if (properties.contains("ambientOcclusionDistance") || properties.contains("ambientOcclusionEnergy") || properties.contains("sunThreshold") || properties.contains("sunAngle") || properties.contains("sunShadowMaximumResolution") || properties.contains("sunShadowJitterOverblur") || properties.contains("sunShadowFilterRadius")) {
|
||||
const auto lighting_value = [&](const char *key, const float current) {
|
||||
if (!properties.contains(key)) return current;
|
||||
if (!properties[key].is_number()) {
|
||||
error = std::string("RENDER_PROPERTY_INVALID: ") + key + " must be numeric";
|
||||
return -1.0f;
|
||||
}
|
||||
return properties[key].get<float>();
|
||||
};
|
||||
const float ao_distance = lighting_value("ambientOcclusionDistance", world->aodist);
|
||||
const float ao_energy = lighting_value("ambientOcclusionEnergy", world->aoenergy);
|
||||
const float sun_threshold = lighting_value("sunThreshold", world->sun_threshold);
|
||||
const float sun_angle = lighting_value("sunAngle", world->sun_angle);
|
||||
const float sun_shadow_maximum_resolution = lighting_value("sunShadowMaximumResolution", world->sun_shadow_maximum_resolution);
|
||||
const float sun_shadow_jitter_overblur = lighting_value("sunShadowJitterOverblur", world->sun_shadow_jitter_overblur);
|
||||
const float sun_shadow_filter_radius = lighting_value("sunShadowFilterRadius", world->sun_shadow_filter_radius);
|
||||
if (ao_distance < 0.0f || ao_energy < 0.0f || sun_threshold < 0.0f || sun_angle < 0.0f || sun_shadow_maximum_resolution < 0.0f || sun_shadow_jitter_overblur < 0.0f || sun_shadow_filter_radius < 0.0f ||
|
||||
!web_engine_blend_main_set_world_lighting_controls(state, target_id, ao_distance, ao_energy, sun_threshold, sun_angle, sun_shadow_maximum_resolution, sun_shadow_jitter_overblur, sun_shadow_filter_radius, error)) return false;
|
||||
}
|
||||
if (properties.contains("mist")) {
|
||||
const json &mist = properties["mist"];
|
||||
if (!mist.is_object() || mist.empty()) {
|
||||
|
||||
@@ -553,6 +553,16 @@ bool web_engine_blend_main_set_light_clip_start(WebBlendMainState *state,
|
||||
const char *target_id,
|
||||
float clip_start,
|
||||
std::string &error);
|
||||
bool web_engine_blend_main_set_world_lighting_controls(WebBlendMainState *state,
|
||||
const char *target_id,
|
||||
float ao_distance,
|
||||
float ao_energy,
|
||||
float sun_threshold,
|
||||
float sun_angle,
|
||||
float sun_shadow_maximum_resolution,
|
||||
float sun_shadow_jitter_overblur,
|
||||
float sun_shadow_filter_radius,
|
||||
std::string &error);
|
||||
bool web_engine_blend_main_set_scene_properties(WebBlendMainState *state,
|
||||
const char *target_id,
|
||||
const char *properties_json,
|
||||
|
||||
Reference in New Issue
Block a user