diff --git a/src/experimental/filament/filament/light.cc b/src/experimental/filament/filament/light.cc index d00f6097..bdc1f2cd 100644 --- a/src/experimental/filament/filament/light.cc +++ b/src/experimental/filament/filament/light.cc @@ -25,6 +25,7 @@ #include #include #include +#include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/texture.h" namespace mujoco { @@ -32,7 +33,22 @@ namespace mujoco { using filament::math::float3; using filament::math::mat3f; -Light::Light(filament::Engine* engine, const Params& params) +void mjr_defaultLightParams(mjrLightParams* params) { + params->type = mjLIGHT_POINT; + params->texture = nullptr; + params->color[0] = 0; + params->color[1] = 0; + params->color[2] = 0; + params->intensity = 0.0f; + params->cast_shadows = true; + params->range = 10.0f; + params->spot_cone_angle = 180.f; + params->bulb_radius = 0.0f; + params->shadow_map_size = 2048; + params->vsm_blur_width = 0.0f; +} + +Light::Light(filament::Engine* engine, const mjrLightParams& params) : engine_(engine), params_(params) { // Filament treats image-based lights (IBLs) as separate objects (i.e. // filament::IndirectLight) and so we need to handle IBLs specially. @@ -71,9 +87,9 @@ Light::Light(filament::Engine* engine, const Params& params) } filament::LightManager::Builder builder(type); - builder.color(params.color); + builder.color(ReadFloat3(params.color)); builder.intensityCandela(params.intensity); - builder.castShadows(params.castshadow); + builder.castShadows(params.cast_shadows); if (type == filament::LightManager::Type::FOCUSED_SPOT) { builder.spotLightCone(0, params.spot_cone_angle * std::numbers::pi / 180.0f); @@ -85,7 +101,7 @@ Light::Light(filament::Engine* engine, const Params& params) opts.mapSize = 4096; opts.shadowCascades = type == filament::LightManager::Type::DIRECTIONAL ? 4 : 1; - opts.shadowBulbRadius = params.bulbradius; + opts.shadowBulbRadius = params.bulb_radius; opts.mapSize = params.shadow_map_size; if (params.vsm_blur_width > 0.0f) { opts.vsm.elvsm = true; @@ -141,7 +157,10 @@ void Light::SetTransform(filament::math::float3 position, void Light::SetColor(const filament::math::float3& color) { if (!ibl_) { - params_.color = color; + params_.color[0] = color.r; + params_.color[1] = color.g; + params_.color[2] = color.b; + filament::LightManager& lm = engine_->getLightManager(); const filament::LightManager::Instance li = lm.getInstance(entity_); lm.setColor(li, color); diff --git a/src/experimental/filament/filament/light.h b/src/experimental/filament/filament/light.h index 93974972..93ad0bb8 100644 --- a/src/experimental/filament/filament/light.h +++ b/src/experimental/filament/filament/light.h @@ -24,34 +24,38 @@ namespace mujoco { +typedef mjtLightType mjrLightType; + +// Configuration parameters for a light. +struct mjrLightParams { + // The type of light (e.g. spot, point, directional, etc.) + mjrLightType type; + // The texture to use for image lights. + const Texture* texture; + // The color of the light. + float color[3]; + // The intensity of the light, in candela. + float intensity; + // Whether or not the light casts shadows. + mjtByte cast_shadows; + // The range/distance in which the light is effective, in meters. + float range; + // The angle of the spot light cone, in degrees. + float spot_cone_angle; + // The radius of the bulb used for soft shadows. + float bulb_radius; + // The size of the shadow map. + int shadow_map_size; + // Blur width for EL VSM. + float vsm_blur_width; +}; + +void mjr_defaultLightParams(mjrLightParams* params); + // Manages the filament Entities for a single mjvLight. class Light { public: - // Configuration parameters for a light. - struct Params { - // The type of light (e.g. spot, point, directional, etc.) - mjtLightType type; - // The texture to use for image lights. - const Texture* texture = nullptr; - // The color of the light. - filament::math::float3 color = {0, 0, 0}; - // The intensity of the light, in candela. - float intensity = 0.0f; - // Whether or not the light casts shadows. - bool castshadow = true; - // The range/distance in which the light is effective, in meters. - float range = 10.0f; - // The angle of the spot light cone, in degrees. - float spot_cone_angle = 180.f; - // The radius of the bulb used for soft shadows. - float bulbradius = 0.0f; - // The size of the shadow map. - int shadow_map_size = 2048; - // Blur width for EL VSM. - float vsm_blur_width = 0.0f; - }; - - Light(filament::Engine* engine, const Params& params); + Light(filament::Engine* engine, const mjrLightParams& params); ~Light() noexcept; Light(const Light&) = delete; @@ -85,7 +89,7 @@ class Light { filament::IndirectLight* ibl_ = nullptr; utils::Entity entity_; bool enabled_ = true; - Params params_; + mjrLightParams params_; }; } // namespace mujoco diff --git a/src/experimental/filament/filament/scene_bridge.cc b/src/experimental/filament/filament/scene_bridge.cc index ad970247..fd62b392 100644 --- a/src/experimental/filament/filament/scene_bridge.cc +++ b/src/experimental/filament/filament/scene_bridge.cc @@ -207,7 +207,8 @@ void SceneBridge::SetEnvironmentLight(std::string_view filename, fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(object_mgr_, filename); - Light::Params params; + mjrLightParams params; + mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.texture = fallback_ibl_texture_.get(); params.intensity = intensity; @@ -233,7 +234,8 @@ void SceneBridge::PrepareLights() { total_light_intensity += model->light_intensity[i]; if (model->light_type[i] == mjLIGHT_IMAGE) { - Light::Params params; + mjrLightParams params; + mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.texture = model_objects_->GetTexture(model->light_texid[i]); params.intensity = model->light_intensity[i]; @@ -242,11 +244,14 @@ void SceneBridge::PrepareLights() { lights_.emplace_back(std::move(light_obj)); has_image_based_light = true; } else { - Light::Params params; - params.color = ReadFloat3(model->light_diffuse); + mjrLightParams params; + mjr_defaultLightParams(¶ms); + params.color[0] = model->light_diffuse[0]; + params.color[1] = model->light_diffuse[1]; + params.color[2] = model->light_diffuse[2]; params.type = (mjtLightType)model->light_type[i]; - params.castshadow = model->light_castshadow[i]; - params.bulbradius = model->light_bulbradius[i]; + params.cast_shadows = model->light_castshadow[i]; + params.bulb_radius = model->light_bulbradius[i]; params.range = model->light_range[i]; params.intensity = model->light_intensity[i]; params.shadow_map_size = default_shadow_map_size_; @@ -267,15 +272,15 @@ void SceneBridge::PrepareLights() { // Add a placeholder (black) headlight as our last light. Going forward, we'll // assume lights_.back() is always the headlight. { - Light::Params params; - params.color = float3(0, 0, 0); + mjrLightParams params; + mjr_defaultLightParams(¶ms); // We break with the spec here slightly and use a spot light for the head // light instead of a directional params. This is because filament only // supports a single directional light, and we'd rather allow a scene // light to be that directional params. It's also a bit odd for a // directional light to move with the camera. params.type = mjLIGHT_SPOT; - params.castshadow = 0; + params.cast_shadows = 0; params.intensity = 0.0f; params.spot_cone_angle = 90.0f; auto light_obj = std::make_unique(engine, params); @@ -290,7 +295,8 @@ void SceneBridge::PrepareLights() { // Create a black indirect light to ensure that the skybox is // oriented to respect mujoco's Z-up convention. filament::Engine* engine = object_mgr_->GetEngine(); - Light::Params params; + mjrLightParams params; + mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.intensity = 10.0f; fallback_ibl_ = std::make_unique(engine, params); @@ -304,7 +310,8 @@ void SceneBridge::PrepareLights() { // Create a fallback environment light. fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(object_mgr_); - Light::Params params; + mjrLightParams params; + mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.texture = fallback_ibl_texture_.get(); params.intensity = fallback_environment_light_intensity_;