/**<Summary> 
	* Calculate the extent of the passed GamedObject 
	* in the calling GameObject Coordinate System
	* </Summary>
	*/
	Vector3D GameObject::getTransformedExtents(SharedPointer<GameObject> i_other)
	{
		Vector3D i_otherExtentInThis;
		Matrix4x4 i_otherCentrePositionInThis = Matrix4x4(getTranslatedPosition(i_other->getPosition()));


		//Tranforming the Extents coordinate of passed gameObject in calling gameObject coordinate system
		Vector3D i_otherXExtentPositionInThis = getTranslatedPosition(i_other->getPosition() + Vector3D(i_other->mCollidingBox->getExtendX(), 0, 0));
		Vector3D i_otherYExtentPositionInThis = getTranslatedPosition(i_other->getPosition() + Vector3D(0, i_other->mCollidingBox->getExtendY(), 0));
		Vector3D i_otherZExtentPositionInThis = getTranslatedPosition(i_other->getPosition() + Vector3D(0, 0, i_other->mCollidingBox->getExtendZ()));

		Vector3D i_otherXExtentVectorInThis = i_otherXExtentPositionInThis - i_otherCentrePositionInThis.getPositionFromMatrix4x4();
		Vector3D i_otherYExtentVectorInThis = i_otherYExtentPositionInThis - i_otherCentrePositionInThis.getPositionFromMatrix4x4();
		Vector3D i_otherZExtentVectorInThis = i_otherZExtentPositionInThis - i_otherCentrePositionInThis.getPositionFromMatrix4x4();

		//Creating the passed gameObject extent Vectors in calling gameObject coordinate system
		i_otherExtentInThis.setX(abs(
			i_otherXExtentVectorInThis.dotProduct(Vector3D(1.0f, 0.0f, 0.0f)) +
			i_otherYExtentVectorInThis.dotProduct(Vector3D(1.0f, 0.0f, 0.0f)) +
			i_otherZExtentVectorInThis.dotProduct(Vector3D(1.0f, 0.0f, 0.0f))
			));

		i_otherExtentInThis.setY(abs(
			i_otherXExtentVectorInThis.dotProduct(Vector3D(0.0f, 1.0f, 0.0f)) +
			i_otherYExtentVectorInThis.dotProduct(Vector3D(0.0f, 1.0f, 0.0f)) +
			i_otherZExtentVectorInThis.dotProduct(Vector3D(0.0f, 1.0f, 0.0f))
			));

		i_otherExtentInThis.setZ(abs(
			i_otherXExtentVectorInThis.dotProduct(Vector3D(0.0f, 0.0f, 1.0f)) +
			i_otherYExtentVectorInThis.dotProduct(Vector3D(0.0f, 0.0f, 1.0f)) +
			i_otherZExtentVectorInThis.dotProduct(Vector3D(0.0f, 0.0f, 1.0f))
			));

		//returning the extent of passed gameObject in calling gameObject coordinate system
		return i_otherExtentInThis;
	}
