Пример #1
0
void CRigidBody::HandleSphereToSphereCollision(CCollisionMessage* ColMsg)
{
	CVehicle* Car = (CVehicle*)ColMsg->GetEntity();
	Vector3f CenterToCenter = *ColMsg->GetCenterToCenter();

	// set translate
	m_vReflection = CenterToCenter*0.05f;
	m_vPosition = m_translate;
	m_vDirectionWhenDisturbed = m_vReflection;

	// set rotation
	if (CenterToCenter.Length() == 0.0f) CenterToCenter = Vector3f(1.0f, 0.0f, 0.0f);
	float theta1 = (CenterToCenter.Dot(Car->GetVehicleHeadingWC()))/(CenterToCenter.Length()*Car->GetVehicleHeadingWC().Length());
	Vector3f CP = CenterToCenter.Cross(Vector3f(0.0f, 1.0f, 0.0f));
	float theta2 = (CP.Dot(Car->GetVehicleHeadingWC()))/(CP.Length()*Car->GetVehicleHeadingWC().Length());

//	CLog::GetLog().Write(LOG_DEBUGOVERLAY, 120, "theta1 = %f", theta1);
//	CLog::GetLog().Write(LOG_DEBUGOVERLAY, 121, "theta2 = %f", theta2);

	float spin;
	if (0.0f < theta1 && theta1 < 1.0f) {
		// LOWER-LEFT QUADRANT
		if (0.0f < theta2 && theta2 < 1.0f) {
			spin = theta2;
		}
		// LOWER-RIGHT QUADRANT
		else {
			spin = theta2;
		}
	}
	else {
		// UPPER-LEFT QUADRANT
		if (0.0f < theta2 && theta2 < 1.0f) {
			spin = -theta2;
		}
		// UPPER-RIGHT QUADRANT
		else {
			spin = -theta2;
		}
	}

	spin *= RIGIDBODY_SPIN_FACTOR;
	m_vRotation = Vector3f(0.0f, spin, 0.0f);

	// actually set it!
	Car->SetVehicleVelocityLC(0.0f);
	Car->SetVehiclePositionLC(Vector3f(m_vPosition.X(), m_vPosition.Z(), m_vPosition.Y()));

	disturbed = true;
}
Пример #2
0
void CRigidBody::DeliverCollisionMessage(CCollisionMessage* ColMsg)
{
	if (!ColMsg) return;

	if (ColMsg->GetCollisionType() == SPHERE_TO_SPHERE) {
		HandleSphereToSphereCollision(ColMsg);
		return;
	}

	/****** Deploy to HandlePushCollision() if this is the case ******/
	// Push collision not working. Commenting this out for now.
	/*	if (ColMsg->GetCollisionType() == PUSHED) {
		HandlePushCollision(ColMsg);
		return;
	}
*/ 

	CVehicle* Car = (CVehicle*)ColMsg->GetEntity();

	/************** set reflection motion ************/

	m_vPosition = m_translate + (*ColMsg->GetReverse())*RIGIDBODY_SPACING_FACTOR;

	Vector3f velocityWC;
	if (disturbed) {
		velocityWC = m_vDirectionWhenDisturbed*80.0f;
	}
	else {
		velocityWC = Car->GetVehicleVelocityWC();
		// if reversing, velocityWC will point in opposite direction as actual velocity
		if (Car->GetVehicleVelocityLC().X() < 0.0f)
			velocityWC *= -1.0f;
	}

	m_vReflection = velocityWC - 2.0f*(velocityWC.Dot(*ColMsg->GetNormal()))*(*ColMsg->GetNormal());
	m_vReflection *= RIGIDBODY_REFLECTION_FACTOR;
	m_vDirectionWhenDisturbed = m_vReflection;

	Car->SetVehicleVelocityLC(0.0f);
	Car->SetVehiclePositionLC(Vector3f(m_vPosition.X(), m_vPosition.Z(), m_vPosition.Y()));

	/*************** set angular velocity ******************/

	// Compute angle between vehicle heading and plane
	Vector3f PlaneEdge = ColMsg->GetPlane()->Edge0();
	Vector3f CarHeading = Car->GetVehicleHeadingWC();
	float angle = acos(CarHeading.Dot(PlaneEdge)/(PlaneEdge.Length()*CarHeading.Length()));

	// spin CW or CCW?
	float spin; // magnitude of spin about the y-axis
	if (angle > Math<float>::PI/2.0f) { // CCW
		spin = Math<float>::PI - angle;
	}
	else { // CW
		spin = -angle;
	}
	spin *= RIGIDBODY_SPIN_FACTOR;
	m_vRotation = Vector3f(0.0f, spin, 0.0f);

	/*************** set vectors that are actually used in renderer ************/
	/*********************** to the values computed above **********************/

	m_translate = m_vPosition;
	m_box.Center() = m_vPosition;
	m_sphere.Center() = m_vPosition;
	Car->GetRotationLC().Z() += spin;

	disturbed = true;

	/*
	CLog::GetLog().Write(LOG_MISC, "\n\n\nreflection = (%f, %f, %f)",
		m_vReflection.X(), m_vReflection.Y(), m_vReflection.Z());
	CLog::GetLog().Write(LOG_MISC, "direction = (%f, %f, %f)\n\n",
		m_vDirectionWhenDisturbed.X(), m_vDirectionWhenDisturbed.Y(), m_vDirectionWhenDisturbed.Z());
*/
}