| 87 | } |
| 88 | |
| 89 | void Emitter::emitParticles(std::vector <unsigned int> &reusedParticles, unsigned int &indexReuse, unsigned int &numEmittedParticles) |
| 90 | { |
| 91 | TimeManager *tm = TimeManager::getCurrent(); |
| 92 | const Real t = tm->getTime(); |
| 93 | const Real timeStepSize = tm->getTimeStepSize(); |
| 94 | const Vector3r & emitDir = m_rotation.col(0); |
| 95 | Vector3r emitVel = m_velocity * emitDir; |
| 96 | Simulation *sim = Simulation::getCurrent(); |
| 97 | const Real radius = sim->getParticleRadius(); |
| 98 | const Real diam = static_cast<Real>(2.0)*radius; |
| 99 | |
| 100 | // shortly before the emitter starts, cleanup the emitter from particles |
| 101 | if (t < m_emitStartTime || t > m_emitEndTime) |
| 102 | emitVel = emitDir * radius * 10 / 0.25; |
| 103 | |
| 104 | if (t >= m_emitStartTime - 0.25 && t <= m_emitEndTime) |
| 105 | { |
| 106 | // animate emitted particles |
| 107 | const Vector3r & x0 = m_x; |
| 108 | |
| 109 | const Real animationMarginAhead = sim->getSupportRadius(); |
| 110 | const Vector3r size = getSize(static_cast<Real>(m_width), static_cast<Real>(m_height), m_type); |
| 111 | const Vector3r halfSize = 0.5 * size; |
| 112 | const Vector3r pos = x0 + static_cast<Real>(0.5) * animationMarginAhead * emitDir; |
| 113 | |
| 114 | const unsigned int nModels = sim->numberOfFluidModels(); |
| 115 | for (unsigned int m = 0; m < nModels; m++) |
| 116 | { |
| 117 | FluidModel *fm = sim->getFluidModel(m); |
| 118 | const unsigned int numParticles = fm->numActiveParticles(); |
| 119 | #pragma omp parallel for schedule(static) default(shared) |
| 120 | for (int i = 0; i < (int)numParticles; i++) |
| 121 | { |
| 122 | Vector3r &xi = fm->getPosition(i); |
| 123 | if (inBox(xi, pos, m_rotation, halfSize)) |
| 124 | { |
| 125 | fm->getVelocity(i) = emitVel; |
| 126 | fm->getPosition(i) += timeStepSize * emitVel; |
| 127 | fm->setParticleState(i, ParticleState::AnimatedByEmitter); |
| 128 | fm->setObjectId(i, m_objectId); |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | if (t < m_nextEmitTime || t > m_emitEndTime) |
| 134 | { |
| 135 | return; |
| 136 | } |
| 137 | |
| 138 | const Vector3r axisHeight = m_rotation.col(1); |
| 139 | const Vector3r axisWidth = m_rotation.col(2); |
| 140 | |
| 141 | const Real startX = -static_cast<Real>(0.5)*(m_width - 1)*diam; |
| 142 | const Real startZ = -static_cast<Real>(0.5)*(m_height - 1)*diam; |
| 143 | |
| 144 | // t-m_nextEmitTime is the time that has passed between the time the particle has been emitted and the current time step. |
| 145 | // timeStepSize is added because emission happens at the end of the time step, but the particles are not animated anymore. |
| 146 | const Real dt = t - m_nextEmitTime + timeStepSize; |
no test coverage detected