Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support shininess value for each Visual in a Model #3235

Merged
merged 3 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions gazebo/physics/Link.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1545,13 +1545,21 @@ void Link::UpdateVisualMsg()
common::resolveSdfPose(visualDom->SemanticPose()));
}
bool newVis = true;
std::string linkName = this->GetScopedName();
std::string visName = this->GetScopedName() + "::" + msg.name();

if (visualElem->HasElement("material"))
{
sdf::ElementPtr matElem = visualElem->GetElement("material");
if (matElem->HasElement("shininess"))
{
this->world->SetVisualShininess(
visName, matElem->Get<double>("shininess"));
}
}

// update visual msg if it exists
for (auto &iter : this->visuals)
{
std::string visName = linkName + "::" +
visualElem->Get<std::string>("name");
if (iter.second.name() == visName)
{
iter.second.mutable_geometry()->CopyFrom(msg.geometry());
Expand All @@ -1563,7 +1571,6 @@ void Link::UpdateVisualMsg()
// add to visual msgs if not found.
if (newVis)
{
std::string visName = this->GetScopedName() + "::" + msg.name();
msg.set_name(visName);
msg.set_id(physics::getUniqueId());
msg.set_parent_name(this->GetScopedName());
Expand Down
59 changes: 29 additions & 30 deletions gazebo/physics/World.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,14 @@ void World::Load(sdf::ElementPtr _sdf)
shadowCasterRenderBackFacesService << "]" << std::endl;
}

std::string materialShininessService("/shininess");
if (!this->dataPtr->ignNode.Advertise(materialShininessService,
&World::MaterialShininessService, this))
{
gzerr << "Error advertising service ["
<< materialShininessService << "]" << std::endl;
}

// This should come before loading of entities
sdf::ElementPtr physicsElem = this->dataPtr->sdf->GetElement("physics");

Expand Down Expand Up @@ -1259,35 +1267,6 @@ ModelPtr World::LoadModel(sdf::ElementPtr _sdf , BasePtr _parent)
}
}

if (_sdf->HasElement("link"))
{
sdf::ElementPtr linkElem = _sdf->GetElement("link");
if (linkElem->HasElement("visual") &&
linkElem->GetElement("visual")->HasElement("material"))
{
sdf::ElementPtr matElem = linkElem->GetElement("visual")->
GetElement("material");

if (matElem->HasElement("shininess"))
{
this->dataPtr->materialShininessMap[modelName] =
matElem->Get<double>("shininess");
}
else
{
this->dataPtr->materialShininessMap[modelName] = 0;
}

std::string materialShininessService("/" + modelName + "/shininess");
if (!this->dataPtr->ignNode.Advertise(materialShininessService,
&World::MaterialShininessService, this))
{
gzerr << "Error advertising service ["
<< materialShininessService << "]" << std::endl;
}
}
}

model = this->dataPtr->physicsEngine->CreateModel(_parent);
model->SetWorld(shared_from_this());
model->Load(_sdf);
Expand Down Expand Up @@ -3467,11 +3446,31 @@ bool World::ShadowCasterRenderBackFacesService(ignition::msgs::Boolean &_res)
return true;
}

//////////////////////////////////////////////////
void World::SetVisualShininess(const std::string &_scopedName,
double _shininess)
{
std::lock_guard<std::mutex> lock(this->dataPtr->materialShininessMutex);
this->dataPtr->materialShininessMap[_scopedName] = _shininess;
}

//////////////////////////////////////////////////
double World::ShininessByScopedName(const std::string &_scopedName) const
{
std::lock_guard<std::mutex> lock(this->dataPtr->materialShininessMutex);
if (this->dataPtr->materialShininessMap.find(_scopedName) !=
this->dataPtr->materialShininessMap.end())
{
return this->dataPtr->materialShininessMap.at(_scopedName);
}
return 0.0;
}

//////////////////////////////////////////////////
bool World::MaterialShininessService(
const ignition::msgs::StringMsg &_req, msgs::Any &_res)
{
_res.set_type(msgs::Any::DOUBLE);
_res.set_double_value(this->dataPtr->materialShininessMap[_req.data()]);
_res.set_double_value(this->ShininessByScopedName(_req.data()));
return true;
}
15 changes: 14 additions & 1 deletion gazebo/physics/World.hh
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,15 @@ namespace gazebo
public: std::string UniqueModelName(const std::string &_name);

/// \brief Set callback 'waitForSensors'
/// \param[in] function to be called
/// \param[in] _func function to be called
public: void SetSensorWaitFunc(std::function<void(double, double)> _func);

