/** See Ogre::ParticleEmitter. */ void _initParticle(Ogre::Particle *particle) { Ogre::Vector3 xOff, yOff, zOff; // Call superclass ParticleEmitter::_initParticle(particle); xOff = Ogre::Math::SymmetricRandom() * mXRange; yOff = Ogre::Math::SymmetricRandom() * mYRange; zOff = Ogre::Math::SymmetricRandom() * mZRange; particle->position = mPosition + xOff + yOff + zOff; // Generate complex data by reference genEmissionColour(particle->colour); // NOTE: We do not use mDirection/mAngle for the initial direction. Ogre::Radian hdir = mHorizontalDir + mHorizontalAngle*Ogre::Math::SymmetricRandom(); Ogre::Radian vdir = mVerticalDir + mVerticalAngle*Ogre::Math::SymmetricRandom(); particle->direction = (Ogre::Quaternion(hdir, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(vdir, Ogre::Vector3::UNIT_X)) * Ogre::Vector3::UNIT_Z; genEmissionVelocity(particle->direction); // Generate simpler data particle->timeToLive = particle->totalTimeToLive = genEmissionTTL(); }
/** See Ogre::ParticleEmitter. */ void _initParticle(Ogre::Particle *particle) { Ogre::Vector3 xOff, yOff, zOff; // Call superclass ParticleEmitter::_initParticle(particle); xOff = Ogre::Math::SymmetricRandom() * mXRange; yOff = Ogre::Math::SymmetricRandom() * mYRange; zOff = Ogre::Math::SymmetricRandom() * mZRange; #if OGRE_VERSION >= (1 << 16 | 10 << 8 | 0) Ogre::Vector3& position = particle->mPosition; Ogre::Vector3& direction = particle->mDirection; Ogre::ColourValue& colour = particle->mColour; Ogre::Real& totalTimeToLive = particle->mTotalTimeToLive; Ogre::Real& timeToLive = particle->mTimeToLive; #else Ogre::Vector3& position = particle->position; Ogre::Vector3& direction = particle->direction; Ogre::ColourValue& colour = particle->colour; Ogre::Real& totalTimeToLive = particle->totalTimeToLive; Ogre::Real& timeToLive = particle->timeToLive; #endif Ogre::Node* emitterBone = mEmitterBones.at(OEngine::Misc::Rng::rollDice(mEmitterBones.size())); position = xOff + yOff + zOff + mParticleBone->_getDerivedOrientation().Inverse() * (emitterBone->_getDerivedPosition() - mParticleBone->_getDerivedPosition()); // Generate complex data by reference genEmissionColour(colour); // NOTE: We do not use mDirection/mAngle for the initial direction. Ogre::Radian hdir = mHorizontalDir + mHorizontalAngle*Ogre::Math::SymmetricRandom(); Ogre::Radian vdir = mVerticalDir + mVerticalAngle*Ogre::Math::SymmetricRandom(); direction = (mParticleBone->_getDerivedOrientation().Inverse() * emitterBone->_getDerivedOrientation() * Ogre::Quaternion(hdir, Ogre::Vector3::UNIT_Z) * Ogre::Quaternion(vdir, Ogre::Vector3::UNIT_X)) * Ogre::Vector3::UNIT_Z; genEmissionVelocity(direction); // Generate simpler data timeToLive = totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void CylinderEmitter::_initParticle(Particle* pParticle) { Real x, y, z; // Call superclass AreaEmitter::_initParticle(pParticle); // First we create a random point inside a bounding cylinder with a // radius and height of 1 (this is easy to do). The distance of the // point from 0,0,0 must be <= 1 (== 1 means on the surface and we // count this as inside, too). while (true) { /* ClearSpace not yet implemeted */ // three random values for one random point in 3D space x = Math::SymmetricRandom(); y = Math::SymmetricRandom(); z = Math::SymmetricRandom(); // the distance of x,y from 0,0 is sqrt(x*x+y*y), but // as usual we can omit the sqrt(), since sqrt(1) == 1 and we // use the 1 as boundary. z is not taken into account, since // all values in the z-direction are inside the cylinder: if ( x*x + y*y <= 1) { break; // found one valid point inside } } // scale the found point to the cylinder's size and move it // relatively to the center of the emitter point pParticle->position = mPosition + + x * mXRange + y * mYRange + z * mZRange; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void HollowEllipsoidEmitter::_initParticle(Particle* pParticle) { Real a, b, c, x, y, z; // Init dimensions pParticle->resetDimensions(); // create two random angles alpha and beta // with these two angles, we are able to select any point on an // ellipsoid's surface Radian alpha ( Math::RangeRandom(0,Math::TWO_PI) ); Radian beta ( Math::RangeRandom(0,Math::PI) ); // create three random radius values that are bigger than the inner // size, but smaller/equal than/to the outer size 1.0 (inner size is // between 0 and 1) a = Math::RangeRandom(mInnerSize.x,1.0); b = Math::RangeRandom(mInnerSize.y,1.0); c = Math::RangeRandom(mInnerSize.z,1.0); // with a,b,c we have defined a random ellipsoid between the inner // ellipsoid and the outer sphere (radius 1.0) // with alpha and beta we select on point on this random ellipsoid // and calculate the 3D coordinates of this point Real sinbeta ( Math::Sin(beta) ); x = a * Math::Cos(alpha) * sinbeta; y = b * Math::Sin(alpha) * sinbeta; z = c * Math::Cos(beta); // scale the found point to the ellipsoid's size and move it // relatively to the center of the emitter point pParticle->position = mPosition + + x * mXRange + y * mYRange + z * mZRange; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void EllipsoidEmitter::_initParticle(Particle* pParticle) { Real x, y, z; // Call superclass AreaEmitter::_initParticle(pParticle); // First we create a random point inside a bounding sphere with a // radius of 1 (this is easy to do). The distance of the point from // 0,0,0 must be <= 1 (== 1 means on the surface and we count this as // inside, too). while (true) { // three random values for one random point in 3D space x = Math::SymmetricRandom(); y = Math::SymmetricRandom(); z = Math::SymmetricRandom(); // the distance of x,y,z from 0,0,0 is sqrt(x*x+y*y+z*z), but // as usual we can omit the sqrt(), since sqrt(1) == 1 and we // use the 1 as boundary: if ( x*x + y*y + z*z <= 1) { break; // found one valid point inside } } // scale the found point to the ellipsoid's size and move it // relatively to the center of the emitter point pParticle->position = mPosition + + x * mXRange + y * mYRange + z * mZRange; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void PointEmitter::_initParticle(Particle* pParticle) { // Very simple emitter, uses default implementations with no modification // Call superclass ParticleEmitter::_initParticle(pParticle); // Point emitter emits from own position pParticle->position = mPosition; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection( pParticle->position, pParticle->direction ); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void BoxEmitter::_initParticle(Particle* pParticle) { Vector3 xOff, yOff, zOff; // Call superclass ParticleEmitter::_initParticle(pParticle); xOff = Math::SymmetricRandom() * mXRange; yOff = Math::SymmetricRandom() * mYRange; zOff = Math::SymmetricRandom() * mZRange; pParticle->position = mPosition + xOff + yOff + zOff; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
//----------------------------------------------------------------------- void RingEmitter::_initParticle(Particle* pParticle) { Real a, b, x, y, z; // Call superclass AreaEmitter::_initParticle(pParticle); // create a random angle from 0 .. PI*2 Radian alpha ( Math::RangeRandom(0,Math::TWO_PI) ); // create two random radius values that are bigger than the inner size a = Math::RangeRandom(mInnerSizex,1.0); b = Math::RangeRandom(mInnerSizey,1.0); // with a and b we have defined a random ellipse inside the inner // ellipse and the outer circle (radius 1.0) // with alpha, and a and b we select a random point on this ellipse // and calculate it's coordinates x = a * Math::Sin(alpha); y = b * Math::Cos(alpha); // the height is simple -1 to 1 z = Math::SymmetricRandom(); // scale the found point to the ring's size and move it // relatively to the center of the emitter point pParticle->position = mPosition + + x * mXRange + y * mYRange + z * mZRange; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }
void PolarEmitter::_initParticle(Particle* pParticle) { Vector3 pos; // if we want to control the step of the parameter if (mUsePolarStep) { pos.x = mRadiusTotal * Math::Sin(Degree(mThetaTotal).valueRadians()) * Math::Cos(Degree(mPhiTotal).valueRadians()); if (mFlipYZAxis) { pos.z = mRadiusTotal * Math::Sin(Degree(mThetaTotal).valueRadians()) * Math::Sin(Degree(mPhiTotal).valueRadians()); pos.y = mRadiusTotal * Math::Cos(Degree(mThetaTotal).valueRadians()); } else { pos.y = mRadiusTotal * Math::Sin(Degree(mThetaTotal).valueRadians()) * Math::Sin(Degree(mPhiTotal).valueRadians()); pos.z = mRadiusTotal * Math::Cos(Degree(mThetaTotal).valueRadians()); } // wrap the angle between 0 and 360 mThetaTotal = fmod( mThetaTotal + mThetaStep, 360.0f ); mPhiTotal = fmod( mPhiTotal + mPhiStep, 360.0f ); // ÅжÏÊÇ·ñÐèÒªreset radius if (mResetRadius && (++mCurrentResetRadiusCount > mResetRadiusCount)) { mCurrentResetRadiusCount = 0; mRadiusTotal = mRadiusMin; } else mRadiusTotal += mRadiusStep; } else { Real currentXAngle = Math::RangeRandom(mThetaMin, mThetaMax); Real currentYAngle = Math::RangeRandom(mPhiMin, mPhiMax); Real currentSphereRadius = Math::RangeRandom(mRadiusMin, mRadiusMax); pos.x = currentSphereRadius * Math::Sin(Degree(currentXAngle).valueRadians()) * Math::Cos(Degree(currentYAngle).valueRadians()); if (mFlipYZAxis) { pos.z = currentSphereRadius * Math::Sin(Degree(currentXAngle).valueRadians()) * Math::Sin(Degree(currentYAngle).valueRadians()); pos.y = currentSphereRadius * Math::Cos(Degree(currentXAngle).valueRadians()); } else { pos.y = currentSphereRadius * Math::Sin(Degree(currentXAngle).valueRadians()) * Math::Sin(Degree(currentYAngle).valueRadians()); pos.z = currentSphereRadius * Math::Cos(Degree(currentXAngle).valueRadians()); } } pParticle->position = mPosition + pos; // Generate complex data by reference genEmissionColour(pParticle->colour); genEmissionDirection(pParticle->direction); genEmissionVelocity(pParticle->direction); // Generate simpler data pParticle->timeToLive = pParticle->totalTimeToLive = genEmissionTTL(); }