void ParticlePool::spark(Position &pos) { int numParticles = randInt(3,6); for(int ii=0; ii<numParticles; ii++) { Position particlePos(pos); particlePos.impulse( randFloat(-50, 50), randFloat(-50, 50) ); float whiteness = randInt(0, 255); Particle p = Particle(whiteness, whiteness, 255, randInt(170, 255), 0.15, particlePos, 300); add(p); } }
//----------------------------------------------------------------------- void RevolutionAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed) { // 因为timeElapsed有可能有0,加上判断,避免除0错 if (false == Ogre::Math::RealEqual(timeElapsed, 0.0f)) { ParticleIterator pi = pSystem->_getIterator(); Particle *p; Quaternion q( Radian(Degree(mRotationSpeed*timeElapsed).valueRadians()), mRotateAxis); Matrix3 mat(Matrix3::IDENTITY); q.ToRotationMatrix(mat); Ogre::Vector3 randomPoint; randomPoint.x = Math::RangeRandom(mCenterOffsetMin.x, mCenterOffsetMax.x); randomPoint.y = Math::RangeRandom(mCenterOffsetMin.y, mCenterOffsetMax.y); randomPoint.z = Math::RangeRandom(mCenterOffsetMin.z, mCenterOffsetMax.z); Vector3 particleSystemPos(Vector3::ZERO); bool localSpace = pSystem->getKeepParticlesInLocalSpace(); particleSystemPos = pSystem->getParentSceneNode()->_getDerivedPosition(); Ogre::Vector3 destPoint = particleSystemPos + randomPoint; Vector3 particlePos(Vector3::ZERO); Vector3 RadiusIncrementDir(Vector3::ZERO); bool needFmod = mRepeatTimes != 1.0f; while (!pi.end()) { p = pi.getNext(); particlePos = p->position; /** 如果是localSpace,那么p->position得到的是粒子的相对位置,所以要加上 粒子系统的位置particleSystemPos,得到绝对位置,再减去destPoint才能得到 正确的向量 particlePos + particleSystemPos - destPoint = particlePos + particleSystemPos - particleSystemPos - randomPoint = particlePos - randomPoint */ if (localSpace) { RadiusIncrementDir = particlePos - randomPoint; RadiusIncrementDir.normalise(); particlePos = mat *( particlePos - randomPoint ) + randomPoint - particlePos; } else { RadiusIncrementDir = particlePos - destPoint; RadiusIncrementDir.normalise(); particlePos = mat *( particlePos - destPoint ) + destPoint - particlePos; } p->direction = particlePos / timeElapsed; if (mUseRadiusIncrementScale) { const Real life_time = p->totalTimeToLive; Real particle_time = 1.0f - (p->timeToLive / life_time); // wrap the particle time Real repeatedParticleTime = needFmod ? fmod( particle_time * mRepeatTimes, 1.0f ) : particle_time; if (repeatedParticleTime <= mTimeAdj[0]) { p->direction += RadiusIncrementDir * mRadiusIncrementAdj[0]; } else if (repeatedParticleTime >= mTimeAdj[MAX_STAGES - 1]) { p->direction += RadiusIncrementDir * mRadiusIncrementAdj[MAX_STAGES - 1]; } else { for (int i=0;i<MAX_STAGES-1;i++) { if (repeatedParticleTime >= mTimeAdj[i] && repeatedParticleTime < mTimeAdj[i + 1]) { repeatedParticleTime -= mTimeAdj[i]; repeatedParticleTime /= (mTimeAdj[i+1]-mTimeAdj[i]); p->direction += RadiusIncrementDir * ( (mRadiusIncrementAdj[i+1] * repeatedParticleTime) + (mRadiusIncrementAdj[i] * (1.0f - repeatedParticleTime)) ); break; } } } } else { p->direction += RadiusIncrementDir*mRadiusIncrement; } // case RotationType::OUTER_NORMAL: //// p->direction.x += pos.x; // // p->direction.z += pos.z; // p->direction = pos; // break; // case RotationType::OUTER_FAST: //// p->direction.x += (p->direction.x + pos.x) /2; // // p->direction.z += (p->direction.z + pos.z) /2; // p->direction += (p->direction + pos) /2; // break; } } }