Esempio n. 1
0
	void processParticles()
	{
		static int pindex = 0 ;
		ParticleIterator pit = particleSystem->_getIterator() ;
		while(!pit.end()) {
			Particle *particle = pit.getNext();
			Vector3 ppos = particle->position;
			if (ppos.y<=0 && particle->timeToLive>0) { // hits the water!
				// delete particle
				particle->timeToLive = 0.0f;
				// push the water
				float x = ppos.x / PLANE_SIZE * COMPLEXITY ;
				float y = ppos.z / PLANE_SIZE * COMPLEXITY ;
				float h = rand() % RAIN_HEIGHT_RANDOM + RAIN_HEIGHT_CONSTANT ;
				if (x<1) x=1 ;
				if (x>COMPLEXITY-1) x=COMPLEXITY-1;
				if (y<1) y=1 ;
				if (y>COMPLEXITY-1) y=COMPLEXITY-1;
				waterMesh->push(x,y,-h) ;
				WaterCircle *circle = new WaterCircle(
					"Circle#"+StringConverter::toString(pindex++),
					x, y);
				circles.push_back(circle);
			}
		}
	}
    //-----------------------------------------------------------------------
    void DeflectorPlaneAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        // precalculate distance of plane from origin
        Real planeDistance = - mPlaneNormal.dotProduct(mPlanePoint) / Math::Sqrt(mPlaneNormal.dotProduct(mPlaneNormal));
        Vector3 directionPart;

        ParticleIterator pi = pSystem->_getIterator();

        while (!pi.end())
        {
            Particle *p = pi.getNext();

            Vector3 direction(p->mDirection * timeElapsed);
            if (mPlaneNormal.dotProduct(p->mPosition + direction) + planeDistance <= 0.0)
            {
                Real a = mPlaneNormal.dotProduct(p->mPosition) + planeDistance;
                if (a > 0.0)
                {
                    // for intersection point
                    directionPart = direction * (- a / direction.dotProduct( mPlaneNormal ));
                    // set new position
                    p->mPosition = (p->mPosition + ( directionPart )) + (((directionPart) - direction) * mBounce);

                    // reflect direction vector
                    p->mDirection = (p->mDirection - (2.0f * p->mDirection.dotProduct( mPlaneNormal ) * mPlaneNormal)) * mBounce;
                }
            }
        }
    }
void LinearForceAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
{
    ParticleIterator pi = pSystem->_getIterator();
    Particle *p;

    Vector3 scaledVector = Vector3::ZERO;

    // Precalc scaled force for optimisation
    if (mForceApplication == FA_ADD)
    {
        // Scale force by time
        scaledVector = mForceVector * timeElapsed;
    }

    while (!pi.end())
    {
        p = pi.getNext();
        if (mForceApplication == FA_ADD)
        {
            p->direction += scaledVector;
        }
        else // FA_AVERAGE
        {
            p->direction = (p->direction + mForceVector) / 2;
        }
    }
}
Esempio n. 4
0
    //-----------------------------------------------------------------------
    void ScaleAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        ParticleIterator pi = pSystem->_getIterator();
        Particle *p;
        Real ds;

        // Scale adjustments by time
        ds = mScaleAdj * timeElapsed;

		Real NewWide, NewHigh;

        while (!pi.end())
        {
            p = pi.getNext();

			if( p->hasOwnDimensions() == false )
			{
            	NewWide = pSystem->getDefaultWidth() + ds;
	            NewHigh = pSystem->getDefaultHeight() + ds;

			}
			else
			{
            	NewWide = p->getOwnWidth()  + ds;
            	NewHigh = p->getOwnHeight() + ds;
			}
			p->setDimensions( NewWide, NewHigh ); 
        }

    }
    //-----------------------------------------------------------------------
    void DirectionRandomiserAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        ParticleIterator pi = pSystem->_getIterator();
        Particle *p;
        Real length = 0;

        while (!pi.end())
        {
            p = pi.getNext();
            if (mScope > Math::UnitRandom())
            {
                if (!p->direction.isZeroLength())
                {
                    if (mKeepVelocity)
                    {
                        length = p->direction.length();
                    }

                    p->direction += Vector3(Math::RangeRandom(-mRandomness, mRandomness) * timeElapsed,
                        Math::RangeRandom(-mRandomness, mRandomness) * timeElapsed,
                        Math::RangeRandom(-mRandomness, mRandomness) * timeElapsed);

                    if (mKeepVelocity)
                    {
                        p->direction *= length / p->direction.length();
                    }
                }
            }
        }
    }
	//-----------------------------------------------------------------------
	void MeshRotationAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
	{
		ParticleIterator pi = pSystem->_getIterator();
		Particle *p;
		Real ds;

		// Rotation adjustments by time
		ds = timeElapsed;

		while (!pi.end())
		{
			p = pi.getNext();

			MeshParticleVisualData *data = static_cast<MeshParticleVisualData *>(p->getVisualData());

			data->mYawRotation = data->mYawRotation + ds * data->mYawRotationSpeed;

			data->mPitchRotation = data->mPitchRotation + ds * data->mPitchRotationSpeed;

			data->mRollRotation = data->mRollRotation + ds * data->mRollRotationSpeed;

			if ( data->mYawRotation != Radian(0) || data->mPitchRotation != Radian(0) || 
				data->mRollRotation != Radian(0) )
				pSystem->_notifyParticleRotated();
		}

	}
    //-----------------------------------------------------------------------
    void ColourImageAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        Particle*			p;
		ParticleIterator	pi				= pSystem->_getIterator();

        if (!mColourImageLoaded)
        {
            _loadImage();
        }

		int				   width			= (int)mColourImage.getWidth()  - 1;
        
		while (!pi.end())
		{
			p = pi.getNext();
			const Real		life_time		= p->totalTimeToLive;
			Real			particle_time	= 1.0f - (p->timeToLive / life_time); 

			if (particle_time > 1.0f)
				particle_time = 1.0f;
			if (particle_time < 0.0f)
				particle_time = 0.0f;

			const Real		float_index		= particle_time * width;
			const int		index			= (int)float_index;

            if(index < 0)
            {
				p->colour = mColourImage.getColourAt(0, 0, 0);
            }
            else if(index >= width) 
            {
                p->colour = mColourImage.getColourAt(width, 0, 0);
            }
            else
            {
                // Linear interpolation
				const Real		fract		= float_index - (Real)index;
				const Real		to_colour	= fract;
				const Real		from_colour	= 1.0f - to_colour;
             
                ColourValue from=mColourImage.getColourAt(index, 0, 0),
							to=mColourImage.getColourAt(index+1, 0, 0);

				p->colour.r = from.r*from_colour + to.r*to_colour;
                p->colour.g = from.g*from_colour + to.g*to_colour;
                p->colour.b = from.b*from_colour + to.b*to_colour;
                p->colour.a = from.a*from_colour + to.a*to_colour;
			}
		}
    }
void RotationAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
{
    ParticleIterator pi = pSystem->_getIterator();
    Particle *p;
    Real ds;

    // Rotation adjustments by time
    ds = timeElapsed;

    Radian NewRotation;

    while (!pi.end())
    {
        p = pi.getNext();
        NewRotation = p->rotation + (ds * p->rotationSpeed);
	p->setRotation( NewRotation );
    }
}
Esempio n. 9
0
int main(int argc, char **argv) {
	NaiveParticlePool<struct simpleParticle>* pool = new NaiveParticlePool<struct simpleParticle>(NUM_PARTICLES);
	SimpleParticleInitializer* init = new SimpleParticleInitializer();
	SimpleParticleUpdater* update = new SimpleParticleUpdater(100);
	Curve<long,long>* c = new ConstantCurve(400);

	ParticleSystem<struct simpleParticle>* system = new ParticleSystem<struct simpleParticle>(pool,init,update,c,false);

	testParticleSystem(system,&valFunc,c,pool,NUM_PARTICLES,30);

	printf("Hello world!\n");

	printf("Managed to create curve on stack.\n");
	printf("Curve gives value %ld for input 45.\n", c->getValue(45));

	//struct simpleParticle** readParticles = (struct simpleParticle**) calloc(NUM_PARTICLES,sizeof(struct simpleParticle*));
	size_t currentPos = 0;

	for(int i = 0; i < ITER; i++) {
		currentPos = 0;
		printf("Started step %d of %d for particle system.\n", i + 1,ITER);
		system->step();

		for(int i = 0; i < NUM_THREADS; i++) startWorkerThread(system);
		ParticleIterator<struct simpleParticle>* living = system->getLivingParticles();

		struct simpleParticle* part;
		while(living->hasNext()) {
			part = living->next();
			//printf("Particle value: %d\n", part->value);
			//if(part->value != i + 1) printf("Read non-updated particle at round %d. %d\n", i + 1, part->value);
			//readParticles[currentPos] = part;
			currentPos++;
			living->done(part);
		}
		delete living;
		printf("%ld Particles this iteration.\n", currentPos);
	}
	//free(readParticles);
	return 0;
}
    //-----------------------------------------------------------------------
    void ColourFaderAffector2::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        ParticleIterator pi = pSystem->_getIterator();
        Particle *p;
        float dr1, dg1, db1, da1;
		float dr2, dg2, db2, da2;

		// Scale adjustments by time
		dr1 = mRedAdj1   * timeElapsed;
		dg1 = mGreenAdj1 * timeElapsed;
		db1 = mBlueAdj1  * timeElapsed;
		da1 = mAlphaAdj1 * timeElapsed;

		// Scale adjustments by time
		dr2 = mRedAdj2   * timeElapsed;
		dg2 = mGreenAdj2 * timeElapsed;
		db2 = mBlueAdj2  * timeElapsed;
		da2 = mAlphaAdj2 * timeElapsed;

        while (!pi.end())
        {
			p = pi.getNext();

			if( p->timeToLive > StateChangeVal )
			{
				applyAdjustWithClamp(&p->colour.r, dr1);
				applyAdjustWithClamp(&p->colour.g, dg1);
				applyAdjustWithClamp(&p->colour.b, db1);
				applyAdjustWithClamp(&p->colour.a, da1);
			}
			else
			{
				applyAdjustWithClamp(&p->colour.r, dr2);
				applyAdjustWithClamp(&p->colour.g, dg2);
				applyAdjustWithClamp(&p->colour.b, db2);
				applyAdjustWithClamp(&p->colour.a, da2);
			}
        }

    }
	//-----------------------------------------------------------------------
	void MeshAnimationAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
	{
		ParticleIterator pi = pSystem->_getIterator();
		Particle *p;

		while (!pi.end())
		{
			p = pi.getNext();

			MeshParticleVisualData *data = static_cast<MeshParticleVisualData *>(p->getVisualData());

            data->mAnimationName = mAnimationName;

            data->mDeltaTime = timeElapsed;

            data->mAnimationLoop = mAnimationLoop;

            data->mAnimationSpeedFactor = mAnimationSpeedFactor;

            data->mAnimationUpdated = true;
		}
	}	