示例#2
0
void PhysicsEngine::collisionTestFastParticles() {
    raySphereRelative.resizeToSizeIfRequiredWithBatchSize(fastParticles.getCount(), SphereRayHelper::batchSize);

    Array<int> collisionTestResult;
    collisionTestResult.setNumberOfElements(fastParticles.getCount(), false);


    for( int index = 0; index < physicsBodies.getCount(); index++ ) {
        SharedPointer<PhysicsBody> currentBody = physicsBodies[index];

        float collisionSphereRadius = currentBody->boundingSphereRadius;

        SphereRayHelper::transferFastParticlesToRaySphereSoa(fastParticles, collisionSphereRadius, currentBody->getPosition(), raySphereRelative);
        SphereRayHelper::doBatchedCollisionTests(raySphereRelative);
        SphereRayHelper::checkForCollisions(raySphereRelative, fastParticles, collisionTestResult);

        // process the collision test result
        for( int collisionTestResultIndex = 0; collisionTestResultIndex < fastParticles.getCount(); collisionTestResultIndex++ ) {
            if( collisionTestResult[collisionTestResultIndex] != 0 ) {
                fastParticles[collisionTestResultIndex]->nextHitAnything = true;
                fastParticles[collisionTestResultIndex]->nextHitBody = currentBody;

                // NOTE< for now just against/for the bounding sphere >
                // TODO< calculate the hit position? >
            }
        }
    }
}
	/**
	*<summary>
	* Check separation Axis test between passed GameObject(A) and calling GameObject(B)
	* You may need to call it twice - for checking collision of B in A's coordinate system
	*</Summary>
	*/
	bool GameObject::separationAxisTest(SharedPointer<GameObject> i_other, float& o_collisionTime, float & o_separationTime, myEngine::typedefs::Axis &o_collisionAxis) //Move to Collsion System to make it better - To-Do
	{
		bool isColliding = false;
		float tCollisionInX = 0.0f;
		float tSeparationInX = 0.0f;
		float tCollisionInY = 0.0f;
		float tSeparationInY = 0.0f;
		float tCollisionInZ = 0.0f;
		float tSeparationInZ = 0.0f;

		//Position of other GameObject in this
		Vector3D i_otherCenterPositionInThis = getTranslatedPosition(i_other->getPosition());

		//Extent of other gameObject in this
		Vector3D i_otherExtentInThis = getTransformedExtents(i_other);

		//Transformed velocity of calling gamobject in its own coordiante system
		Vector3D thisVelocityInThis = getTranslationMatrix() *physicsComponent->getCurrentVelocity();

		//Velocity of other GameObject in calling gameObject coordinate system
		Vector3D i_otherVelocityInThis = getTranslationMatrix() * i_other->physicsComponent->getCurrentVelocity();

		//Relative velocity of other gamObject in freezed gameObject coordinate system i.e. in calling gameObject coordiante system
		Vector3D i_otherChangedVelocityInThis = i_otherVelocityInThis - thisVelocityInThis;

		//Expanding the extents of calling gameObject
		float thisChangedXExtent = getCollider()->getExtendX() + i_otherExtentInThis.getX();
		float thisChangedYExtent = getCollider()->getExtendY() + i_otherExtentInThis.getY();
		float thisChangedZExtent = getCollider()->getExtendZ() + i_otherExtentInThis.getZ();
		
		bool finalCollisionTimeInitialized = false;

		//Swept collision for each axes

		//Checking in X-Axis
		switch (i_otherCenterPositionInThis.getX() >= 0 )
		{
		case true:
			if (i_otherCenterPositionInThis.getX() <= thisChangedXExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getX() != 0)
				{
					tCollisionInX = abs(((0 + thisChangedXExtent) - i_otherCenterPositionInThis.getX()) / i_otherChangedVelocityInThis.getX());
					tSeparationInX = abs((i_otherCenterPositionInThis.getX() - (0 - thisChangedXExtent)) / i_otherChangedVelocityInThis.getX());
					o_collisionTime = tCollisionInX;
					o_separationTime = tSeparationInX;
					o_collisionAxis = myEngine::typedefs::XAxis;
					finalCollisionTimeInitialized = true;
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getX()) <= thisChangedXExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getX() != 0)
				{
					tCollisionInX = abs((i_otherCenterPositionInThis.getX() - (0 - thisChangedXExtent)) / i_otherChangedVelocityInThis.getX());
					tSeparationInX = abs(((0 + thisChangedXExtent) - i_otherCenterPositionInThis.getX()) / i_otherChangedVelocityInThis.getX());
					o_collisionTime = tCollisionInX;
					o_separationTime = tSeparationInX;
					o_collisionAxis = myEngine::typedefs::XAxis;
					finalCollisionTimeInitialized = true;
				}				
			}
			else return false;
			break;
		}


		//Check in Y-axis in case X-Axis collision is true
		switch (i_otherCenterPositionInThis.getY() >= 0)
		{
		case true:
			if (i_otherCenterPositionInThis.getY() <= thisChangedYExtent)
			{
				//To-Do - time of collision -Done but need testing
				if (i_otherChangedVelocityInThis.getY() != 0)
				{
					tCollisionInY = abs(((0 + thisChangedYExtent) - i_otherCenterPositionInThis.getY()) / i_otherChangedVelocityInThis.getY());
					tSeparationInY = abs((i_otherCenterPositionInThis.getY() - (0 - thisChangedYExtent)) / i_otherChangedVelocityInThis.getY());
					
					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInY;
						o_separationTime = tSeparationInY;
						o_collisionAxis = myEngine::typedefs::YAxis;
					}
					else
					{
						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInY;
							o_collisionAxis = myEngine::typedefs::YAxis;

						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInY;
					}
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getY()) <= thisChangedYExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getY() != 0)
				{
					tCollisionInY = abs((i_otherCenterPositionInThis.getY() - (0 - thisChangedYExtent)) / i_otherChangedVelocityInThis.getY());
					tSeparationInY = abs(((0 + thisChangedYExtent) - i_otherCenterPositionInThis.getY()) / i_otherChangedVelocityInThis.getY());
					
					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInY;
						o_separationTime = tSeparationInY;
						o_collisionAxis = myEngine::typedefs::YAxis;
					}
					else
					{

						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInY;
							o_collisionAxis = myEngine::typedefs::YAxis;
						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInY;
					}
				}
			}
			else return false;
			break;
		}


		//Check in Z-axis in case X-Axis and Y-Axis collision is true
		switch (i_otherCenterPositionInThis.getZ() >= 0)
		{
		case true:
			if (i_otherCenterPositionInThis.getZ() <= thisChangedZExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getZ() != 0)
				{
					tCollisionInZ = abs(((0 + thisChangedZExtent) - i_otherCenterPositionInThis.getZ()) / i_otherChangedVelocityInThis.getZ());
					tSeparationInZ = abs((i_otherCenterPositionInThis.getZ() - (0 - thisChangedZExtent)) / i_otherChangedVelocityInThis.getZ());

					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInZ;
						o_separationTime = tSeparationInZ;
						o_collisionAxis = myEngine::typedefs::ZAxis;
					}
					else
					{

						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInZ;
							o_collisionAxis = myEngine::typedefs::ZAxis;
						}

						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInZ;
					}
				}
			}
			else return false;
			break;
		case false:
			if (abs(i_otherCenterPositionInThis.getZ()) <= thisChangedZExtent)
			{
				//To-Do - time of collision - Done but need testing
				if (i_otherChangedVelocityInThis.getZ() != 0)
				{
					tCollisionInZ = abs((i_otherCenterPositionInThis.getZ() - (0 - thisChangedZExtent)) / i_otherChangedVelocityInThis.getZ());
					tSeparationInZ = abs(((0 + thisChangedZExtent) - i_otherCenterPositionInThis.getZ()) / i_otherChangedVelocityInThis.getZ());

					if (!finalCollisionTimeInitialized)
					{
						o_collisionTime = tCollisionInZ;
						o_separationTime = tSeparationInZ;
						o_collisionAxis = myEngine::typedefs::ZAxis;
					}
					else
					{
						if (tCollisionInY < o_collisionTime)
						{
							o_collisionTime = tCollisionInZ;
							o_collisionAxis = myEngine::typedefs::ZAxis;
						}
						if (tSeparationInY < o_separationTime)
							o_separationTime = tSeparationInZ;
					}
				}
			}
			else return false;
			break;
		}

		
		//returning if all if's are false i.e. collsion occured in this coordinate system
		return true;
	}