//-----------------------------------------------------------------------
	void BoxCollider::_affect(ParticleTechnique* particleTechnique, Particle* particle, Real timeElapsed)
	{
		mPredictedPosition = particle->position + mVelocityScale * particle->direction;
		bool collision = false;

		/** Collision detection is a two-step. First, we determine whether the particle is now colliding.
			If it is, the particle is re-positioned. However, a timeElapsed value is used, which is not the same
			as the one that was used at the moment before the particle was colliding. Therefore, we rather 
			want to predict particle collision in front. This probably isn't the fastest solution.
			The same approach was used for the other colliders.
		*/
		switch(mIntersectionType)
		{
			case BaseCollider::IT_POINT:
			{
				// Validate for a point-box intersection
				if (mInnerCollision != mBox.intersects(particle->position))
				{
					// Collision detected (re-position the particle)
					particle->position -= mVelocityScale * particle->direction;
					collision = true;
				}
				else if (mInnerCollision != mBox.intersects(mPredictedPosition))
				{
					// Collision detected
					collision = true;
				}
			}
			break;

			case BaseCollider::IT_BOX:
			{
				// Validate for a box-box intersection
				if (particle->particleType != Particle::PT_VISUAL)
					break;

				VisualParticle* visualParticle = static_cast<VisualParticle*>(particle);
				AxisAlignedBox box;
				populateAlignedBox(box,
					visualParticle->position, 
					visualParticle->width, 
					visualParticle->height,
					visualParticle->depth);

				if (mInnerCollision != box.intersects(mBox))
				{
					// Collision detected (re-position the particle)
					particle->position -= mVelocityScale * particle->direction;
					collision = true;
				}
				else
				{
					AxisAlignedBox box;
					populateAlignedBox(box,
						mPredictedPosition, 
						visualParticle->width, 
						visualParticle->height,
						visualParticle->depth);
					if (mInnerCollision != box.intersects(mBox))
					{
						// Collision detected
						collision = true;
					}
				}
			}
			break;
		}

		if (collision)
		{
			calculateDirectionAfterCollision(particle);
			calculateRotationSpeedAfterCollision(particle);
			particle->addEventFlags(Particle::PEF_COLLIDED);
		}
	}
