UNPKG

@box2d/debug-draw

Version:

Debug drawing helper for @box2d

136 lines (135 loc) 5.48 kB
"use strict"; // MIT License Object.defineProperty(exports, "__esModule", { value: true }); exports.b2CircleShape = void 0; // Copyright (c) 2019 Erin Catto // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // DEBUG: import { b2Assert } from "../common/b2_common"; const b2_common_1 = require("../common/b2_common"); const b2_math_1 = require("../common/b2_math"); const b2_shape_1 = require("./b2_shape"); /** * A solid circle shape */ class b2CircleShape extends b2_shape_1.b2Shape { constructor(radius = 0) { super(b2_shape_1.b2ShapeType.e_circle, radius); /** Position */ this.m_p = new b2_math_1.b2Vec2(); } Set(position, radius = this.m_radius) { this.m_p.Copy(position); this.m_radius = radius; return this; } /** * Implement b2Shape. */ Clone() { return new b2CircleShape().Copy(this); } Copy(other) { super.Copy(other); // DEBUG: b2Assert(other instanceof b2CircleShape); this.m_p.Copy(other.m_p); return this; } /** * @see b2Shape::GetChildCount */ GetChildCount() { return 1; } /** * Implement b2Shape. */ TestPoint(transform, p) { const center = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.TestPoint_s_center); const d = b2_math_1.b2Vec2.Subtract(p, center, b2CircleShape.TestPoint_s_d); return b2_math_1.b2Vec2.Dot(d, d) <= this.m_radius ** 2; } /** * Implement b2Shape. * * @note because the circle is solid, rays that start inside do not hit because the normal is * not defined. Collision Detection in Interactive 3D Environments by Gino van den Bergen * From Section 3.1.2 * x = s + a * r * norm(x) = radius */ RayCast(output, input, transform, _childIndex) { const position = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.RayCast_s_position); const s = b2_math_1.b2Vec2.Subtract(input.p1, position, b2CircleShape.RayCast_s_s); const b = b2_math_1.b2Vec2.Dot(s, s) - this.m_radius ** 2; // Solve quadratic equation. const r = b2_math_1.b2Vec2.Subtract(input.p2, input.p1, b2CircleShape.RayCast_s_r); const c = b2_math_1.b2Vec2.Dot(s, r); const rr = b2_math_1.b2Vec2.Dot(r, r); const sigma = c * c - rr * b; // Check for negative discriminant and short segment. if (sigma < 0 || rr < b2_common_1.b2_epsilon) { return false; } // Find the point of intersection of the line with the circle. let a = -(c + Math.sqrt(sigma)); // Is the intersection point on the segment? if (a >= 0 && a <= input.maxFraction * rr) { a /= rr; output.fraction = a; b2_math_1.b2Vec2.AddScaled(s, a, r, output.normal).Normalize(); return true; } return false; } /** * @see b2Shape::ComputeAABB */ ComputeAABB(aabb, transform, _childIndex) { const p = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.ComputeAABB_s_p); aabb.lowerBound.Set(p.x - this.m_radius, p.y - this.m_radius); aabb.upperBound.Set(p.x + this.m_radius, p.y + this.m_radius); } /** * @see b2Shape::ComputeMass */ ComputeMass(massData, density) { const radius_sq = this.m_radius ** 2; massData.mass = density * Math.PI * radius_sq; massData.center.Copy(this.m_p); // inertia about the local origin massData.I = massData.mass * (0.5 * radius_sq + b2_math_1.b2Vec2.Dot(this.m_p, this.m_p)); } SetupDistanceProxy(proxy, _index) { proxy.m_vertices = proxy.m_buffer; proxy.m_vertices[0] = this.m_p; proxy.m_count = 1; proxy.m_radius = this.m_radius; } Draw(draw, color) { const center = this.m_p; const radius = this.m_radius; const axis = b2_math_1.b2Vec2.UNITX; draw.DrawSolidCircle(center, radius, axis, color); } } exports.b2CircleShape = b2CircleShape; b2CircleShape.TestPoint_s_center = new b2_math_1.b2Vec2(); b2CircleShape.TestPoint_s_d = new b2_math_1.b2Vec2(); b2CircleShape.RayCast_s_position = new b2_math_1.b2Vec2(); b2CircleShape.RayCast_s_s = new b2_math_1.b2Vec2(); b2CircleShape.RayCast_s_r = new b2_math_1.b2Vec2(); b2CircleShape.ComputeAABB_s_p = new b2_math_1.b2Vec2();