Skip to content

Commit

Permalink
Merge branch 'ign-rendering4' into thermal_particles
Browse files Browse the repository at this point in the history
  • Loading branch information
adlarkin authored Feb 17, 2021
2 parents 18fd616 + 938e42c commit c0d4ef0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 36 deletions.
16 changes: 16 additions & 0 deletions examples/particles_demo/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ void buildScene(ScenePtr _scene)

//! [create particle emitter]
ParticleEmitterPtr emitter = _scene->CreateParticleEmitter();
emitter->SetType(EM_POINT);
emitter->SetLocalPose({2, 1.10, 1.25, 1.5708, 0, 2.3});
emitter->SetRate(10);
emitter->SetParticleSize({1, 1, 1});
Expand All @@ -118,6 +119,21 @@ void buildScene(ScenePtr _scene)
emitter->SetEmitting(true);
root->AddChild(emitter);
//! [create particle emitter]

// area emitter
ParticleEmitterPtr areaEmitter = _scene->CreateParticleEmitter();
areaEmitter->SetType(EM_BOX);
areaEmitter->SetEmitterSize({3.0, 3.0, 3.0});
areaEmitter->SetLocalPose({3, 0, 0, 0, -1.5707, 0});
areaEmitter->SetRate(10);
areaEmitter->SetParticleSize({0.01, 0.01, 0.01});
areaEmitter->SetLifetime(1);
areaEmitter->SetVelocityRange(0.5, 1);
areaEmitter->SetMaterial(particleMaterial);
areaEmitter->SetColorRangeImage(RESOURCE_PATH + "/smokecolors.png");
areaEmitter->SetScaleRate(1);
areaEmitter->SetEmitting(true);
root->AddChild(areaEmitter);
}

//////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ namespace ignition
// Documentation inherited.
protected: virtual void Init() override;

/// \brief Internal pre-render function added to avoid breaking ABI
/// compatibility
private: void PreRenderImpl();

/// \brief Create the particle system
private: void CreateParticleSystem();

/// \brief Only the ogre scene can instanstiate this class
private: friend class Ogre2Scene;

Expand Down
128 changes: 92 additions & 36 deletions ogre2/src/Ogre2ParticleEmitter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ class ignition::rendering::Ogre2ParticleEmitterPrivate
public: Ogre::ParticleSystem *ps = nullptr;

/// \brief Ogre particle emitter.
public: std::array<Ogre::ParticleEmitter*,
EmitterType::EM_NUM_EMITTERS> emitters;
public: Ogre::ParticleEmitter *emitter = nullptr;

// \brief Ogre color image affector.
public: Ogre::ParticleAffector *colorImageAffector = nullptr;
Expand All @@ -64,6 +63,10 @@ class ignition::rendering::Ogre2ParticleEmitterPrivate

/// \brief Pointer to the unlit material used by particle emitter.
public: MaterialPtr materialUnlit;

/// \brief Flag to indicate that the emitter is dirty and needs to be
/// recreated
public: bool emitterDirty = false;
};

// Names used in Ogre for the supported emitters.
Expand Down Expand Up @@ -93,6 +96,11 @@ void Ogre2ParticleEmitter::Destroy()
{
if (this->dataPtr->ps)
{
this->dataPtr->ps->removeAllAffectors();
this->dataPtr->colorInterpolatorAffector = nullptr;
this->dataPtr->colorImageAffector = nullptr;
this->dataPtr->scalerAffector = nullptr;

this->scene->OgreSceneManager()->destroyParticleSystem(
this->dataPtr->ps);
this->dataPtr->ps = nullptr;
Expand All @@ -106,7 +114,7 @@ void Ogre2ParticleEmitter::Destroy()
}

//////////////////////////////////////////////////
void Ogre2ParticleEmitter::Ogre2ParticleEmitter::SetType(
void Ogre2ParticleEmitter::SetType(
const EmitterType _type)
{
// Sanity check: Make sure that the emitter type is valid.
Expand All @@ -117,11 +125,16 @@ void Ogre2ParticleEmitter::Ogre2ParticleEmitter::SetType(
return;
}

for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
this->dataPtr->emitters[i]->setEnabled(false);
if (this->type == _type)
return;

this->dataPtr->emitters[_type]->setEnabled(true);
this->type = _type;

this->dataPtr->emitterDirty = true;
// todo(anyone) remove this call. We had to do this since we can't override
// PreRender() as it breaks ABI. We should rename PreRenderImpl to PreRender()
// in next release.
this->PreRenderImpl();
}

//////////////////////////////////////////////////
Expand Down Expand Up @@ -160,15 +173,13 @@ void Ogre2ParticleEmitter::SetEmitterSize(const ignition::math::Vector3d &_size)
for (auto[param, value] : allParamsToSet)
{
// We skip EM_POINT.
for (auto i = 1; i < EmitterType::EM_NUM_EMITTERS; ++i)
if (!this->dataPtr->emitter->setParameter(param, value))
{
if (!this->dataPtr->emitters[i]->setParameter(param, value))
{
ignerr << "SetEmitterSize() error for " << kOgreEmitterTypes[i]
<< " emitter because SetParameter(" << param << " " << value
<< ") failed." << std::endl;
return;
}
ignerr << "SetEmitterSize() error for "
<< this->dataPtr->emitter->getType()
<< " emitter because SetParameter(" << param << " " << value
<< ") failed." << std::endl;
return;
}
}
break;
Expand All @@ -195,25 +206,24 @@ void Ogre2ParticleEmitter::SetRate(double _rate)
return;
}

for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
this->dataPtr->emitters[i]->setEmissionRate(_rate);
this->dataPtr->emitter->setEmissionRate(_rate);

this->rate = _rate;
}

