All pastes #1930209 Raw Edit

Contact

public java v1 · immutable
#1930209 ·published 2010-09-01 01:25 UTC
rendered paste body
package collisions;import physics.PhysicsData;import physics.Vector2;/* * A contact represents two objects in contact (in this case * Contact representing two particles). Resolving a * contact removes their interpenetration, and applies sufficient * impulse to keep them apart. Colliding bodies may also rebound. * * The contact has no callable functions, it just holds the * contact details. To resolve a set of contacts, use the particle * contact resolver class. */public class Contact {	/*	 * Holds the particles that are involved in the contact. The	 * second of these can be null, for contacts with the scenery.	 */	private PhysicsData[] pdArray = {null, null};    /*	 * Holds the normal restitution coefficient at the contact.	 */	private float restitution = 1.0f;	/*	 * Holds the depth of the interpenetration.	 */	private float penetration;	/*	 * Holds the direction of the contact	 */	private Vector2 contactNormal;		public Contact(PhysicsData pd1, PhysicsData pd2, float restitution, float penetration, Vector2 contactNormal) {		this.pdArray[0] = pd1;		this.pdArray[1] = pd2;		this.penetration = penetration;		this.contactNormal = contactNormal;	}		/*	 * Resolves this contact, for both velocity and interpenetration.	 */	public void resolve(long timePassed) {		this.resolveVelocity(timePassed);		this.resolveInterpenetration(timePassed);	}		/*	 * Calculates the separating velocity at this contact.	 */	public float calculateSeperatingVelocity() {		Vector2 relativeVelocity = new Vector2(this.pdArray[0].getVelocity());		if (this.pdArray[1] != null)			relativeVelocity.subtract(this.pdArray[1].getVelocity());		return relativeVelocity.dotProduct(this.contactNormal);	}		/*	 * Handles the impulse calculations for this collision.	 */	private void resolveVelocity(long timePassed) {		// Find the velocity in the direction of the contact.		float separatingVelocity = this.calculateSeperatingVelocity();				if (separatingVelocity > 0)			// The contact is either separating or stationary - there’s			// no impulse required.			return;				// Calculate the new separating velocity.		float newSepVelocity = -separatingVelocity * this.restitution;				float deltaVelocity = newSepVelocity - separatingVelocity;				/*		 * We apply the change in velocity to each object in proportion to		 * its inverse mass (i.e., those with lower inverse mass [higher		 * actual mass] get less change in velocity).		 */		float totalInverseMass = this.pdArray[0].getInverseMass();		if (this.pdArray[1] != null)			totalInverseMass += this.pdArray[1].getInverseMass();				// If all particles have infinite mass, then impulses have no effect.		if (totalInverseMass <= 0)			return;				// Calculate the impulse to apply.		float impulse = deltaVelocity / totalInverseMass;				Vector2 impulsePerIMass = Vector2.multiplyByScalar(this.contactNormal, impulse);		// Apply impulses: they are applied in the direction of the contact,		// and are proportional to the inverse mass.		this.pdArray[0].setVelocity(Vector2.add(this.pdArray[0].getVelocity(), Vector2.multiplyByScalar(impulsePerIMass, this.pdArray[0].getInverseMass())));				if (this.pdArray[1] != null)			this.pdArray[1].setVelocity(Vector2.add(this.pdArray[1].getVelocity(), Vector2.multiplyByScalar(impulsePerIMass, -this.pdArray[1].getInverseMass())));	}	/*	 * Handles the interpenetration resolution for this contact	 */	private void resolveInterpenetration(long timePassed) {		if (this.penetration <= 0)			return;				// The movement of each object is based on its inverse mass.		float totalInverseMass = this.pdArray[0].getInverseMass();		if (this.pdArray[1] != null)			totalInverseMass += this.pdArray[1].getInverseMass();				// If all particles have infinite mass, we do nothing		if (totalInverseMass <= 0)			return;				// Find the amount of penetration resolution per unit of inverse mass.		Vector2 movePerIMass = Vector2.multiplyByScalar(this.contactNormal, -this.penetration / totalInverseMass);				// Apply the penetration resolution.		this.pdArray[0].setPosition(Vector2.add(this.pdArray[0].getPosition(), Vector2.multiplyByScalar(movePerIMass, this.pdArray[0].getInverseMass())));		if (this.pdArray[1] != null)			this.pdArray[1].setPosition(Vector2.add(this.pdArray[1].getPosition(), Vector2.multiplyByScalar(movePerIMass, this.pdArray[1].getInverseMass())));	}}