UNPKG

planck-js

Version:

2D physics engine for JavaScript/HTML5 game development

128 lines (113 loc) 3.77 kB
/* * Copyright (c) 2016 Ali Shakiba http://shakiba.me/planck.js * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ module.exports = Sweep; var Math = require('./Math'); var Vec2 = require('./Vec2'); var Rot = require('./Rot'); var Transform = require('./Transform'); /** * This describes the motion of a body/shape for TOI computation. Shapes are * defined with respect to the body origin, which may not coincide with the * center of mass. However, to support dynamics we must interpolate the center * of mass position. * * @prop {Vec2} localCenter Local center of mass position * @prop {Vec2} c World center position * @prop {float} a World angle * @prop {float} alpha0 Fraction of the current time step in the range [0,1], c0 * and a0 are c and a at alpha0. */ function Sweep(c, a) { Assert(typeof c === 'undefined'); Assert(typeof a === 'undefined'); this.localCenter = new Vec2(); this.c = Vec2(); this.a = 0; this.alpha0 = 0; this.c0 = Vec2(); this.a0 = 0; } Sweep.prototype.SetTransform = function(xf) { var c = Transform.Mul(xf, this.localCenter); this.c.Set(c); this.c0.Set(c); this.a = xf.q.GetAngle(); this.a0 = xf.q.GetAngle(); }; Sweep.prototype.SetLocalCenter = function(localCenter, xf) { this.localCenter.Set(localCenter); var c = Transform.Mul(xf, this.localCenter); this.c.Set(c); this.c0.Set(c); }; /** * Get the interpolated transform at a specific time. * * @param xf * @param beta A factor in [0,1], where 0 indicates alpha0 */ Sweep.prototype.GetTransform = function(xf, beta) { beta = typeof beta === 'undefined' ? 0 : beta; xf.q.Set((1.0 - beta) * this.a0 + beta * this.a); xf.p.WSet((1.0 - beta), this.c0, beta, this.c); // shift to origin xf.p.Sub(Rot.Mul(xf.q, this.localCenter)); }; /** * Advance the sweep forward, yielding a new initial state. * * @param {float} alpha The new initial time */ Sweep.prototype.Advance = function(alpha) { Assert(this.alpha0 < 1.0); var beta = (alpha - this.alpha0) / (1.0 - this.alpha0); this.c0.WSet(beta, this.c, 1 - beta, this.c0); this.a0 = beta * this.a + (1 - beta) * this.a0; this.alpha0 = alpha; }; Sweep.prototype.Forward = function() { this.a0.Set(this.a); this.c0.Set(this.c); }; /** * Normalize the angles in radians to be between -pi and pi. */ Sweep.prototype.Normalize = function() { var a0 = Math.mod(this.a0, -Math.PI, +Math.PI); this.a -= this.a0 - a0; this.a0 = a0; }; Sweep.prototype.Clone = function() { var clone = new Sweep(); clone.localCenter.Set(this.localCenter); clone.alpha0 = this.alpha0; clone.a0 = this.a0; clone.a = this.a; clone.c0.Set(this.c0); clone.c.Set(this.c); return clone; }; Sweep.prototype.Set = function(that) { this.localCenter.Set(that.localCenter); this.alpha0 = that.alpha0; this.a0 = that.a0; this.a = that.a; this.c0.Set(that.c0); this.c.Set(that.c); };