void CParticleJetEffectPainter::CreateLinearParticles (CSpaceObject *pObj, int iCount, const CVector &vInitialPos, const CVector &vInitialVel) // CreateLinearParticles // // Creates new particles on a straight line { int i; // Compute some basic stuff const Metric rJitterFactor = LIGHT_SPEED / 100000.0; Metric rCurRotation = AngleToRadians(180 + m_iXformRotation + m_iCurDirection); // Compute the spread angle, in radians Metric rSpread = AngleToRadians(Max(0, m_SpreadAngle.Roll())); Metric rHalfSpread = 0.5 * rSpread; // Calculate where last tick's particles would be based on the last rotation. Metric rAveSpeed = m_EmitSpeed.GetAveValue() * LIGHT_SPEED / 100.0; CVector vCurStart = (m_vLastEmitPos + (m_rXformTime * ::PolarToVectorRadians(rCurRotation, rAveSpeed * g_SecondsPerUpdate))) - vInitialPos; // Create particles for (i = 0; i < iCount; i++) { Metric rSlide = mathRandom(0, 9999) / 10000.0; // We place the particle along the line betwen the current // and last emit positions CVector vPos = vInitialPos + rSlide * vCurStart; // Generate a random velocity backwards Metric rRotation = rCurRotation + (rHalfSpread * mathRandom(-1000, 1000) / 1000.0); Metric rSpeed = m_EmitSpeed.Roll() * LIGHT_SPEED / 100.0; CVector vVel = m_rXformTime * (vInitialVel + ::PolarToVectorRadians(rRotation, rSpeed + rJitterFactor * mathRandom(-500, 500))); // Lifetime int iLifeLeft = m_ParticleLifetime.Roll(); // Add the particle m_Particles.AddParticle(vPos, vVel, iLifeLeft, AngleToDegrees(rRotation)); } // Remember the last position m_iLastDirection = m_iCurDirection; m_vLastEmitPos = vInitialPos; }
void CParticleJetEffectPainter::CreateInterpolatedParticles (CSpaceObject *pObj, int iCount, const CVector &vInitialPos, const CVector &vInitialVel) // CreateInterpolatedParticles // // Creates particles interpolated between to directions. { int i; // Compute some basic stuff const Metric rJitterFactor = LIGHT_SPEED / 100000.0; Metric rLastRotation = AngleToRadians(180 + m_iXformRotation + m_iLastDirection); Metric rCurRotation = AngleToRadians(180 + m_iXformRotation + m_iCurDirection); // Compute the spread angle, in radians Metric rSpread = AngleToRadians(Max(0, m_SpreadAngle.Roll())); Metric rHalfSpread = 0.5 * rSpread; // Calculate where last tick's particles would be based on the last rotation. Metric rAveSpeed = m_EmitSpeed.GetAveValue() * LIGHT_SPEED / 100.0; CVector vLastStart = (m_vLastEmitPos + (m_rXformTime * ::PolarToVectorRadians(rLastRotation, rAveSpeed * g_SecondsPerUpdate))) - vInitialPos; // Calculate where last tick's particles would be IF we have used the current // rotation. This allows us to interpolate a turn. CVector vCurStart = (m_vLastEmitPos + (m_rXformTime * ::PolarToVectorRadians(rCurRotation, rAveSpeed * g_SecondsPerUpdate))) - vInitialPos; // Create particles for (i = 0; i < iCount; i++) { Metric rSlide = mathRandom(0, 9999) / 10000.0; // Compute two points along the two slide vectors (last and current) CVector vSlide1 = rSlide * vLastStart; CVector vSlide2 = rSlide * vCurStart; CVector vAdj = (rSlide * vSlide1) + ((1.0 - rSlide) * vSlide2); // We place the particle along the line betwen the current // and last emit positions CVector vPos = vInitialPos + vAdj; // We blend the rotation as well if (Absolute(rCurRotation - rLastRotation) > g_Pi) { if (rLastRotation < rCurRotation) rLastRotation += g_Pi * 2.0; else rCurRotation += g_Pi * 2.0; } Metric rSlideRotation = (rSlide * rLastRotation) + ((1.0 - rSlide) * rCurRotation); // Generate a random velocity backwards Metric rRotation = rSlideRotation + (rHalfSpread * mathRandom(-1000, 1000) / 1000.0); Metric rSpeed = m_EmitSpeed.Roll() * LIGHT_SPEED / 100.0; CVector vVel = m_rXformTime * (vInitialVel + ::PolarToVectorRadians(rRotation, rSpeed + rJitterFactor * mathRandom(-500, 500))); // Lifetime int iLifeLeft = m_ParticleLifetime.Roll(); // Add the particle m_Particles.AddParticle(vPos, vVel, iLifeLeft, AngleToDegrees(rRotation)); } // Remember the last position m_iLastDirection = m_iCurDirection; m_vLastEmitPos = vInitialPos; }
void CParticleJetEffectPainter::CreateFixedParticles (CSpaceObject *pObj, int iCount, const CVector &vInitialPos, const CVector &vInitialVel) // CreateFixedParticles // // Creates particles along the objects path (e.g., missile exhaust). { int i; // Calculate a vector to our previous position // // NOTE: In this mode m_vLastEmitPos is the last position of the object. CVector vCurPos = (pObj ? pObj->GetPos() : CVector()); CVector vToOldPos; if (m_bTrackingObject) { Metric rAveSpeed = m_rXformTime * m_EmitSpeed.GetAveValue() * LIGHT_SPEED / 100.0; vToOldPos = m_vLastEmitPos - (vCurPos + vInitialPos) + ::PolarToVector(180 + m_iLastDirection, rAveSpeed * g_SecondsPerUpdate); } else { Metric rSpeed = (pObj ? pObj->GetVel().Length() : 0.0); vToOldPos = ::PolarToVector(180 + m_iLastDirection, rSpeed * g_SecondsPerUpdate); } // Compute two orthogonal coordinates CVector vAxis = ::PolarToVector(m_iCurDirection + 180, 1.0); CVector vTangent = ::PolarToVector(m_iCurDirection + 90, 1.0); // Create particles for (i = 0; i < iCount; i++) { Metric rSlide = mathRandom(0, 9999) / 10000.0; // Compute a position randomly along the line between the current and // last emit positions. CVector vPos = vInitialPos + rSlide * vToOldPos; // Generate a random velocity along the tangent Metric rTangentSlide = mathRandom(-9999, 9999) / 10000.0; Metric rAxisJitter = mathRandom(-50, 50) / 100.0; CVector vVel = (vTangent * rTangentSlide * m_rXformTime * m_TangentSpeed.Roll() * LIGHT_SPEED / 100.0) + (vAxis * (m_EmitSpeed.Roll() + rAxisJitter) * LIGHT_SPEED / 100.0); // Lifetime int iLifeLeft = m_ParticleLifetime.Roll(); // Add the particle m_Particles.AddParticle(vPos, vVel, iLifeLeft, m_iCurDirection); } // Remember the last position m_iLastDirection = m_iCurDirection; m_vLastEmitPos = vCurPos + vInitialPos; }