예제 #1
0
    /** 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();
    }
예제 #2
0
    /** 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();
        
    }
예제 #6
0
    //-----------------------------------------------------------------------
    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();
        
    }
예제 #7
0
    //-----------------------------------------------------------------------
    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();
        
    }
예제 #8
0
    //-----------------------------------------------------------------------
    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();
        
    }
예제 #9
0
    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();
    }