7 #include "imstkRenderParticleEmitter.h" 8 #include "imstkLogger.h" 9 #include "imstkRenderParticles.h" 10 #include "imstkTimer.h" 18 m_mode(mode), m_time(time), m_emitTime(m_time), m_stopWatch(
std::make_unique<
StopWatch>())
24 startFrame.m_time = 0.0f;
25 startFrame.m_acceleration = Vec3f(0, 0, 0);
26 startFrame.m_rotationalAcceleration = 0.0f;
29 endFrame.m_color = startFrame.m_color;
31 endFrame.m_acceleration = Vec3f(0, 0, 0);
32 endFrame.m_rotationalAcceleration = 0.0f;
42 std::shared_ptr<Geometry> geometry)
44 CHECK(geometry->getTypeName() == RenderParticles::getStaticTypeName()) <<
"Error: Geometry must be RenderParticles";
46 m_animationGeometry = geometry;
47 m_particles = &std::static_pointer_cast<
RenderParticles>(m_animationGeometry)->getParticles();
64 const Vec3f maxDirection,
67 const float minRotationSpeed,
68 const float maxRotationSpeed)
70 m_minDirection = minDirection;
71 m_maxDirection = maxDirection;
72 m_minDirection.normalize();
73 m_maxDirection.normalize();
74 m_minSpeed = minSpeed;
75 m_maxSpeed = maxSpeed;
76 m_minRotationSpeed = minRotationSpeed;
77 m_maxRotationSpeed = maxRotationSpeed;
109 RenderParticleEmitter::getEndKeyFrame()
124 std::vector<RenderParticleKeyFrame>&
138 auto renderParticles = std::static_pointer_cast<
RenderParticles>(m_geometry);
139 renderParticles->
reset();
147 auto renderParticles = std::static_pointer_cast<
RenderParticles>(m_geometry);
151 m_stopWatch->start();
155 auto time = m_stopWatch->getTimeElapsed();
156 float dt = (float)(time - m_lastUpdateTime);
157 m_lastUpdateTime = time;
159 for (
auto&& particle : (*m_particles))
162 auto startKeyFrame = &startKeyFrameTemp;
163 auto endKeyFrameTemp = *this->getEndKeyFrame();
164 auto endKeyFrame = &endKeyFrameTemp;
166 particle->m_age += dt;
168 if (!(particle->m_created) && particle->m_age >= 0)
170 particle->m_created =
true;
172 renderParticles->incrementNumOfParticles();
174 else if (particle->m_age < 0)
180 && particle->m_age >
m_time)
182 particle->m_age = particle->m_age - ((int)(particle->m_age /
m_time) *
m_time);
190 if (particle->m_age >= keyFrame->m_time
191 && keyFrame->m_time > startKeyFrame->m_time)
193 startKeyFrame = keyFrame;
195 if (particle->m_age < keyFrame->m_time
196 && keyFrame->m_time < endKeyFrame->m_time)
198 endKeyFrame = keyFrame;
203 particle->m_rotationalAcceleration = startKeyFrame->m_rotationalAcceleration;
204 particle->m_rotationalVelocity += particle->m_rotationalAcceleration * (dt / 1000.0f);
205 particle->m_rotation += particle->m_rotationalVelocity * (dt / 1000.0f);
207 particle->m_acceleration = startKeyFrame->m_acceleration;
208 particle->m_velocity += particle->m_acceleration * (dt / 1000.0);
209 particle->m_position += particle->m_velocity * (dt / 1000.0);
211 float timeDifference = endKeyFrame->m_time - startKeyFrame->m_time;
212 float alpha = (particle->m_age - startKeyFrame->m_time) / timeDifference;
214 particle->m_scale = (alpha * endKeyFrame->m_scale)
215 + ((1.0f - alpha) * startKeyFrame->m_scale);
217 auto particleColor =
imstk::Color(particle->m_color[0], particle->m_color[1], particle->m_color[2], particle->m_color[3]);
219 endKeyFrame->m_color,
220 startKeyFrame->m_color,
228 m_particles->clear();
230 auto particles = std::static_pointer_cast<
RenderParticles>(m_animationGeometry);
232 for (
unsigned int i = 0; i < particles->getMaxNumParticles(); i++)
234 m_particles->push_back(std::unique_ptr<RenderParticle>(
new RenderParticle()));
235 (*m_particles)[i]->m_age = -(i / (float)(particles->getMaxNumParticles())) * m_emitTime;
236 (*m_particles)[i]->m_created =
false;
243 auto position = m_animationGeometry->getTranslation();
245 if (m_shape == Shape::Cube)
251 particle->m_position[0] = (float)position[0] + x;
252 particle->m_position[1] = (float)position[1] + y;
253 particle->m_position[2] = (float)position[2] + z;
258 particle->m_rotation = randomRotation;
259 particle->m_rotationalVelocity = (randomRotationalVelocity * m_minRotationSpeed) +
260 ((1.0f - randomRotationalVelocity) * m_maxRotationSpeed);
267 float speed = (randomSpeed * m_minSpeed) + ((1.0f - randomSpeed) * m_maxSpeed);
268 float directionX = (randomDirectionX * m_minDirection[0]) + ((1.0f - randomDirectionX) * m_maxDirection[0]);
269 float directionY = (randomDirectionY * m_minDirection[1]) + ((1.0f - randomDirectionY) * m_maxDirection[1]);
270 float directionZ = (randomDirectionZ * m_minDirection[2]) + ((1.0f - randomDirectionZ) * m_maxDirection[2]);
271 Vec3f direction(directionX, directionY, directionZ);
272 direction.normalize();
273 particle->m_velocity[0] = directionX * speed;
274 particle->m_velocity[1] = directionY * speed;
275 particle->m_velocity[2] = directionZ * speed;
280 const Color& sourceA,
281 const Color& sourceB,
284 destination.r = (sourceA.r * alpha) + (sourceB.r * (1.0f - alpha));
285 destination.g = (sourceA.g * alpha) + (sourceB.g * (1.0f - alpha));
286 destination.b = (sourceA.b * alpha) + (sourceB.b * (1.0f - alpha));
287 destination.a = (sourceA.a * alpha) + (sourceB.a * (1.0f - alpha));
293 return (
float)std::rand() / RAND_MAX;
void reset()
Reset number of particles.
float getRandomNormalizedFloat()
Get uniformly-distributed float.
Keyframe for particle animation.
virtual void update()
Update.
RenderParticleEmitter(std::shared_ptr< Geometry > geometry, const float time=3000.0f, Mode mode=Mode::Continuous)
Constructor.
std::vector< RenderParticleKeyFrame > & getKeyFrames()
Get key frames.
RenderParticleKeyFrame * getStartKeyFrame()
Get start and end frames.
std::vector< RenderParticleKeyFrame > m_keyFrames
Particle keyframes.
bool addKeyFrame(RenderParticleKeyFrame keyFrame)
Add keyframe to particle emitter.
void initializeParticles()
Initialize particles.
const int c_maxNumKeyFrames
Maximum key frames.
Emitter continuously releases/recycles particles.
float m_time
total time for particle system
void emitParticle(std::unique_ptr< RenderParticle > &particle)
Emit particle.
Contains geometric and animation render information.
void interpolateColor(Color &destination, const Color &sourceA, const Color &sourceB, const float alpha)
Interpolate color.
virtual void setGeometry(std::shared_ptr< Geometry > renderParticles)
Set animation geometry.
Emitter releases particles once until manually reset.
virtual void reset()
Reset the emitter Only works for burst particles.
Stop Watch utility class.
static Color White
Various commonly used colors.
void setEmitterSize(const float size)
Set size of emitter.
void setInitialVelocityRange(const Vec3f minDirection, const Vec3f maxDirection, const float minSpeed, const float maxSpeed, const float minRotationSpeed, const float maxRotationSpeed)
Set velocity range This functions sets minimum and maximum rotation values for determining the initia...
RenderParticleEmitter::Mode getEmitterMode() const
Get mode of emitter.