void PUParticle3DPlaneCollider::updatePUAffector( PUParticle3D *particle, float deltaTime )
{
    //for (auto iter : _particleSystem->getParticles())
    {
        //PUParticle3D *particle = iter;
        _predictedPosition = particle->position + _velocityScale * particle->direction;
        bool collision = false;

        switch(_intersectionType)
        {
        case PUParticle3DBaseCollider::IT_POINT:
            {
                // Validate for a point-plane intersection (on the plane or the back side)
                // First determine whether it is now colliding (some affector made the particle move), else
                // determine whether it WILL be colliding
                if (_plane.getDistance(particle->position) <= 0.0f)
                {
                    // Collision detected (re-position the particle)
                    particle->position -= _velocityScale * particle->direction;
                    collision = true;
                }
                else if (_plane.getDistance(_predictedPosition) <= 0.0f)
                {
                    // Collision detected
                    collision = true;
                }
            }
            break;

        case PUParticle3DBaseCollider::IT_BOX:
            {

                AABB box;
                populateAlignedBox(box,
                    particle->position, 
                    particle->width, 
                    particle->height,
                    particle->depth);
                //FIXME
                //if (box.intersects(_plane))
                //{
                //	// Collision detected (re-position the particle)
                //	particle->position -= _velocityScale * particle->direction;
                //	collision = true;
                //}
                //else 
                //{
                //	populateAlignedBox(box,
                //		_predictedPosition, 
                //		particle->width, 
                //		particle->height,
                //		particle->depth);
                //	if (box.intersects(_plane))
                //	{
                //		// Collision detected
                //		collision = true;
                //	}
                //}
            }
            break;
        }

        if (collision)
        {
            calculateDirectionAfterCollision(particle, deltaTime);
            calculateRotationSpeedAfterCollision(particle);
            particle->addEventFlags(PUParticle3D::PEF_COLLIDED);
        }
    }

}
示例#3
0
void PUBoxCollider::updatePUAffector( PUParticle3D *particle, float deltaTime )
{
    //for (auto iter : _particleSystem->getParticles())
    {
        //PUParticle3D *particle = iter;
        _predictedPosition = particle->position + _velocityScale * particle->direction;
        bool collision = false;

        /** Collision detection is a two-step. First, we determine whether the particle is now colliding.
            If it is, the particle is re-positioned. However, a timeElapsed value is used, which is not the same
            as the one that was used at the moment before the particle was colliding. Therefore, we rather 
            want to predict particle collision in front. This probably isn't the fastest solution.
            The same approach was used for the other colliders.
        */
        switch(_intersectionType)
        {
            case PUBaseCollider::IT_POINT:
            {
                // Validate for a point-box intersection
                if (_innerCollision != _box.containPoint(particle->position))
                {
                    // Collision detected (re-position the particle)
                    particle->position -= _velocityScale * particle->direction;
                    collision = true;
                }
                else if (_innerCollision != _box.containPoint(_predictedPosition))
                {
                    // Collision detected
                    collision = true;
                }
            }
            break;

            case PUBaseCollider::IT_BOX:
            {
                AABB box;
                populateAlignedBox(box,
                    particle->position, 
                    particle->width, 
                    particle->height,
                    particle->depth);

                if (_innerCollision != box.intersects(_box))
                {
                    // Collision detected (re-position the particle)
                    particle->position -= _velocityScale * particle->direction;
                    collision = true;
                }
                else
                {
                    populateAlignedBox(box,
                        _predictedPosition, 
                        particle->width, 
                        particle->height,
                        particle->depth);
                    if (_innerCollision != box.intersects(_box))
                    {
                        // Collision detected
                        collision = true;
                    }
                }
            }
            break;
        }

        if (collision)
        {
            calculateDirectionAfterCollision(particle);
            calculateRotationSpeedAfterCollision(particle);
            particle->addEventFlags(PUParticle3D::PEF_COLLIDED);
        }
    }

}
void PUParticle3DSphereCollider::updatePUAffector( PUParticle3D *particle, float deltaTime )
{
    //for (auto iter : _particleSystem->getParticles())
    {
        //PUParticle3D *particle = iter;
        _predictedPosition = particle->position + _velocityScale * particle->direction;
        bool collision = false;
        Vec3 distance = particle->position - _derivedPosition;
        float distanceLength = distance.length();
        float scaledRadius = 0.3333f * (_affectorScale.x + _affectorScale.y + _affectorScale.z) * _radius; // Scaling changed in V 1.3.1

        switch(_intersectionType)
        {
        case PUParticle3DBaseCollider::IT_POINT:
            {
                // Validate for a point-sphere intersection
                if (_innerCollision == (distanceLength > scaledRadius))
                {
                    // Collision detected (re-position the particle)
                    particle->position -= _velocityScale * particle->direction;
                    collision = true;
                }
                else
                {
                    distance = _predictedPosition - _derivedPosition;
                    distanceLength = distance.length();
                    if (_innerCollision == (distanceLength > scaledRadius))
                    {
                        // Collision detected
                        collision = true;
                    }
                }
            }
            break;

        case PUParticle3DBaseCollider::IT_BOX:
            {
                //// Validate for a box-sphere intersection
                //if (particle->particleType != Particle::PT_VISUAL)
                //	break;
                AABB box;
                populateAlignedBox(box,
                    particle->position, 
                    particle->width, 
                    particle->height,
                    particle->depth);

                //FIXME
                //if (_innerCollision != box.intersects(_sphere))
                //{
                //	// Collision detected (re-position the particle)
                //	particle->position -= _velocityScale * particle->direction;
                //	collision = true;
                //}
                //else
                //{
                //	AABB box;
                //	populateAlignedBox(box,
                //		_predictedPosition, 
                //		particle->width, 
                //		particle->height,
                //		particle->depth);
                //	if (_innerCollision != box.intersects(_sphere))
                //	{
                //		// Collision detected
                //		collision = true;
                //	}
                //}
            }
            break;
        }

        if (collision)
        {
            calculateDirectionAfterCollision(particle, distance, distanceLength);
            calculateRotationSpeedAfterCollision(particle);
            particle->addEventFlags(PUParticle3D::PEF_COLLIDED);
        }
    }
}