Skip to content

Commit

Permalink
split RigidBody.applyForce() into .applyForce() and .applyImpulse(). …
Browse files Browse the repository at this point in the history
…Both are now taking mass properties into account. Ping @sole
  • Loading branch information
schteppe committed Mar 24, 2013
1 parent bd32a7b commit 49bccee
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 23 deletions.
57 changes: 52 additions & 5 deletions build/cannon.js
Original file line number Diff line number Diff line change
Expand Up @@ -1611,15 +1611,62 @@ CANNON.RigidBody.prototype.computeAABB = function(){
this.aabbNeedsUpdate = false;
};

CANNON.RigidBody.prototype.applyImpulse = function(worldPoint,force,dt){
dt = dt || 1/60;
var r=new CANNON.Vec3(), rotForce=new CANNON.Vec3();
/**
* Apply force to a world point. This could for example be a point on the RigidBody surface. Applying force this way will add to Body.force and Body.tau.
* @param CANNON.Vec3 force The amount of force to add.
* @param CANNON.Vec3 worldPoint A world point to apply the force on.
*/
var RigidBody_applyForce_r = new CANNON.Vec3();
var RigidBody_applyForce_rotForce = new CANNON.Vec3();
CANNON.RigidBody.prototype.applyForce = function(force,worldPoint){
// Compute point position relative to the body center
var r = RigidBody_applyForce_r;
worldPoint.vsub(this.position,r);

// Compute produced rotational force
var rotForce = RigidBody_applyForce_rotForce;
r.cross(force,rotForce);
this.velocity.vadd(force.mult(dt),this.velocity);
this.angularVelocity.vadd(rotForce.mult(dt),this.angularVelocity);

// Add linear force
this.force.vadd(force,this.force);

// Add rotational force
this.tau.vadd(rotForce,this.tau);
};

/**
* Apply impulse to a world point. This could for example be a point on the RigidBody surface. An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
* @param CANNON.Vec3 impulse The amount of impulse to add.
* @param CANNON.Vec3 worldPoint A world point to apply the force on.
*/
var RigidBody_applyImpulse_r = new CANNON.Vec3();
var RigidBody_applyImpulse_velo = new CANNON.Vec3();
var RigidBody_applyImpulse_rotVelo = new CANNON.Vec3();
CANNON.RigidBody.prototype.applyImpulse = function(impulse,worldPoint){
// Compute point position relative to the body center
var r = RigidBody_applyImpulse_r;
worldPoint.vsub(this.position,r);

// Compute produced central impulse velocity
var velo = RigidBody_applyImpulse_velo;
impulse.copy(velo);
velo.mult(this.invMass,velo);

// Add linear impulse
this.velocity.vadd(velo, this.velocity);

// Compute produced rotational impulse velocity
var rotVelo = RigidBody_applyImpulse_rotVelo;
r.cross(impulse,rotVelo);
rotVelo.x *= this.invInertia.x;
rotVelo.y *= this.invInertia.y;
rotVelo.z *= this.invInertia.z;

// Add rotational Impulse
this.angularVelocity.vadd(rotVelo, this.angularVelocity);
};


/**
* @brief Spherical rigid body
* @class CANNON.Sphere
Expand Down
6 changes: 3 additions & 3 deletions build/cannon.min.js

Large diffs are not rendered by default.

49 changes: 40 additions & 9 deletions demos/impulses.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@
<script>

/**
* Demonstrates how to add an impulse to a body in an easy way.
* Think of this impulse as a force added in a short period of time on a point on the body.
* You can add the impulse to any point on the body.
* Demonstrates how to add impulses and forces to a body. You can add the impulses and forces to any point on the body.
* Adding a force to the body will add to Body.force and Body.tau.
* An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
*/

var demo = new CANNON.Demo();

var radius=1, mass=1, f=500;
var radius=1, mass=2, f=500;
var dt=1/60, damping=0.5;

// Add impulse to the body center
demo.addScene("center",function(){
demo.addScene("center impulse",function(){
var world = setupWorld(demo);
var shape = new CANNON.Sphere(radius);
var body = new CANNON.RigidBody(mass,shape);
Expand All @@ -37,12 +37,12 @@

// Add an impulse to the center
var worldPoint = new CANNON.Vec3(0,0,0);
var force = new CANNON.Vec3(f,0,0);
body.applyImpulse(worldPoint,force,dt);
var impulse = new CANNON.Vec3(f*dt,0,0);
body.applyImpulse(impulse,worldPoint);
});

// Add impulse to the top of the sphere
demo.addScene("top",function(){
demo.addScene("top impulse",function(){
var world = setupWorld(demo);
var shape = new CANNON.Sphere(radius);
var body = new CANNON.RigidBody(mass,shape);
Expand All @@ -52,8 +52,39 @@

// Add an impulse to the center
var worldPoint = new CANNON.Vec3(0,0,radius);
var impulse = new CANNON.Vec3(f*dt,0,0);
body.applyImpulse(impulse,worldPoint);
});


// Add force to the body center
demo.addScene("center force",function(){
var world = setupWorld(demo);
var shape = new CANNON.Sphere(radius);
var body = new CANNON.RigidBody(mass,shape);
body.linearDamping = body.angularDamping = damping;
world.add(body);
demo.addVisual(body);

// Add an force to the center
var worldPoint = new CANNON.Vec3(0,0,0);
var force = new CANNON.Vec3(f,0,0);
body.applyForce(force,worldPoint);
});

// Add force to the top of the sphere
demo.addScene("top force",function(){
var world = setupWorld(demo);
var shape = new CANNON.Sphere(radius);
var body = new CANNON.RigidBody(mass,shape);
body.linearDamping = body.angularDamping = damping;
world.add(body);
demo.addVisual(body);

// Add an force to the center
var worldPoint = new CANNON.Vec3(0,0,radius);
var force = new CANNON.Vec3(f,0,0);
body.applyImpulse(worldPoint,force,dt);
body.applyForce(force,worldPoint);
});

function setupWorld(demo){
Expand Down
58 changes: 52 additions & 6 deletions src/objects/RigidBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,57 @@ CANNON.RigidBody.prototype.computeAABB = function(){
this.aabbNeedsUpdate = false;
};

CANNON.RigidBody.prototype.applyImpulse = function(worldPoint,force,dt){
dt = dt || 1/60;
var r=new CANNON.Vec3(), rotForce=new CANNON.Vec3();
/**
* Apply force to a world point. This could for example be a point on the RigidBody surface. Applying force this way will add to Body.force and Body.tau.
* @param CANNON.Vec3 force The amount of force to add.
* @param CANNON.Vec3 worldPoint A world point to apply the force on.
*/
var RigidBody_applyForce_r = new CANNON.Vec3();
var RigidBody_applyForce_rotForce = new CANNON.Vec3();
CANNON.RigidBody.prototype.applyForce = function(force,worldPoint){
// Compute point position relative to the body center
var r = RigidBody_applyForce_r;
worldPoint.vsub(this.position,r);

// Compute produced rotational force
var rotForce = RigidBody_applyForce_rotForce;
r.cross(force,rotForce);
this.velocity.vadd(force.mult(dt),this.velocity);
this.angularVelocity.vadd(rotForce.mult(dt),this.angularVelocity);
};

// Add linear force
this.force.vadd(force,this.force);

// Add rotational force
this.tau.vadd(rotForce,this.tau);
};

/**
* Apply impulse to a world point. This could for example be a point on the RigidBody surface. An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity.
* @param CANNON.Vec3 impulse The amount of impulse to add.
* @param CANNON.Vec3 worldPoint A world point to apply the force on.
*/
var RigidBody_applyImpulse_r = new CANNON.Vec3();
var RigidBody_applyImpulse_velo = new CANNON.Vec3();
var RigidBody_applyImpulse_rotVelo = new CANNON.Vec3();
CANNON.RigidBody.prototype.applyImpulse = function(impulse,worldPoint){
// Compute point position relative to the body center
var r = RigidBody_applyImpulse_r;
worldPoint.vsub(this.position,r);

// Compute produced central impulse velocity
var velo = RigidBody_applyImpulse_velo;
impulse.copy(velo);
velo.mult(this.invMass,velo);

// Add linear impulse
this.velocity.vadd(velo, this.velocity);

// Compute produced rotational impulse velocity
var rotVelo = RigidBody_applyImpulse_rotVelo;
r.cross(impulse,rotVelo);
rotVelo.x *= this.invInertia.x;
rotVelo.y *= this.invInertia.y;
rotVelo.z *= this.invInertia.z;

// Add rotational Impulse
this.angularVelocity.vadd(rotVelo, this.angularVelocity);
};

0 comments on commit 49bccee

Please sign in to comment.