diff --git a/CMakeLists.txt b/CMakeLists.txt index 150f789e88..9631ab9fc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # as protobuf could be find transitively by any dependency set(protobuf_MODULE_COMPATIBLE TRUE) -ign_find_package(sdformat11 REQUIRED VERSION 11.2.1) +ign_find_package(sdformat11 REQUIRED VERSION 11.4.0) set(SDF_VER ${sdformat11_VERSION_MAJOR}) #-------------------------------------- diff --git a/src/Conversions.cc b/src/Conversions.cc index a71ef0aafb..aafd9213f7 100644 --- a/src/Conversions.cc +++ b/src/Conversions.cc @@ -568,6 +568,14 @@ msgs::Light ignition::gazebo::convert(const sdf::Light &_in) out.set_spot_inner_angle(_in.SpotInnerAngle().Radian()); out.set_spot_outer_angle(_in.SpotOuterAngle().Radian()); out.set_spot_falloff(_in.SpotFalloff()); + + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + auto header = out.mutable_header()->add_data(); + header->set_key("isLightOn"); + std::string *value = header->add_value(); + *value = std::to_string(_in.LightOn()); + if (_in.Type() == sdf::LightType::POINT) out.set_type(msgs::Light_LightType_POINT); else if (_in.Type() == sdf::LightType::SPOT) @@ -597,6 +605,25 @@ sdf::Light ignition::gazebo::convert(const msgs::Light &_in) out.SetSpotInnerAngle(math::Angle(_in.spot_inner_angle())); out.SetSpotOuterAngle(math::Angle(_in.spot_outer_angle())); out.SetSpotFalloff(_in.spot_falloff()); + + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + bool isLightOn = true; + for (int i = 0; i < _in.header().data_size(); ++i) + { + for (int j = 0; + j < _in.header().data(i).value_size(); ++j) + { + if (_in.header().data(i).key() == + "isLightOn") + { + isLightOn = ignition::math::parseInt( + _in.header().data(i).value(0)); + } + } + } + out.SetLightOn(isLightOn); + if (_in.type() == msgs::Light_LightType_POINT) out.SetType(sdf::LightType::POINT); else if (_in.type() == msgs::Light_LightType_SPOT) diff --git a/src/gui/plugins/component_inspector/ComponentInspector.cc b/src/gui/plugins/component_inspector/ComponentInspector.cc index f2c31ec06f..f16712ce73 100644 --- a/src/gui/plugins/component_inspector/ComponentInspector.cc +++ b/src/gui/plugins/component_inspector/ComponentInspector.cc @@ -153,6 +153,21 @@ void ignition::gazebo::setData(QStandardItem *_item, const msgs::Light &_data) lightType = 2; } + bool isLightOn = true; + for (int i = 0; i < _data.header().data_size(); ++i) + { + for (int j = 0; + j < _data.header().data(i).value_size(); ++j) + { + if (_data.header().data(i).key() == + "isLightOn") + { + isLightOn = ignition::math::parseInt( + _data.header().data(i).value(0)); + } + } + } + _item->setData(QString("Light"), ComponentsModel::RoleNames().key("dataType")); _item->setData(QList({ @@ -176,7 +191,8 @@ void ignition::gazebo::setData(QStandardItem *_item, const msgs::Light &_data) QVariant(_data.spot_outer_angle()), QVariant(_data.spot_falloff()), QVariant(_data.intensity()), - QVariant(lightType) + QVariant(lightType), + QVariant(isLightOn) }), ComponentsModel::RoleNames().key("data")); } @@ -989,7 +1005,8 @@ void ComponentInspector::OnLight( double _attRange, double _attLinear, double _attConstant, double _attQuadratic, bool _castShadows, double _directionX, double _directionY, double _directionZ, double _innerAngle, - double _outerAngle, double _falloff, double _intensity, int _type) + double _outerAngle, double _falloff, double _intensity, int _type, + bool _isLightOn) { std::function cb = [](const ignition::msgs::Boolean &/*_rep*/, const bool _result) @@ -999,6 +1016,14 @@ void ComponentInspector::OnLight( }; ignition::msgs::Light req; + + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + auto header = req.mutable_header()->add_data(); + header->set_key("isLightOn"); + std::string *value = header->add_value(); + *value = std::to_string(_isLightOn); + req.set_name(this->dataPtr->entityName); req.set_id(this->dataPtr->entity); ignition::msgs::Set(req.mutable_diffuse(), diff --git a/src/gui/plugins/component_inspector/ComponentInspector.hh b/src/gui/plugins/component_inspector/ComponentInspector.hh index 9229a24188..0590aa31c7 100644 --- a/src/gui/plugins/component_inspector/ComponentInspector.hh +++ b/src/gui/plugins/component_inspector/ComponentInspector.hh @@ -252,6 +252,7 @@ namespace gazebo /// \param[in] _falloff Falloff of the spotlight /// \param[in] _intensity Intensity of the light /// \param[in] _type light type + /// \param[in] _isLightOn is light on public: Q_INVOKABLE void OnLight( double _rSpecular, double _gSpecular, double _bSpecular, double _aSpecular, double _rDiffuse, double _gDiffuse, @@ -259,7 +260,7 @@ namespace gazebo double _attLinear, double _attConstant, double _attQuadratic, bool _castShadows, double _directionX, double _directionY, double _directionZ, double _innerAngle, double _outerAngle, - double _falloff, double _intensity, int _type); + double _falloff, double _intensity, int _type, bool _isLightOn); /// \brief Callback in Qt thread when physics' properties change. /// \param[in] _stepSize step size diff --git a/src/gui/plugins/component_inspector/ComponentInspector.qml b/src/gui/plugins/component_inspector/ComponentInspector.qml index 545e46d538..c9f68bd1e4 100644 --- a/src/gui/plugins/component_inspector/ComponentInspector.qml +++ b/src/gui/plugins/component_inspector/ComponentInspector.qml @@ -101,12 +101,14 @@ Rectangle { _rDiffuse, _gDiffuse, _bDiffuse, _aDiffuse, _attRange, _attLinear, _attConstant, _attQuadratic, _castShadows, _directionX, _directionY, _directionZ, - _innerAngle, _outerAngle, _falloff, _intensity, _type) { + _innerAngle, _outerAngle, _falloff, _intensity, _type, + _isLightOn) { ComponentInspector.OnLight(_rSpecular, _gSpecular, _bSpecular, _aSpecular, _rDiffuse, _gDiffuse, _bDiffuse, _aDiffuse, _attRange, _attLinear, _attConstant, _attQuadratic, _castShadows, _directionX, _directionY, _directionZ, - _innerAngle, _outerAngle, _falloff, _intensity, _type) + _innerAngle, _outerAngle, _falloff, _intensity, _type, + _isLightOn) } /* diff --git a/src/gui/plugins/component_inspector/Light.qml b/src/gui/plugins/component_inspector/Light.qml index 98cf143e82..f051feb2b3 100644 --- a/src/gui/plugins/component_inspector/Light.qml +++ b/src/gui/plugins/component_inspector/Light.qml @@ -99,6 +99,9 @@ Rectangle { // Loaded item for intensity property var intensityItem: {} + // Loaded item for isLightOn + property var isLightOnItem: {} + // Send new light data to C++ function sendLight() { // TODO(anyone) There's a loss of precision when these values get to C++ @@ -123,7 +126,8 @@ Rectangle { outerAngleItem.value, falloffItem.value, intensityItem.value, - model.data[20] + model.data[20], + isLightOnItem.checked ); } @@ -285,6 +289,37 @@ Rectangle { id: grid width: parent.width + RowLayout { + Rectangle { + color: "transparent" + height: 40 + Layout.preferredWidth: isOnText.width + indentation*3 + + Text { + id : isOnText + text: ' Turn on/off' + leftPadding: 5 + color: Material.theme == Material.Light ? "#444444" : "#bbbbbb" + font.pointSize: 12 + anchors.centerIn: parent + } + } + Item { + Layout.fillWidth: true + height: 40 + + Loader { + id: isOnLoader + anchors.fill: parent + property double numberValue: model.data[21] + sourceComponent: ignSwitch + onLoaded: { + isLightOnItem = isOnLoader.item + } + } + } + } + RowLayout { Rectangle { color: "transparent" diff --git a/src/rendering/RenderUtil.cc b/src/rendering/RenderUtil.cc index 35c347cd33..15e7bdfd43 100644 --- a/src/rendering/RenderUtil.cc +++ b/src/rendering/RenderUtil.cc @@ -2131,11 +2131,35 @@ void RenderUtilPrivate::UpdateLights( auto l = std::dynamic_pointer_cast(node); if (l) { - if (!ignition::math::equal( - l->Intensity(), - static_cast(light.second.intensity()))) + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + bool isLightOn = true; + for (int i = 0; i < light.second.header().data_size(); ++i) + { + for (int j = 0; + j < light.second.header().data(i).value_size(); ++j) + { + if (light.second.header().data(i).key() == + "isLightOn") + { + isLightOn = ignition::math::parseInt( + light.second.header().data(i).value(0)); + } + } + } + + if (isLightOn) + { + if (!ignition::math::equal( + l->Intensity(), + static_cast(light.second.intensity()))) + { + l->SetIntensity(light.second.intensity()); + } + } + else { - l->SetIntensity(light.second.intensity()); + l->SetIntensity(0); } if (light.second.has_diffuse()) { diff --git a/src/systems/user_commands/UserCommands.cc b/src/systems/user_commands/UserCommands.cc index 079245773c..1bd29a7d96 100644 --- a/src/systems/user_commands/UserCommands.cc +++ b/src/systems/user_commands/UserCommands.cc @@ -159,7 +159,28 @@ class LightCommand : public UserCommandBase public: std::function lightEql { [](const msgs::Light &_a, const msgs::Light &_b) { + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + auto getIsLightOn = [](const msgs::Light &_light) -> bool + { + bool isLightOn = true; + for (int i = 0; i < _light.header().data_size(); ++i) + { + for (int j = 0; + j < _light.header().data(i).value_size(); ++j) + { + if (_light.header().data(i).key() == + "isLightOn") + { + isLightOn = ignition::math::parseInt( + _light.header().data(i).value(0)); + } + } + } + return isLightOn; + }; return + getIsLightOn(_a) == getIsLightOn(_b) && _a.type() == _b.type() && _a.name() == _b.name() && math::equal( diff --git a/test/integration/user_commands.cc b/test/integration/user_commands.cc index 4011cfaccf..390f4a4a2e 100644 --- a/test/integration/user_commands.cc +++ b/test/integration/user_commands.cc @@ -760,6 +760,14 @@ TEST_F(UserCommandsTest, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(Light)) req.set_attenuation_constant(0.6f); req.set_attenuation_quadratic(0.001f); req.set_cast_shadows(true); + + // todo(ahcorde) Use the field is_light_off in light.proto from + // Garden on. + auto header = req.mutable_header()->add_data(); + header->set_key("isLightOn"); + std::string *value = header->add_value(); + *value = std::to_string(true); + EXPECT_TRUE(node.Request(service, req, timeout, res, result)); EXPECT_TRUE(result); EXPECT_TRUE(res.data());