/// \brief Set Visual shininess value by scoped name
/// \param[in] _scopedName Scoped name of visual.
/// \param[in] _shininess Shininess value.
public: void SetVisualShininess(const std::string &_scopedName,
double _shininess);

/// \cond
/// This is an internal function.
/// \brief Get a model by id.
Expand Down Expand Up @@ -678,6 +684,13 @@ namespace gazebo
private: bool MaterialShininessService(
const ignition::msgs::StringMsg &_request, msgs::Any &_response);

/// \brief Helper function for getting shininess values by scoped
/// visual name.
/// \param[in] _scopedName Scoped visual name.
/// \return Shininess value.
private: double ShininessByScopedName(const std::string &_scopedName)
const;

/// \internal
/// \brief Private data pointer.
private: std::unique_ptr<WorldPrivate> dataPtr;
Expand Down
4 changes: 4 additions & 0 deletions gazebo/physics/WorldPrivate.hh
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ namespace gazebo
/// \brief Shadow caster render back faces from scene SDF
public: bool shadowCasterRenderBackFaces = true;

/// \brief This mutex is used to by the SetVisualShininess and
/// ShininessByScopedName methods to protect materialShininessMap.
public: std::mutex materialShininessMutex;

/// \brief Shininess values from scene SDF
public: std::map<std::string, double> materialShininessMap;
};
Expand Down
5 changes: 2 additions & 3 deletions gazebo/rendering/Visual.cc
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,9 @@ void Visual::Load()
ignition::transport::Node node;
msgs::Any rep;

const std::string visualName =
this->Name().substr(0, this->Name().find(":"));
const std::string visualName = this->Name();

const std::string serviceName = "/" + visualName + "/shininess";
const std::string serviceName = "/shininess";

const std::string validServiceName =
ignition::transport::TopicUtils::AsValidTopic(serviceName);
Expand Down
18 changes: 10 additions & 8 deletions test/integration/visual_shininess.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ class VisualShininess : public RenderingFixture
};

/////////////////////////////////////////////////
void CheckShininessService(const std::string &_modelName,
void CheckShininessService(const std::string &_scopedName,
double _expectedShininess)
{
std::string serviceName = '/' + _modelName + "/shininess";
std::string serviceName = "/shininess";
ignition::transport::Node ignNode;

{
Expand All @@ -43,22 +43,23 @@ void CheckShininessService(const std::string &_modelName,
gazebo::msgs::Any reply;
const unsigned int timeout = 3000;
bool result = false;
request.set_data(_modelName);
request.set_data(_scopedName);
EXPECT_TRUE(ignNode.Request(serviceName, request, timeout, reply, result));
EXPECT_TRUE(result);
EXPECT_EQ(msgs::Any_ValueType_DOUBLE, reply.type());
EXPECT_DOUBLE_EQ(_expectedShininess, reply.double_value()) << _modelName;
EXPECT_DOUBLE_EQ(_expectedShininess, reply.double_value()) << _scopedName;
}

/////////////////////////////////////////////////
TEST_F(VisualShininess, ShapesShininessServices)
{
Load("worlds/shapes_shininess.world", true);

CheckShininessService("ground_plane", 0.0);
CheckShininessService("box", 1.0);
CheckShininessService("sphere", 5.0);
CheckShininessService("cylinder", 10.0);
CheckShininessService("ground_plane::link::visual", 0.0);
CheckShininessService("box::link::visual", 1.0);
CheckShininessService("box::link::visual2", 10.0);
CheckShininessService("sphere::link::visual", 5.0);
CheckShininessService("cylinder::link::visual", 10.0);
}

/////////////////////////////////////////////////
Expand Down Expand Up @@ -101,6 +102,7 @@ TEST_F(VisualShininess, ShapesShininess)

std::unordered_map<std::string, double> nameToShininess;
nameToShininess["box::link::visual"] = 1.0;
nameToShininess["box::link::visual2"] = 10.0;
nameToShininess["sphere::link::visual"] = 5.0;
nameToShininess["cylinder::link::visual"] = 10.0;

Expand Down
12 changes: 12 additions & 0 deletions worlds/shapes_shininess.world
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
</box>
</geometry>
</visual>
<visual name="visual2">
<pose>0 0 3 0 0 0</pose>
<material>
<specular>1 0 0 1</specular>
<shininess>10</shininess>
</material>
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>
</model>
<model name="sphere">
Expand Down