Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions bodies/Ellipse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Owner: david@famo.us
* @license MPL 2.0
* @copyright Famous Industries, Inc. 2014
*/

define(function(require, exports, module) {
var Body = require('./Body');
var Matrix = require('famous/math/Matrix');

/**
* Implements a circle, or spherical, geometry for an Body with
* radius.
*
* @class Circle
* @extends Body
* @constructor
*/
function Circle(options) {
options = options || {};
this.setRadius(options.radius || 0);
Body.call(this, options);
}

Circle.prototype = Object.create(Body.prototype);
Circle.prototype.constructor = Circle;

/**
* Basic setter for radius.
* @method setRadius
* @param r {Number} radius
*/
Circle.prototype.setRadius = function setRadius(r) {
this.radius = r;
this.size = [2*this.radius, 2*this.radius];
this.setMomentsOfInertia();
};

Circle.prototype.setMomentsOfInertia = function setMomentsOfInertia() {
var m = this.mass;
var r = this.radius;

this.inertia = new Matrix([
[0.25 * m * r * r, 0, 0],
[0, 0.25 * m * r * r, 0],
[0, 0, 0.5 * m * r * r]
]);

this.inverseInertia = new Matrix([
[4 / (m * r * r), 0, 0],
[0, 4 / (m * r * r), 0],
[0, 0, 2 / (m * r * r)]
]);
};

module.exports = Circle;

});
44 changes: 44 additions & 0 deletions bodies/Square.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Owner: david@famo.us
* @license MPL 2.0
* @copyright Famous Industries, Inc. 2014
*/

define(function(require, exports, module) {
var Body = require('./Rectangle');
var Matrix = require('famous/math/Matrix');

/**
* Implements a square geometry for an Body with
* size = length.
*
* @class Square
* @extends Rectangle
* @constructor
*/
function Square(options) {
options = options || {};
this.size = options.size || [0,0];
Rectangle.call(this, options);
}

Square.prototype = Object.create(Rectangle.prototype);
Square.prototype.constructor = Square;

/**
* Basic setter for size.
* @method setSize
* @param length
*/
Square.prototype.setSize = function setSize(length) {
var size = [length, length];
this.size = size;
this.setMomentsOfInertia();
};

module.exports = Square;

});
77 changes: 70 additions & 7 deletions constraints/Collision.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ define(function(require, exports, module) {
this.vDiff = new Vector();
this.impulse1 = new Vector();
this.impulse2 = new Vector();
this.torque1 = new Vector();
this.torque2 = new Vector();

Constraint.call(this);
}
Expand Down Expand Up @@ -74,7 +76,15 @@ define(function(require, exports, module) {
var v1 = source.velocity;
var p1 = source.position;
var w1 = source.inverseMass;
var r1 = source.radius;

if (source instanceof Circle) {
var r1 = source.radius;
}
else if (source instanceof Ellipse) {
}
else if (source instanceof Rectangle) {
var o1 = source.orientation;
}

var options = this.options;
var drift = options.drift;
Expand All @@ -86,6 +96,8 @@ define(function(require, exports, module) {
var vDiff = this.vDiff;
var impulse1 = this.impulse1;
var impulse2 = this.impulse2;
var torque1 = this.torque1;
var torque2 = this.torque2;

for (var i = 0; i < targets.length; i++) {
var target = targets[i];
Expand All @@ -95,19 +107,48 @@ define(function(require, exports, module) {
var v2 = target.velocity;
var p2 = target.position;
var w2 = target.inverseMass;
var r2 = target.radius;

if (target instanceof Rectangle) {
var o2 = target.orientation;
}

pDiff.set(p2.sub(p1));
vDiff.set(v2.sub(v1));

var dist = pDiff.norm();
var overlap = dist - (r1 + r2);
var effMass = 1/(w1 + w2);
var gamma = 0;

if (target instanceof Circle) {
var r1 = target.radius;
}
else if (target instanceof Ellispe) {
}
else if (target instanceof Square) {
var theta = Math.atan(pDiff.y/pDiff.x);
if (source instanceof Square) {
var r1 = source.size[0]/2 * Math.cos(theta);
}
var r2 = target.size[0]/2 * Math.cos(theta);
}
else if (target instanceof Rectangle) {
}

var overlap = dist - (r1 + r2);

if (overlap < 0) {

n.set(pDiff.normalize());
if ((source instanceof Circle) && (target instanceof Circle)) {
n.set(pDiff.normalize());
}
if ((source instanceof Square) && (target instanceof Square)) {
if ((theta < Math.PI/4) && theta > -1*Math.PI/4) {
n.set(1);
}
if ((theta > Math.PI/4) && theta < -1*Math.PI/4) {
n.set([0,1,0]);
}
}

if (this._eventOutput) {
var collisionData = {
Expand All @@ -121,16 +162,38 @@ define(function(require, exports, module) {
this._eventOutput.emit('collision', collisionData);
}

var lambda = (overlap <= slop)
? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
: ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass);
//if ((source instanceof Circle) && (target instanceof Circle)) {
var lambda = (overlap <= slop)
? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
: ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass);
//}
//if ((source instanceof Square) && (target instanceof Square)) {
// var vtheta = Math.atan(vDiff.y/vDiff.x);
// var lambda = (overlap <= slop)
// ? ((1 + restitution) * n.dot(vDiff) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
// : ((1 + restitution) * n.dot(vDiff)) / (gamma + dt/effMass);
//}

n.mult(dt*lambda).put(impulse1);
impulse1.mult(-1).put(impulse2);

source.applyImpulse(impulse1);
target.applyImpulse(impulse2);

// Calculate the torque for off center collisions of Rectangular bodies.
// Normal orientation and same size of source and target.
else if (target instanceof Rectangle) {
var fdist = pDiff.y.mult(0.5);
var torque1 = (overlap <= slop)
? (vDiff.cross(fdist).mult(1 + restitution) + drift/dt * (overlap - slop)) / (gamma + dt/effMass)
: vDiff.cross(fdist).mult((1 + restitution)/(gamma + dt/effMass));
//vDiff.cross(fdist).put(torque1);
torque1.mult(-1).put(torque2);
source.applyTorque(torque1);
target.applyTorque(torque2);
}


//source.setPosition(p1.add(n.mult(overlap/2)));
//target.setPosition(p2.sub(n.mult(overlap/2)));

Expand Down
2 changes: 1 addition & 1 deletion forces/Repulsion.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ define(function(require, exports, module) {

/**
* An inverse squared distance decay function
* @attribute INVERSE
* @attribute GRAVITY
* @type Function
* @param {Number} r distance from the source body
* @param {Number} cutoff a distance shift to avoid singularities
Expand Down