ppovb5fc7/gazebo/plugins/ShaderParamVisualPlugin.cc

155 lines
4.5 KiB
C++
Raw Permalink Normal View History

2019-03-25 11:01:43 +08:00
/*
* Copyright (C) 2018 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <mutex>
#include <vector>
#include <gazebo/common/Time.hh>
#include <gazebo/rendering/Scene.hh>
#include <gazebo/rendering/Visual.hh>
#include <gazebo/transport/Node.hh>
#include "ShaderParamVisualPlugin.hh"
namespace gazebo
{
/// \internal
/// \brief Private data for the ShaderParamVisualPlugin class.
class ShaderParamVisualPluginPrivate
{
/// \brief Visual whose color and vertices will be changed.
public: rendering::VisualPtr visual;
/// \brief A list of params that requires setting sim time.
/// Each element is a pair of <paramName, shaderType>
public: std::vector<std::pair<std::string, std::string>> simTimeParams;
/// \brief Connects to render update event.
public: event::ConnectionPtr updateConnection;
/// \brief The current simulation time.
public: common::Time currentSimTime;
/// \brief Node used for communication.
public: transport::NodePtr node;
/// \brief Subscriber to world info.
public: transport::SubscriberPtr infoSub;
/// \brief Mutex to protect sim time updates.
public: std::mutex mutex;
};
}
using namespace gazebo;
GZ_REGISTER_VISUAL_PLUGIN(ShaderParamVisualPlugin)
/////////////////////////////////////////////////
ShaderParamVisualPlugin::ShaderParamVisualPlugin()
: dataPtr(new ShaderParamVisualPluginPrivate)
{
}
/////////////////////////////////////////////////
ShaderParamVisualPlugin::~ShaderParamVisualPlugin()
{
}
/////////////////////////////////////////////////
void ShaderParamVisualPlugin::Load(rendering::VisualPtr _visual,
sdf::ElementPtr _sdf)
{
if (!_visual || !_sdf)
{
gzerr << "No visual or sdf element specified. Plugin won't load."
<< std::endl;
return;
}
this->dataPtr->visual = _visual;
if (!_sdf->HasElement("param"))
{
gzwarn << "No <param> specified, exiting" << std::endl;
return;
}
// loop and set all shader params
sdf::ElementPtr paramElem = _sdf->GetElement("param");
while (paramElem)
{
if (!paramElem->HasElement("type") ||
!paramElem->HasElement("name") ||
!paramElem->HasElement("value"))
{
gzerr << "<param> must have <type>, <name> and <value>" << std::endl;
paramElem = paramElem->GetNextElement("param");
continue;
}
std::string shaderType = paramElem->Get<std::string>("type");
std::string paramName = paramElem->Get<std::string>("name");
std::string value = paramElem->Get<std::string>("value");
// TIME is reserved keyword for sim time
if (value == "TIME")
{
this->dataPtr->simTimeParams.push_back(
std::make_pair(paramName, shaderType));
}
else
{
this->dataPtr->visual->SetMaterialShaderParam(
paramName, shaderType, value);
}
paramElem = paramElem->GetNextElement("param");
}
// Connect to the world update signal
this->dataPtr->updateConnection = event::Events::ConnectPreRender(
std::bind(&ShaderParamVisualPlugin::Update, this));
// only subscribe to pose topic to get sim time if a param requests it
if (!this->dataPtr->simTimeParams.empty())
{
this->dataPtr->node = transport::NodePtr(new transport::Node());
this->dataPtr->node->Init();
this->dataPtr->infoSub = this->dataPtr->node->Subscribe(
"~/pose/local/info", &ShaderParamVisualPlugin::OnInfo, this);
}
}
/////////////////////////////////////////////////
void ShaderParamVisualPlugin::Update()
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
// set sim time on every render update
for (auto &p : this->dataPtr->simTimeParams)
{
this->dataPtr->visual->SetMaterialShaderParam(p.first, p.second,
std::to_string(this->dataPtr->currentSimTime.Double()));
}
}
/////////////////////////////////////////////////
void ShaderParamVisualPlugin::OnInfo(ConstPosesStampedPtr &_msg)
{
std::lock_guard<std::mutex> lock(this->dataPtr->mutex);
// we are only interested in sim time
this->dataPtr->currentSimTime = msgs::Convert(_msg->time());
}