UNPKG

planck-js

Version:

2D physics engine for JavaScript/HTML5 game development

173 lines (145 loc) 4.84 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 = EdgeShape; var create = require('../util/create'); var options = require('../util/options'); var Settings = require('../Settings'); var Shape = require('../Shape'); var Math = require('../common/Math'); var Transform = require('../common/Transform'); var Rot = require('../common/Rot'); var Vec2 = require('../common/Vec2'); var AABB = require('../collision/AABB'); EdgeShape._super = Shape; EdgeShape.prototype = create(EdgeShape._super.prototype); EdgeShape.TYPE = 'edge'; /** * A line segment (edge) shape. These can be connected in chains or loops to * other edge shapes. The connectivity information is used to ensure correct * contact normals. */ function EdgeShape(v1, v2) { if (!(this instanceof EdgeShape)) { return new EdgeShape(v1, v2); } EdgeShape._super.call(this); this.m_type = EdgeShape.TYPE; this.m_radius = Settings.polygonRadius; // These are the edge vertices this.m_vertex1 = Vec2(v1); this.m_vertex2 = Vec2(v2); // Optional adjacent vertices. These are used for smooth collision. // Used by chain shape. this.m_vertex0 = Vec2(); this.m_vertex3 = Vec2(); this.m_hasVertex0 = false; this.m_hasVertex3 = false; } /** * Set this as an isolated edge. */ EdgeShape.prototype.Set = function(v1, v2) { this.m_vertex1.Set(v1); this.m_vertex2.Set(v2); this.m_hasVertex0 = false; this.m_hasVertex3 = false; return this; } EdgeShape.prototype.Clone = function() { var clone = new EdgeShape(); clone.m_type = this.m_type; clone.m_radius = this.m_radius; clone.m_vertex1.Set(this.m_vertex1); clone.m_vertex2.Set(this.m_vertex2); clone.m_vertex0.Set(this.m_vertex0); clone.m_vertex3.Set(this.m_vertex3); clone.m_hasVertex0 = this.m_hasVertex0; clone.m_hasVertex3 = this.m_hasVertex3; return clone; } EdgeShape.prototype.GetChildCount = function() { return 1; } EdgeShape.prototype.TestPoint = function(xf, p) { return false; } // p = p1 + t * d // v = v1 + s * e // p1 + t * d = v1 + s * e // s * e - t * d = p1 - v1 EdgeShape.prototype.RayCast = function(output, input, xf, childIndex) { // NOT_USED(childIndex); // Put the ray into the edge's frame of reference. var p1 = Vec2.MulT(xf.q, Vec2.Sub(input.p1, xf.p)); var p2 = Vec2.MulT(xf.q, Vec2.Sub(input.p2, xf.p)); var d = Vec2.Sub(p2, p1); var v1 = this.m_vertex1; var v2 = this.m_vertex2; var e = Vec2.Sub(v2, v1); var normal = Vec2(e.y, -e.x); normal.Normalize(); // q = p1 + t * d // dot(normal, q - v1) = 0 // dot(normal, p1 - v1) + t * dot(normal, d) = 0 var numerator = Vec2.Dot(normal, Vec2.Sub(v1, p1)); var denominator = Vec2.Dot(normal, d); if (denominator == 0.0) { return false; } var t = numerator / denominator; if (t < 0.0 || input.maxFraction < t) { return false; } var q = Vec2.Add(p1, Vec2.Mul(t, d)); // q = v1 + s * r // s = dot(q - v1, r) / dot(r, r) var r = Vec2.Sub(v2, v1); var rr = Vec2.Dot(r, r); if (rr == 0.0) { return false; } var s = Vec2.Dot(Vec2.Sub(q - v1), r) / rr; if (s < 0.0 || 1.0 < s) { return false; } output.fraction = t; if (numerator > 0.0) { output.normal = -Vec2.Mul(xf.q, normal); } else { output.normal = Vec2.Mul(xf.q, normal); } return true; } EdgeShape.prototype.ComputeAABB = function(aabb, xf, childIndex) { var v1 = Transform.Mul(xf, this.m_vertex1); var v2 = Transform.Mul(xf, this.m_vertex2); aabb.CombinePoints(v1, v2); aabb.Extend(this.m_radius) } EdgeShape.prototype.ComputeMass = function(massData, density) { massData.mass = 0.0; massData.center.WSet(0.5, this.m_vertex1, 0.5, this.m_vertex2); massData.I = 0.0; } EdgeShape.prototype.ComputeDistanceProxy = function(proxy) { proxy.m_vertices.push(this.m_vertex1); proxy.m_vertices.push(this.m_vertex2); proxy.m_count = 2; proxy.m_radius = this.m_radius; };