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

Particle system - Part4 #615

Merged
merged 14 commits into from
Feb 18, 2021
21 changes: 21 additions & 0 deletions examples/worlds/particle_emitter.sdf
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
<?xml version="1.0" ?>

<!--
Launch this example with:

ign gazebo -r particle_emitter.sdf

Try modifying some parameters of the emitter:

To disable the particle emitter:

ign topic -t /model/smoke_generator/particle_emitter/smoke_generator -m ignition.msgs.ParticleEmitter -p 'name: "smoke_generator" pose { position { } orientation { w: 1 } } size { x: 1 y: 1 z: 1 } rate: 10 emitting: false particle_size { x: 1 y: 1 z: 1 } lifetime: 2 material { header { data { key: "double_sided" value: "0" } } ambient { a: 1 } diffuse { r: 0.7 g: 0.7 b: 0.7 a: 1 } specular { a: 1 } emissive { a: 1 } lighting: true pbr { type: METAL albedo_map: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smoke.png" metalness: 0.5 roughness: 0.5 } } min_velocity: 10 max_velocity: 20 color_start { r: 1 g: 1 b: 1 a: 1 } color_end { r: 1 g: 1 b: 1 a: 1 } scale_rate: 10 color_range_image: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smokecolors.png"'

Enable back the particle emitter:

ign topic -t /model/smoke_generator/particle_emitter/smoke_generator -m ignition.msgs.ParticleEmitter -p 'name: "smoke_generator" pose { position { } orientation { w: 1 } } size { x: 1 y: 1 z: 1 } rate: 10 emitting: true particle_size { x: 1 y: 1 z: 1 } lifetime: 2 material { header { data { key: "double_sided" value: "0" } } ambient { a: 1 } diffuse { r: 0.7 g: 0.7 b: 0.7 a: 1 } specular { a: 1 } emissive { a: 1 } lighting: true pbr { type: METAL albedo_map: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smoke.png" metalness: 0.5 roughness: 0.5 } } min_velocity: 10 max_velocity: 20 color_start { r: 1 g: 1 b: 1 a: 1 } color_end { r: 1 g: 1 b: 1 a: 1 } scale_rate: 10 color_range_image: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smokecolors.png"'

Then, change the particle rate:

ign topic -t /model/smoke_generator/particle_emitter/smoke_generator -m ignition.msgs.ParticleEmitter -p 'name: "smoke_generator" pose { position { } orientation { w: 1 } } size { x: 1 y: 1 z: 1 } rate: 100 emitting: true particle_size { x: 1 y: 1 z: 1 } lifetime: 2 material { header { data { key: "double_sided" value: "0" } } ambient { a: 1 } diffuse { r: 0.7 g: 0.7 b: 0.7 a: 1 } specular { a: 1 } emissive { a: 1 } lighting: true pbr { type: METAL albedo_map: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smoke.png" metalness: 0.5 roughness: 0.5 } } min_velocity: 10 max_velocity: 20 color_start { r: 1 g: 1 b: 1 a: 1 } color_end { r: 1 g: 1 b: 1 a: 1 } scale_rate: 10 color_range_image: "/home/caguero/.ignition/fuel/fuel.ignitionrobotics.org/caguero/models/smoke_generator/2/materials/textures/smokecolors.png"'
-->

<sdf version="1.6">
<world name="particle_emitters">

Expand Down
7 changes: 7 additions & 0 deletions include/ignition/gazebo/components/ParticleEmitter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ namespace components
serializers::MsgSerializer>;
IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.ParticleEmitter",
ParticleEmitter)

/// \brief A component that contains a particle emitter command.
using ParticleEmitterCmd = Component<msgs::ParticleEmitter,
class ParticleEmitterCmdTag,
serializers::MsgSerializer>;
IGN_GAZEBO_REGISTER_COMPONENT("ign_gazebo_components.ParticleEmitterCmd",
ParticleEmitterCmd)
}
}
}
Expand Down
15 changes: 11 additions & 4 deletions include/ignition/gazebo/rendering/SceneManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,20 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
public: rendering::LightPtr CreateLight(Entity _id,
const sdf::Light &_light, Entity _parentId);

/// \brief Create a particle emitter
/// \brief Create a particle emitter.
/// \param[in] _id Unique particle emitter id
/// \param[in] _emitter Particle emitter data
/// \param[in] _parentId Parent id
/// \return Particle emitter object created
public: rendering::ParticleEmitterPtr CreateParticleEmitter(Entity _id,
const msgs::ParticleEmitter &_emitter, Entity _parentId);
/// \return Default particle emitter object created
public: rendering::ParticleEmitterPtr CreateParticleEmitter(
Entity _id, const msgs::ParticleEmitter &_emitter, Entity _parentId);

