@box2d/debug-draw
Version:
Debug drawing helper for @box2d
192 lines (191 loc) • 7.46 kB
JavaScript
"use strict";
// MIT License
Object.defineProperty(exports, "__esModule", { value: true });
exports.b2EdgeShape = 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 line segment (edge) shape. These can be connected in chains or loops
* to other edge shapes. Edges created independently are two-sided and do
* no provide smooth movement across junctions.
*/
class b2EdgeShape extends b2_shape_1.b2Shape {
constructor() {
super(b2_shape_1.b2ShapeType.e_edge, b2_common_1.b2_polygonRadius);
/** These are the edge vertices */
this.m_vertex1 = new b2_math_1.b2Vec2();
this.m_vertex2 = new b2_math_1.b2Vec2();
/** Optional adjacent vertices. These are used for smooth collision. */
this.m_vertex0 = new b2_math_1.b2Vec2();
this.m_vertex3 = new b2_math_1.b2Vec2();
/** Uses m_vertex0 and m_vertex3 to create smooth collision. */
this.m_oneSided = false;
}
/**
* Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3
* follows. These extra vertices are used to provide smooth movement
* across junctions. This also makes the collision one-sided. The edge
* normal points to the right looking from v1 to v2.
*/
SetOneSided(v0, v1, v2, v3) {
this.m_vertex0.Copy(v0);
this.m_vertex1.Copy(v1);
this.m_vertex2.Copy(v2);
this.m_vertex3.Copy(v3);
this.m_oneSided = true;
return this;
}
/**
* Set this as an isolated edge. Collision is two-sided.
*/
SetTwoSided(v1, v2) {
this.m_vertex1.Copy(v1);
this.m_vertex2.Copy(v2);
this.m_oneSided = false;
return this;
}
/**
* Implement b2Shape.
*/
Clone() {
return new b2EdgeShape().Copy(this);
}
Copy(other) {
super.Copy(other);
// DEBUG: b2Assert(other instanceof b2EdgeShape);
this.m_vertex1.Copy(other.m_vertex1);
this.m_vertex2.Copy(other.m_vertex2);
this.m_vertex0.Copy(other.m_vertex0);
this.m_vertex3.Copy(other.m_vertex3);
this.m_oneSided = other.m_oneSided;
return this;
}
/**
* @see b2Shape::GetChildCount
*/
GetChildCount() {
return 1;
}
/**
* @see b2Shape::TestPoint
*/
TestPoint(_xf, _p) {
return false;
}
/**
* Implement b2Shape.
*
* p = p1 + t * d
* v = v1 + s * e
* p1 + t * d = v1 + s * e
* s * e - t * d = p1 - v1
*/
RayCast(output, input, xf, _childIndex) {
// Put the ray into the edge's frame of reference.
const p1 = b2_math_1.b2Transform.TransposeMultiplyVec2(xf, input.p1, b2EdgeShape.RayCast_s_p1);
const p2 = b2_math_1.b2Transform.TransposeMultiplyVec2(xf, input.p2, b2EdgeShape.RayCast_s_p2);
const d = b2_math_1.b2Vec2.Subtract(p2, p1, b2EdgeShape.RayCast_s_d);
const v1 = this.m_vertex1;
const v2 = this.m_vertex2;
const e = b2_math_1.b2Vec2.Subtract(v2, v1, b2EdgeShape.RayCast_s_e);
// Normal points to the right, looking from v1 at v2
const { normal } = output;
normal.Set(e.y, -e.x).Normalize();
// q = p1 + t * d
// dot(normal, q - v1) = 0
// dot(normal, p1 - v1) + t * dot(normal, d) = 0
const numerator = b2_math_1.b2Vec2.Dot(normal, b2_math_1.b2Vec2.Subtract(v1, p1, b2_math_1.b2Vec2.s_t0));
if (this.m_oneSided && numerator > 0) {
return false;
}
const denominator = b2_math_1.b2Vec2.Dot(normal, d);
if (denominator === 0) {
return false;
}
const t = numerator / denominator;
if (t < 0 || input.maxFraction < t) {
return false;
}
const q = b2_math_1.b2Vec2.AddScaled(p1, t, d, b2EdgeShape.RayCast_s_q);
// q = v1 + s * r
// s = dot(q - v1, r) / dot(r, r)
const r = b2_math_1.b2Vec2.Subtract(v2, v1, b2EdgeShape.RayCast_s_r);
const rr = b2_math_1.b2Vec2.Dot(r, r);
if (rr === 0) {
return false;
}
const s = b2_math_1.b2Vec2.Dot(b2_math_1.b2Vec2.Subtract(q, v1, b2_math_1.b2Vec2.s_t0), r) / rr;
if (s < 0 || s > 1) {
return false;
}
output.fraction = t;
b2_math_1.b2Rot.MultiplyVec2(xf.q, output.normal, output.normal);
if (numerator > 0) {
output.normal.Negate();
}
return true;
}
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb, xf, _childIndex) {
const v1 = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertex1, b2EdgeShape.ComputeAABB_s_v1);
const v2 = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertex2, b2EdgeShape.ComputeAABB_s_v2);
b2_math_1.b2Vec2.Min(v1, v2, aabb.lowerBound);
b2_math_1.b2Vec2.Max(v1, v2, aabb.upperBound);
const r = this.m_radius;
aabb.lowerBound.SubtractXY(r, r);
aabb.upperBound.AddXY(r, r);
}
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData, _density) {
massData.mass = 0;
b2_math_1.b2Vec2.Mid(this.m_vertex1, this.m_vertex2, massData.center);
massData.I = 0;
}
SetupDistanceProxy(proxy, _index) {
proxy.m_vertices = proxy.m_buffer;
proxy.m_vertices[0] = this.m_vertex1;
proxy.m_vertices[1] = this.m_vertex2;
proxy.m_count = 2;
proxy.m_radius = this.m_radius;
}
Draw(draw, color) {
const v1 = this.m_vertex1;
const v2 = this.m_vertex2;
draw.DrawSegment(v1, v2, color);
if (this.m_oneSided === false) {
draw.DrawPoint(v1, 4, color);
draw.DrawPoint(v2, 4, color);
}
}
}
exports.b2EdgeShape = b2EdgeShape;
b2EdgeShape.RayCast_s_p1 = new b2_math_1.b2Vec2();
b2EdgeShape.RayCast_s_p2 = new b2_math_1.b2Vec2();
b2EdgeShape.RayCast_s_d = new b2_math_1.b2Vec2();
b2EdgeShape.RayCast_s_e = new b2_math_1.b2Vec2();
b2EdgeShape.RayCast_s_q = new b2_math_1.b2Vec2();
b2EdgeShape.RayCast_s_r = new b2_math_1.b2Vec2();
b2EdgeShape.ComputeAABB_s_v1 = new b2_math_1.b2Vec2();
b2EdgeShape.ComputeAABB_s_v2 = new b2_math_1.b2Vec2();