From 895dfe0d2714909fdbc8f6c9f5ec29ba2fdd675d Mon Sep 17 00:00:00 2001 From: Adnan Munawar Date: Wed, 13 Mar 2024 06:10:13 +0500 Subject: [PATCH 1/2] Adding support for setting light attenuation in ADF file Usage: In the light data, set the three normalized variables as attenuation: {constant: 1.0, linear: 0.0, quadratic: 0.0} --- adf_loader/version_1_0/adf_loader_1_0.cpp | 8 ++++++++ ambf_framework/afAttributes.h | 8 ++++++++ ambf_framework/afFramework.cpp | 8 +++++++- external/chai3d/src/lighting/CSpotLight.cpp | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/adf_loader/version_1_0/adf_loader_1_0.cpp b/adf_loader/version_1_0/adf_loader_1_0.cpp index 867a102a1..61cf330fc 100644 --- a/adf_loader/version_1_0/adf_loader_1_0.cpp +++ b/adf_loader/version_1_0/adf_loader_1_0.cpp @@ -1162,6 +1162,7 @@ bool ADFLoader_1_0::loadLightAttribs(YAML::Node *a_node, afLightAttributes *attr YAML::Node spotExponentNode = node["spot exponent"]; YAML::Node shadowQualityNode = node["shadow quality"]; YAML::Node cuttOffAngleNode = node["cutoff angle"]; + YAML::Node attenuationNode = node["attenuation"]; bool valid = true; @@ -1214,6 +1215,13 @@ bool ADFLoader_1_0::loadLightAttribs(YAML::Node *a_node, afLightAttributes *attr attribs->m_cuttoffAngle = cuttOffAngleNode.as(); } + if (attenuationNode.IsDefined()){ + attribs->m_attenuationDefined = true; + if (attenuationNode["constant"].IsDefined()) attribs->m_constantAttenuation = attenuationNode["constant"].as(); + if (attenuationNode["linear"].IsDefined()) attribs->m_linearAttenuation = attenuationNode["linear"].as(); + if (attenuationNode["quadratic"].IsDefined()) attribs->m_quadraticAttenuation = attenuationNode["quadratic"].as(); + } + return valid; } diff --git a/ambf_framework/afAttributes.h b/ambf_framework/afAttributes.h index bc527b73c..77b676437 100644 --- a/ambf_framework/afAttributes.h +++ b/ambf_framework/afAttributes.h @@ -623,10 +623,18 @@ struct afLightAttributes: public afBaseObjectAttributes afLightAttributes(){ m_spotExponent = 0.7; m_cuttoffAngle = 0.7; + m_constantAttenuation = 1.0; + m_linearAttenuation = 0.0; + m_quadraticAttenuation = 0.0; + m_attenuationDefined = false; } double m_spotExponent; double m_cuttoffAngle; + double m_constantAttenuation; + double m_linearAttenuation; + double m_quadraticAttenuation; + bool m_attenuationDefined; afVector3d m_direction; afShadowQualityType m_shadowQuality; diff --git a/ambf_framework/afFramework.cpp b/ambf_framework/afFramework.cpp index 4ed92c94a..b479e4773 100644 --- a/ambf_framework/afFramework.cpp +++ b/ambf_framework/afFramework.cpp @@ -7216,6 +7216,12 @@ bool afLight::createFromAttribs(afLightAttributes *a_attribs) m_spotLight->setCutOffAngleDeg(a_attribs->m_cuttoffAngle * (180/3.14)); m_spotLight->setShadowMapEnabled(true); + if (a_attribs->m_attenuationDefined){ + m_spotLight->setAttConstant(a_attribs->m_constantAttenuation); + m_spotLight->setAttLinear(a_attribs->m_linearAttenuation); + m_spotLight->setAttQuadratic(a_attribs->m_quadraticAttenuation); + } + switch (a_attribs->m_shadowQuality) { case afShadowQualityType::NO_SHADOW: m_spotLight->setShadowMapEnabled(false); @@ -8302,7 +8308,7 @@ bool afVolume::createFromAttribs(afVolumeAttributes *a_attribs) m_voxelObject = new cVoxelObject(); // Setting transparency before setting the texture ensures that the rendering does not show empty spaces as black // and the depth point cloud is able to see the volume - m_voxelObject->setTransparencyLevel(1.0); +// m_voxelObject->setTransparencyLevel(1.0); cTexture3dPtr texture = cTexture3d::create(); texture->setImage(m_multiImage); diff --git a/external/chai3d/src/lighting/CSpotLight.cpp b/external/chai3d/src/lighting/CSpotLight.cpp index d5b6ef388..c2e0721f8 100644 --- a/external/chai3d/src/lighting/CSpotLight.cpp +++ b/external/chai3d/src/lighting/CSpotLight.cpp @@ -181,6 +181,11 @@ void cSpotLight::renderLightSource(cRenderOptions& a_options) // set cutoff angle glLightf(m_glLightNumber, GL_SPOT_CUTOFF, m_cutOffAngleDeg); + // Set Attenuation Constants + glLightf(m_glLightNumber, GL_CONSTANT_ATTENUATION, getAttConstant()); + glLightf(m_glLightNumber, GL_LINEAR_ATTENUATION, getAttLinear()); + glLightf(m_glLightNumber, GL_QUADRATIC_ATTENUATION, getAttQuadratic()); + #endif } From 054534d625974ae0c2b8e99e057fb8a730d9c620 Mon Sep 17 00:00:00 2001 From: Adnan Munawar Date: Fri, 15 Mar 2024 05:45:03 +0500 Subject: [PATCH 2/2] Implement setting of light attenuation via ROS Param Server Set as rosparam set /attenuation/ Where can be for example /ambf/env/lights/light1 and type is constant/linear/quadratic Can also query the light params using rosparam get --- ambf_framework/afFramework.cpp | 6 ++--- ambf_framework/afFramework.h | 12 +++++++++ .../core/ros_comm_plugin/ObjectCommPlugin.cpp | 7 +++++ .../ambf_server/include/ambf_server/Light.h | 8 +++++- ambf_ros_modules/ambf_server/src/Light.cpp | 27 +++++++++++++++++++ 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/ambf_framework/afFramework.cpp b/ambf_framework/afFramework.cpp index b479e4773..fcfc63c54 100644 --- a/ambf_framework/afFramework.cpp +++ b/ambf_framework/afFramework.cpp @@ -7217,9 +7217,9 @@ bool afLight::createFromAttribs(afLightAttributes *a_attribs) m_spotLight->setShadowMapEnabled(true); if (a_attribs->m_attenuationDefined){ - m_spotLight->setAttConstant(a_attribs->m_constantAttenuation); - m_spotLight->setAttLinear(a_attribs->m_linearAttenuation); - m_spotLight->setAttQuadratic(a_attribs->m_quadraticAttenuation); + setConstantAttenuation(a_attribs->m_constantAttenuation); + setLinearAttenuation(a_attribs->m_linearAttenuation); + setQuadraticAttenuation(a_attribs->m_quadraticAttenuation); } switch (a_attribs->m_shadowQuality) { diff --git a/ambf_framework/afFramework.h b/ambf_framework/afFramework.h index a764aedeb..de8c536c6 100644 --- a/ambf_framework/afFramework.h +++ b/ambf_framework/afFramework.h @@ -2083,6 +2083,18 @@ class afLight: public afBaseObject{ cGenericLight* getInternalLight(); + double getConstantAttenuation(){return m_spotLight->getAttConstant();} + + double getLinearAttenuation(){return m_spotLight->getAttLinear();} + + double getQuadraticAttenuation(){return m_spotLight->getAttQuadratic();} + + void setConstantAttenuation(double att){m_spotLight->setAttConstant(att);} + + void setLinearAttenuation(double att){m_spotLight->setAttLinear(att);} + + void setQuadraticAttenuation(double att){m_spotLight->setAttQuadratic(att);} + protected: cSpotLight* m_spotLight; diff --git a/ambf_plugins/core/ros_comm_plugin/ObjectCommPlugin.cpp b/ambf_plugins/core/ros_comm_plugin/ObjectCommPlugin.cpp index 787e00508..db3a61052 100644 --- a/ambf_plugins/core/ros_comm_plugin/ObjectCommPlugin.cpp +++ b/ambf_plugins/core/ros_comm_plugin/ObjectCommPlugin.cpp @@ -532,6 +532,10 @@ void afObjectCommunicationPlugin::lightFetchCommand(afLightPtr lightPtr, double lightPtr->setCutOffAngle(cutoff_angle); lightPtr->resolveParent(parent_name); + + lightPtr->setConstantAttenuation(m_lightCommPtr->get_constant_attenuation()); + lightPtr->setLinearAttenuation(m_lightCommPtr->get_linear_attenuation()); + lightPtr->setQuadraticAttenuation(m_lightCommPtr->get_quadratic_attenuation()); } m_read_count = 0; @@ -544,6 +548,9 @@ void afObjectCommunicationPlugin::lightUpdateState(afLightPtr lightPtr, double d m_lightCommPtr->set_cuttoff_angle(lightPtr->getCutOffAngle()); m_lightCommPtr->set_type(ambf_comm::LightType::SPOT); m_lightCommPtr->set_parent_name(lightPtr->m_parentName); + m_lightCommPtr->set_attenuation(lightPtr->getConstantAttenuation(), + lightPtr->getLinearAttenuation(), + lightPtr->getQuadraticAttenuation()); m_lightCommPtr->set_params_on_server(); m_paramsSet = true; diff --git a/ambf_ros_modules/ambf_server/include/ambf_server/Light.h b/ambf_ros_modules/ambf_server/include/ambf_server/Light.h index 73c18ffee..71a5b0dfb 100644 --- a/ambf_ros_modules/ambf_server/include/ambf_server/Light.h +++ b/ambf_ros_modules/ambf_server/include/ambf_server/Light.h @@ -59,7 +59,8 @@ enum class LightType{ enum class LightParamsEnum{ cuttoff_angle, parent_name, - type + type, + attenuation }; @@ -76,10 +77,14 @@ class LightParams{ // Setters void set_type(LightType val){m_light_type = val;} void set_cuttoff_angle(double val){m_cuttoff_angle = val;} + void set_attenuation(double cons, double lin, double quad); // Getters LightType get_type(){return m_light_type;} double get_cuttoff_angle(){return m_cuttoff_angle;} + double get_constant_attenuation(){return m_attenuation["constant"];} + double get_linear_attenuation(){return m_attenuation["linear"];} + double get_quadratic_attenuation(){return m_attenuation["quadratic"];} // This a flag to check if any param has been updated bool m_paramsChanged; @@ -92,6 +97,7 @@ class LightParams{ // Datatyped Variables for params defined on the server double m_type; double m_cuttoff_angle; + std::map m_attenuation; // Constant, Linear and Quadratic Attenuation LightType m_light_type; }; diff --git a/ambf_ros_modules/ambf_server/src/Light.cpp b/ambf_ros_modules/ambf_server/src/Light.cpp index 6dec256f8..f4f1be5e4 100644 --- a/ambf_ros_modules/ambf_server/src/Light.cpp +++ b/ambf_ros_modules/ambf_server/src/Light.cpp @@ -56,28 +56,42 @@ const std::string light_param_enum_to_str(LightParamsEnum enumVal) if (enumVal == LightParamsEnum::cuttoff_angle) return "cutoff_angle"; else if (enumVal == LightParamsEnum::parent_name) return "parent_name"; else if (enumVal == LightParamsEnum::type) return "type"; + else if (enumVal == LightParamsEnum::attenuation) return "attenuation"; return ""; } LightParams::LightParams(){ m_paramsChanged = false; + m_attenuation["constant"] = 1.0; + m_attenuation["linear"] = 0.0; + m_attenuation["quadratic"] = 0.0; +} + +void LightParams::set_attenuation(double cons, double lin, double quad) +{ + m_attenuation["constant"] = cons; + m_attenuation["linear"] = lin; + m_attenuation["quadratic"] = quad; } void Light::set_params_on_server(){ nodePtr->setParam(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::cuttoff_angle), m_cuttoff_angle); nodePtr->setParam(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::parent_name), m_State.parent_name.data); nodePtr->setParam(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::type), light_type_enum_to_str(m_light_type)); + nodePtr->setParam(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::attenuation), m_attenuation); } void Light::update_params_from_server(){ double ca; std::string pn; std::string lt; + std::map att; LightType lt_enum; nodePtr->getParamCached(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::cuttoff_angle), ca); nodePtr->getParamCached(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::parent_name), pn); nodePtr->getParamCached(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::type), lt); + nodePtr->getParamCached(m_base_prefix + "/" + light_param_enum_to_str(LightParamsEnum::attenuation), att); if (lt.compare(light_type_enum_to_str(LightType::SPOT)) == 0){ lt_enum = LightType::SPOT; @@ -106,6 +120,19 @@ void Light::update_params_from_server(){ std::cerr << "INFO! PARAMS CHANGED FOR \"" << m_name << "\"\n"; } + std::map::iterator it; + for (it = m_attenuation.begin() ; it != m_attenuation.end() ; ++it){ + try{ + if (att[it->first] != it->second){ + m_paramsChanged = true; + it->second = att[it->first]; + } + } + catch (...){ + // Do nothing + } + } + // Finally update the local copies of the params m_cuttoff_angle = ca; m_State.parent_name.data = pn;