/// \brief Update an existing particle emitter
/// \brief _id Emitter id to update
/// \brief _emitter Data to update the particle emitter
/// \return Particle emitter updated
public: rendering::ParticleEmitterPtr UpdateParticleEmitter(Entity _id,
adlarkin marked this conversation as resolved.
Show resolved Hide resolved
const msgs::ParticleEmitter &_emitter);

/// \brief Ignition sensors is the one responsible for adding sensors
/// to the scene. Here we just keep track of it and make sure it has
Expand Down
1 change: 1 addition & 0 deletions src/gui/plugins/scene3d/Scene3D.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2752,6 +2752,7 @@ void Scene3D::Update(const UpdateInfo &_info,
msgs::Pose poseMsg = msgs::Convert(renderWindow->CameraPose());
this->dataPtr->cameraPosePub.Publish(poseMsg);
}
this->dataPtr->renderUtil->UpdateECM(_info, _ecm);
this->dataPtr->renderUtil->UpdateFromECM(_info, _ecm);
adlarkin marked this conversation as resolved.
Show resolved Hide resolved

// check if video recording is enabled and if we need to lock step
Expand Down
47 changes: 47 additions & 0 deletions src/rendering/RenderUtil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <ignition/math/Matrix4.hh>
#include <ignition/math/Pose3.hh>

#include <ignition/msgs/Utility.hh>

#include <ignition/rendering.hh>
#include <ignition/rendering/RenderEngine.hh>
#include <ignition/rendering/RenderingIface.hh>
Expand Down Expand Up @@ -169,6 +171,12 @@ class ignition::gazebo::RenderUtilPrivate
public: std::vector<std::tuple<Entity, msgs::ParticleEmitter, Entity>>
newParticleEmitters;

/// \brief New particle emitter commands to be requested.
/// The map key and value are: entity id of the particle emitter to
/// update, and particle emitter msg
public: std::unordered_map<Entity, msgs::ParticleEmitter>
newParticleEmittersCmds;