Esempio n. 12
0
    //-----------------------------------------------------------------------
    void ColourFaderAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        ParticleIterator pi = pSystem->_getIterator();
        Particle *p;
        float dr, dg, db, da;

        // Scale adjustments by time
        dr = mRedAdj * timeElapsed;
        dg = mGreenAdj * timeElapsed;
        db = mBlueAdj * timeElapsed;
        da = mAlphaAdj * timeElapsed;

        while (!pi.end())
        {
            p = pi.getNext();
            applyAdjustWithClamp(&p->colour.r, dr);
            applyAdjustWithClamp(&p->colour.g, dg);
            applyAdjustWithClamp(&p->colour.b, db);
            applyAdjustWithClamp(&p->colour.a, da);
        }

    }
    //-----------------------------------------------------------------------
    void ColourInterpolatorAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
    {
        Particle*			p;
		ParticleIterator	pi				= pSystem->_getIterator();


		while (!pi.end())
        {
            p = pi.getNext();
			const Real		life_time		= p->totalTimeToLive;
			Real			particle_time	= 1.0f - (p->timeToLive / life_time); 

			if (particle_time <= mTimeAdj[0])
			{
				p->colour = mColourAdj[0];
			} else
			if (particle_time >= mTimeAdj[MAX_STAGES - 1])
			{
				p->colour = mColourAdj[MAX_STAGES-1];
			} else
			{
				for (int i=0;i<MAX_STAGES-1;i++)
				{
					if (particle_time >= mTimeAdj[i] && particle_time < mTimeAdj[i + 1])
					{
						particle_time -= mTimeAdj[i];
						particle_time /= (mTimeAdj[i+1]-mTimeAdj[i]);
						p->colour.r = ((mColourAdj[i+1].r * particle_time) + (mColourAdj[i].r * (1.0f - particle_time)));
						p->colour.g = ((mColourAdj[i+1].g * particle_time) + (mColourAdj[i].g * (1.0f - particle_time)));
						p->colour.b = ((mColourAdj[i+1].b * particle_time) + (mColourAdj[i].b * (1.0f - particle_time)));
						p->colour.a = ((mColourAdj[i+1].a * particle_time) + (mColourAdj[i].a * (1.0f - particle_time)));
						break;
					}
				}
			}
		}
    }
	//-----------------------------------------------------------------------
	void FireExtinguisherAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
	{
		ExtinguishableFireAffectorFactory::affectorIterator affIt = mEfaf->getAffectorIterator();
		ExtinguishableFireAffector* fire;

		while(affIt.hasMoreElements())
		{
			fire = (ExtinguishableFireAffector*)affIt.getNext();

			if (fire->isTemplate())
				continue;

			Real squaredRadius = Math::Pow(fire->getRadius(), 2);
			Vector3 middlePoint = fire->getAbsoluteMiddlePoint();

			ParticleIterator pi = pSystem->_getIterator();
			Particle *p;
			int fireHits = 0;
			while (!pi.end())
			{
				p = pi.getNext();

				if ( middlePoint.squaredDistance(p->position) < squaredRadius )
				{
					// This particle is inside the fire, dispose of it in the next update
					p->timeToLive = 0;
					++fireHits;
				}
			}
			if (fireHits>0)
			{
				Real intensity = fire->reduceIntensity(fireHits*mEffectiveness);
				if (intensity<0) delete fire->getParticleSystem();
			}
		}
	}
    //-----------------------------------------------------------------------
    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;
            }
        }
    }