CollisionResult CollisionBody::checkIfCollide(CollisionBody *body2, float deltaT) {
	// First of all, don't check collision between collision bodies of the same physical body,
	// or of the same group
	if (parent == body2->parent || parent->getCollisionGroup() == body2->parent->getCollisionGroup()) {
		return CollisionResult(this, body2, 0, Vector3(0, 0, 0));
	}
	Vector3 body1Vel = this->parent->getVelocity(deltaT * 1000.0f);
	Vector3 body2Vel = body2->parent->getVelocity(deltaT * 1000.0f);
	Vector3 body1Pos = *getAbsolutePosition();
	Vector3 body2Pos = *(body2->getAbsolutePosition());
	// Sphere-Sphere collision
	if (type == SPHERE && body2->type == SPHERE) {
		float distance = pow(body2Pos.x - body1Pos.x, 2) + pow(body2Pos.y - body1Pos.y, 2) + pow(body2Pos.z - body1Pos.z, 2);
		if (distance < pow(this->radius + body2->radius, 2)) {
			// We have a collision!
			float penetration = sqrt(pow(this->radius + body2->radius, 2) - distance);
			Vector3 normal = Vector3(body1Pos - body2Pos).normalised();
			return CollisionResult(this, body2, penetration, normal);
		}
	}
	// Sphere-Plane collision
	if (type == SPHERE && body2->type == PLANE) {
		float distancePlaneToSphere = Vector3::dot(*(body2->normal), body1Pos) + body2->radius;
		if (distancePlaneToSphere < radius) {
			// We have a collision!
			float penetration = radius - distancePlaneToSphere;
			return CollisionResult(this, body2, penetration, Vector3(*(body2->normal)));
		}
	}
	// Sphere-InvertedCylinder collision
	if (type == SPHERE && body2->type == INV_CYLINDER) {
		float cylMin = ((body2Pos * *(body2->normal)) - (*(body2->normal) * body2->length)).getLength();
		float cylMax = ((body2Pos * *(body2->normal)) + (*(body2->normal) * body2->length)).getLength();
		float body1AxisPos = (body1Pos * *(body2->normal)).getLength();
		float cylMinX = body2Pos.x - body2->length;
		float cylMaxX = body2Pos.x + body2->length;
		/* This is the downside of this implementation: if the sphere is only slightly after
		* the end of the cylinder, but the lower half is still colliding with it, this
		* algorithm won't detect it.
		*/
		if (body1AxisPos >= cylMin && body1AxisPos <= cylMax) {
			Vector3 circunferenceDistance = (body2Pos - body1Pos) * (Vector3(1, 1, 1) - *(body2->normal));
			float distance = pow(circunferenceDistance.x, 2) + pow(circunferenceDistance.y, 2) + pow(circunferenceDistance.z, 2);
			if (distance > pow(body2->radius - this->radius, 2)) {
				// We have a collision!
				float penetration = sqrt(distance - pow(body2->radius - this->radius, 2));
				Vector3 normal = ((body1Pos - body2Pos) * (Vector3(1, 1, 1) - *(body2->normal))).normalised();
				return CollisionResult(this, body2, penetration, normal);
			}
		}
	}
	// If there's no collision, or we're trying to detect collision between planes and cylinders, return a no-collision result
	return CollisionResult(this, body2, 0, Vector3(0, 0, 0));
}
Ejemplo n.º 2
0
Archivo: game.c Proyecto: yxrkt/DigiPen
//**************//
// Game Update  //
//**************//
int GSGameProc()
{
    Move();
    
    RunAI();
    
    if (GetVerticalBlankCount()  % 15 == 0)
        SwapBGPalette();

    return CollisionResult();
}