//////////////////////////////////////////////////
void Ogre2ParticleEmitter::SetDuration(double _duration)
{
for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
this->dataPtr->emitters[i]->setDuration(_duration);
this->dataPtr->emitter->setDuration(_duration);


this->duration = _duration;
}

//////////////////////////////////////////////////
void Ogre2ParticleEmitter::SetEmitting(bool _enable)
{
this->dataPtr->emitters[this->type]->setEnabled(_enable);
this->dataPtr->emitter->setEnabled(_enable);
this->dataPtr->ps->setEmitting(_enable);
this->emitting = _enable;
}
Expand All @@ -229,8 +239,14 @@ void Ogre2ParticleEmitter::SetParticleSize(
<< "Particle size values should be non-negative." << std::endl;
return;
}
this->dataPtr->ps->setDefaultDimensions(_size[0], _size[1]);

this->particleSize = _size;

this->dataPtr->emitterDirty = true;
// todo(anyone) remove this call. We had to do this since we can't override
// PreRender() as it breaks ABI. We should rename PreRenderImpl to PreRender()
// in next release.
this->PreRenderImpl();
}

//////////////////////////////////////////////////
Expand All @@ -244,8 +260,7 @@ void Ogre2ParticleEmitter::SetLifetime(double _lifetime)
return;
}

for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
this->dataPtr->emitters[i]->setTimeToLive(_lifetime);
this->dataPtr->emitter->setTimeToLive(_lifetime);

this->lifetime = _lifetime;
}
Expand All @@ -269,8 +284,8 @@ void Ogre2ParticleEmitter::SetMaterial(const MaterialPtr &_material)
void Ogre2ParticleEmitter::SetVelocityRange(double _minVelocity,
double _maxVelocity)
{
for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
this->dataPtr->emitters[i]->setParticleVelocity(_minVelocity, _maxVelocity);
this->dataPtr->emitter->setParticleVelocity(_minVelocity, _maxVelocity);


this->minVelocity = _minVelocity;
this->maxVelocity = _maxVelocity;
Expand Down Expand Up @@ -415,7 +430,53 @@ void Ogre2ParticleEmitter::SetColorRangeImage(const std::string &_image)
void Ogre2ParticleEmitter::Init()
{
Ogre2Visual::Init();
this->CreateParticleSystem();
}

//////////////////////////////////////////////////
void Ogre2ParticleEmitter::PreRenderImpl()
{
// todo(anyone) rename this function to PreRender() so it overrides function
// from base class. Since this rename breaks ABI, we should rename this
// function in the next release

// recreate the particle system if needed
// currently this is needed when user changes type or particle size
if (this->dataPtr->emitterDirty)
{
this->Destroy();
this->CreateParticleSystem();

// make direct ogre calls here so we don't mark emitter as dirty again
this->dataPtr->ps->setDefaultDimensions(
this->particleSize[0], this->particleSize[1]);

this->SetEmitterSize(this->emitterSize);

// set other properties
this->SetDuration(this->duration);
this->SetEmitting(this->emitting);
this->SetLifetime(this->lifetime);
this->SetRate(this->rate);
this->SetVelocityRange(this->minVelocity, this->maxVelocity);

if (this->material)
this->SetMaterial(this->material);

if (!this->colorRangeImage.empty())
this->SetColorRangeImage(this->colorRangeImage);
else
this->SetColorRange(this->colorStart, this->colorEnd);

this->SetScaleRate(this->scaleRate);

this->dataPtr->emitterDirty = false;
}
}

//////////////////////////////////////////////////
void Ogre2ParticleEmitter::CreateParticleSystem()
{
// Instantiate the particle system and default parameters.
this->dataPtr->ps = this->scene->OgreSceneManager()->createParticleSystem();
this->dataPtr->ps->setCullIndividually(true);
Expand All @@ -428,16 +489,12 @@ void Ogre2ParticleEmitter::Init()
"The nummer of supported emitters does not match the number of "
"Ogre emitter types.");

// Instantiate all particle emitters and their default parameters.
// Note that we enable the point emitter by default.
for (auto i = 0; i < EmitterType::EM_NUM_EMITTERS; ++i)
{
this->dataPtr->emitters[i] =
this->dataPtr->ps->addEmitter(kOgreEmitterTypes[i]);
this->dataPtr->emitters[i]->setEnabled(false);
this->dataPtr->emitters[i]->setDirection(Ogre::Vector3::UNIT_X);
}
this->dataPtr->emitters[EmitterType::EM_POINT]->setEnabled(true);
// Instantiate particle emitter and their default parameters.
// Emitter type is point unless otherwise specified.
this->dataPtr->emitter =
this->dataPtr->ps->addEmitter(kOgreEmitterTypes[this->type]);
this->dataPtr->emitter->setDirection(Ogre::Vector3::UNIT_X);
this->dataPtr->emitter->setEnabled(true);

// Instantiate the default material.
this->dataPtr->materialUnlit = this->scene->CreateMaterial();
Expand All @@ -447,8 +504,7 @@ void Ogre2ParticleEmitter::Init()
this->dataPtr->ps->setMaterialName(
*(this->dataPtr->ogreDatablock->getNameStr()));

// Default emitter parameters.
this->SetParticleSize({1, 1, 1});
this->dataPtr->ps->setDefaultDimensions(1, 1);

this->ogreNode->attachObject(this->dataPtr->ps);
igndbg << "Particle emitter initialized" << std::endl;
Expand Down

0 comments on commit c0d4ef0

Please sign in to comment.