bool PartEmitter::initParticle(PartParticle *particle, uint32 currentTime, uint32 timerDelta) { if (!particle) { return STATUS_FAILED; } if (_sprites.size() == 0) { return STATUS_FAILED; } int posX = BaseUtils::randomInt(_posX, _posX + _width); int posY = BaseUtils::randomInt(_posY, _posY + _height); float posZ = BaseUtils::randomFloat(0.0f, 100.0f); float velocity; if (_velocityZBased) { velocity = _velocity1 + posZ * (_velocity2 - _velocity1) / 100; } else { velocity = BaseUtils::randomFloat(_velocity1, _velocity2); } float scale; if (_scaleZBased) { scale = _scale1 + posZ * (_scale2 - _scale1) / 100; } else { scale = BaseUtils::randomFloat(_scale1, _scale2); } int lifeTime; if (_lifeTimeZBased) { lifeTime = (int)(_lifeTime2 - posZ * (_lifeTime2 - _lifeTime1) / 100); } else { lifeTime = BaseUtils::randomInt(_lifeTime1, _lifeTime2); } float angle = BaseUtils::randomAngle(_angle1, _angle2); int spriteIndex = BaseUtils::randomInt(0, _sprites.size() - 1); float rotation = BaseUtils::randomAngle(_rotation1, _rotation2); float angVelocity = BaseUtils::randomFloat(_angVelocity1, _angVelocity2); float growthRate = BaseUtils::randomFloat(_growthRate1, _growthRate2); if (!BasePlatform::isRectEmpty(&_border)) { int thicknessLeft = (int)(_borderThicknessLeft - (float)_borderThicknessLeft * posZ / 100.0f); int thicknessRight = (int)(_borderThicknessRight - (float)_borderThicknessRight * posZ / 100.0f); int thicknessTop = (int)(_borderThicknessTop - (float)_borderThicknessTop * posZ / 100.0f); int thicknessBottom = (int)(_borderThicknessBottom - (float)_borderThicknessBottom * posZ / 100.0f); particle->_border = _border; particle->_border.left += thicknessLeft; particle->_border.right -= thicknessRight; particle->_border.top += thicknessTop; particle->_border.bottom -= thicknessBottom; } Vector2 vecPos((float)posX, (float)posY); Vector2 vecVel(0, velocity); Matrix4 matRot; matRot.rotationZ(Common::deg2rad(BaseUtils::normalizeAngle(angle - 180))); matRot.transformVector2(vecVel); if (_alphaTimeBased) { particle->_alpha1 = _alpha1; particle->_alpha2 = _alpha2; } else { int alpha = BaseUtils::randomInt(_alpha1, _alpha2); particle->_alpha1 = alpha; particle->_alpha2 = alpha; } particle->_creationTime = currentTime; particle->_pos = vecPos; particle->_posZ = posZ; particle->_velocity = vecVel; particle->_scale = scale; particle->_lifeTime = lifeTime; particle->_rotation = rotation; particle->_angVelocity = angVelocity; particle->_growthRate = growthRate; particle->_exponentialGrowth = _exponentialGrowth; particle->_isDead = DID_FAIL(particle->setSprite(_sprites[spriteIndex])); particle->fadeIn(currentTime, _fadeInTime); if (particle->_isDead) { return STATUS_FAILED; } else { return STATUS_OK; } }
bool cNoradBase::FinalPosition(double incl, double omega, double e, double a, double xl, double xnode, double xn, double tsince, cEci &eci) { if ((e * e) > 1.0) { // error in satellite data return false; } double beta = sqrt(1.0 - e * e); // Long period periodics double axn = e * cos(omega); double temp = 1.0 / (a * beta * beta); double xll = temp * m_xlcof * axn; double aynl = temp * m_aycof; double xlt = xl + xll; double ayn = e * sin(omega) + aynl; // Solve Kepler's Equation double capu = Fmod2p(xlt - xnode); double temp2 = capu; double temp3 = 0.0; double temp4 = 0.0; double temp5 = 0.0; double temp6 = 0.0; double sinepw = 0.0; double cosepw = 0.0; bool fDone = false; for (int i = 1; (i <= 10) && !fDone; i++) { sinepw = sin(temp2); cosepw = cos(temp2); temp3 = axn * sinepw; temp4 = ayn * cosepw; temp5 = axn * cosepw; temp6 = ayn * sinepw; double epw = (capu - temp4 + temp3 - temp2) / (1.0 - temp5 - temp6) + temp2; if (fabs(epw - temp2) <= E6A) fDone = true; else temp2 = epw; } // Short period preliminary quantities double ecose = temp5 + temp6; double esine = temp3 - temp4; double elsq = axn * axn + ayn * ayn; temp = 1.0 - elsq; double pl = a * temp; double r = a * (1.0 - ecose); double temp1 = 1.0 / r; double rdot = XKE * sqrt(a) * esine * temp1; double rfdot = XKE * sqrt(pl) * temp1; temp2 = a * temp1; double betal = sqrt(temp); temp3 = 1.0 / (1.0 + betal); double cosu = temp2 * (cosepw - axn + ayn * esine * temp3); double sinu = temp2 * (sinepw - ayn - axn * esine * temp3); double u = AcTan(sinu, cosu); double sin2u = 2.0 * sinu * cosu; double cos2u = 2.0 * cosu * cosu - 1.0; temp = 1.0 / pl; temp1 = CK2 * temp; temp2 = temp1 * temp; // Update for short periodics double rk = r * (1.0 - 1.5 * temp2 * betal * m_x3thm1) + 0.5 * temp1 * m_x1mth2 * cos2u; double uk = u - 0.25 * temp2 * m_x7thm1 * sin2u; double xnodek = xnode + 1.5 * temp2 * m_cosio * sin2u; double xinck = incl + 1.5 * temp2 * m_cosio * m_sinio * cos2u; double rdotk = rdot - xn * temp1 * m_x1mth2 * sin2u; double rfdotk = rfdot + xn * temp1 * (m_x1mth2 * cos2u + 1.5 * m_x3thm1); // Orientation vectors double sinuk = sin(uk); double cosuk = cos(uk); double sinik = sin(xinck); double cosik = cos(xinck); double sinnok = sin(xnodek); double cosnok = cos(xnodek); double xmx = -sinnok * cosik; double xmy = cosnok * cosik; double ux = xmx * sinuk + cosnok * cosuk; double uy = xmy * sinuk + sinnok * cosuk; double uz = sinik * sinuk; double vx = xmx * cosuk - cosnok * sinuk; double vy = xmy * cosuk - sinnok * sinuk; double vz = sinik * cosuk; // Position double x = rk * ux; double y = rk * uy; double z = rk * uz; cVector vecPos(x, y, z); // Validate on altitude double altKm = (vecPos.Magnitude() * (XKMPER_WGS72 / AE)); if ((altKm < XKMPER_WGS72) || (altKm > (2 * GEOSYNC_ALT))) return false; // Velocity double xdot = rdotk * ux + rfdotk * vx; double ydot = rdotk * uy + rfdotk * vy; double zdot = rdotk * uz + rfdotk * vz; cVector vecVel(xdot, ydot, zdot); cJulian gmt = m_Orbit.Epoch(); gmt.addMin(tsince); eci = cEci(vecPos, vecVel, gmt); return true; }