/// \brief Map of ids of entites to be removed and sim iteration when the
/// remove request is received
public: std::unordered_map<Entity, uint64_t> removeEntities;
Expand Down Expand Up @@ -295,6 +303,28 @@ void RenderUtil::UpdateECM(const UpdateInfo &/*_info*/,
EntityComponentManager &_ecm)
{
std::lock_guard<std::mutex> lock(this->dataPtr->updateMutex);

// particle emitters commands
_ecm.Each<components::ParticleEmitterCmd>(
[&](const Entity &_entity,
const components::ParticleEmitterCmd *_emitterCmd) -> bool
{
// store emitter properties and update them in rendering thread
this->dataPtr->newParticleEmittersCmds[_entity] =
_emitterCmd->Data();

// update pose comp here
if (_emitterCmd->Data().has_pose())
{
auto poseComp = _ecm.Component<components::Pose>(_entity);
if (poseComp)
poseComp->Data() = msgs::Convert(_emitterCmd->Data().pose());
}
_ecm.RemoveComponent<components::ParticleEmitterCmd>(_entity);

return true;
});

// Update thermal cameras
_ecm.Each<components::ThermalCamera>(
[&](const Entity &_entity,
Expand Down Expand Up @@ -420,6 +450,8 @@ void RenderUtil::Update()
auto newActors = std::move(this->dataPtr->newActors);
auto newLights = std::move(this->dataPtr->newLights);
auto newParticleEmitters = std::move(this->dataPtr->newParticleEmitters);
auto newParticleEmittersCmds =
std::move(this->dataPtr->newParticleEmittersCmds);
auto removeEntities = std::move(this->dataPtr->removeEntities);
auto entityPoses = std::move(this->dataPtr->entityPoses);
auto trajectoryPoses = std::move(this->dataPtr->trajectoryPoses);
Expand All @@ -436,6 +468,7 @@ void RenderUtil::Update()
this->dataPtr->newActors.clear();
this->dataPtr->newLights.clear();
this->dataPtr->newParticleEmitters.clear();
this->dataPtr->newParticleEmittersCmds.clear();
this->dataPtr->removeEntities.clear();
this->dataPtr->entityPoses.clear();
this->dataPtr->trajectoryPoses.clear();
Expand Down Expand Up @@ -543,6 +576,12 @@ void RenderUtil::Update()
std::get<0>(emitter), std::get<1>(emitter), std::get<2>(emitter));
}

for (const auto &emitterCmd : newParticleEmittersCmds)
{
this->dataPtr->sceneManager.UpdateParticleEmitter(
emitterCmd.first, emitterCmd.second);
}

if (this->dataPtr->enableSensors && this->dataPtr->createSensorCb)
{
for (const auto &sensor : newSensors)
Expand Down Expand Up @@ -1501,6 +1540,14 @@ void RenderUtilPrivate::RemoveRenderingEntities(
return true;
});

// particle emitters
_ecm.EachRemoved<components::ParticleEmitter>(
[&](const Entity &_entity, const components::ParticleEmitter *)->bool
{
this->removeEntities[_entity] = _info.iterations;
return true;
});

// cameras
_ecm.EachRemoved<components::Camera>(
[&](const Entity &_entity, const components::Camera *)->bool
Expand Down
67 changes: 51 additions & 16 deletions src/rendering/SceneManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -969,8 +969,8 @@ rendering::LightPtr SceneManager::CreateLight(Entity _id,
}

/////////////////////////////////////////////////
rendering::ParticleEmitterPtr SceneManager::CreateParticleEmitter(Entity _id,
const msgs::ParticleEmitter &_emitter, Entity _parentId)
rendering::ParticleEmitterPtr SceneManager::CreateParticleEmitter(
Entity _id, const msgs::ParticleEmitter &_emitter, Entity _parentId)
{
if (!this->dataPtr->scene)
return rendering::ParticleEmitterPtr();
Expand Down Expand Up @@ -1005,11 +1005,32 @@ rendering::ParticleEmitterPtr SceneManager::CreateParticleEmitter(Entity _id,
rendering::ParticleEmitterPtr emitter;
emitter = this->dataPtr->scene->CreateParticleEmitter(name);

if (emitter == nullptr)
this->dataPtr->particleEmitters[_id] = emitter;

if (parent)
parent->AddChild(emitter);

this->UpdateParticleEmitter(_id, _emitter);

return emitter;
}

/////////////////////////////////////////////////
rendering::ParticleEmitterPtr SceneManager::UpdateParticleEmitter(Entity _id,
const msgs::ParticleEmitter &_emitter)
{
if (!this->dataPtr->scene)
return rendering::ParticleEmitterPtr();

// Sanity check: Make sure that the id exists.
auto emitterIt = this->dataPtr->particleEmitters.find(_id);
if (emitterIt == this->dataPtr->particleEmitters.end())
{
ignerr << "Failed to create particle emitter with name[" << name << "]\n";
ignerr << "Particle emitter with Id: [" << _id << "] not found in the "
<< "scene" << std::endl;
return rendering::ParticleEmitterPtr();
}
auto emitter = emitterIt->second;

// Type.
switch (_emitter.type())
Expand All @@ -1036,7 +1057,8 @@ rendering::ParticleEmitterPtr SceneManager::CreateParticleEmitter(Entity _id,
}

// Emitter size.
emitter->SetEmitterSize(ignition::msgs::Convert(_emitter.size()));
if (_emitter.has_size())
emitter->SetEmitterSize(ignition::msgs::Convert(_emitter.size()));

// Rate.
emitter->SetRate(_emitter.rate());
Expand Down Expand Up @@ -1065,22 +1087,25 @@ rendering::ParticleEmitterPtr SceneManager::CreateParticleEmitter(Entity _id,
// Velocity range.
emitter->SetVelocityRange(_emitter.min_velocity(), _emitter.max_velocity());

// Color range.
emitter->SetColorRange(
ignition::msgs::Convert(_emitter.color_start()),
ignition::msgs::Convert(_emitter.color_end()));

// Scale rate.
emitter->SetScaleRate(_emitter.scale_rate());

// Color range image.
if (!_emitter.color_range_image().empty())
{
emitter->SetColorRangeImage(_emitter.color_range_image());
}
// Color range.
else if (_emitter.has_color_start() && _emitter.has_color_end())
{
emitter->SetColorRange(
ignition::msgs::Convert(_emitter.color_start()),
ignition::msgs::Convert(_emitter.color_end()));
}

this->dataPtr->particleEmitters[_id] = emitter;
// Scale rate.
emitter->SetScaleRate(_emitter.scale_rate());

if (parent)
parent->AddChild(emitter);
// pose
if (_emitter.has_pose())
emitter->SetLocalPose(msgs::Convert(_emitter.pose()));

return emitter;
}
Expand Down Expand Up @@ -1385,6 +1410,16 @@ void SceneManager::RemoveEntity(Entity _id)
}
}

{
auto it = this->dataPtr->particleEmitters.find(_id);
if (it != this->dataPtr->particleEmitters.end())
{
this->dataPtr->scene->DestroyVisual(it->second);
this->dataPtr->particleEmitters.erase(it);
return;
}
}

{
auto it = this->dataPtr->sensors.find(_id);
if (it != this->dataPtr->sensors.end())
Expand Down
3 changes: 3 additions & 0 deletions src/systems/particle_emitter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ gz_add_system(particle-emitter
SOURCES
ParticleEmitter.cc
PUBLIC_LINK_LIBS
ignition-common${IGN_COMMON_VER}::ignition-common${IGN_COMMON_VER}
ignition-msgs${IGN_MSGS_VER}::ignition-msgs${IGN_MSGS_VER}
ignition-plugin${IGN_PLUGIN_VER}::ignition-plugin${IGN_PLUGIN_VER}
ignition-transport${IGN_TRANSPORT_VER}::ignition-transport${IGN_TRANSPORT_VER}
)
Loading