planck-v2 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of planck-v2 might be problematic. Click here for more details.
- package/LICENSE.txt +20 -0
- package/README.md +21 -0
- package/dist/planck-with-testbed.d.ts +4433 -0
- package/dist/planck-with-testbed.js +20730 -0
- package/dist/planck-with-testbed.js.map +1 -0
- package/dist/planck-with-testbed.umd.cjs +20730 -0
- package/dist/planck-with-testbed.umd.cjs.map +1 -0
- package/dist/planck.d.ts +4343 -0
- package/dist/planck.js +13516 -0
- package/dist/planck.js.map +1 -0
- package/dist/planck.umd.cjs +13516 -0
- package/dist/planck.umd.cjs.map +1 -0
- package/package.json +105 -0
- package/src/Settings.ts +238 -0
- package/src/__test__/Basic.test.ts +43 -0
- package/src/__test__/CCD.test.ts +70 -0
- package/src/__test__/Collision.test.ts +133 -0
- package/src/__test__/Math.test.ts +105 -0
- package/src/__test__/Pool.test.ts +48 -0
- package/src/__test__/World.test.ts +73 -0
- package/src/collision/AABB.ts +287 -0
- package/src/collision/BroadPhase.ts +210 -0
- package/src/collision/Distance.ts +962 -0
- package/src/collision/DynamicTree.ts +907 -0
- package/src/collision/Manifold.ts +420 -0
- package/src/collision/Raycast.ts +30 -0
- package/src/collision/Shape.ts +114 -0
- package/src/collision/TimeOfImpact.ts +502 -0
- package/src/collision/shape/BoxShape.ts +34 -0
- package/src/collision/shape/ChainShape.ts +360 -0
- package/src/collision/shape/CircleShape.ts +202 -0
- package/src/collision/shape/CollideCircle.ts +66 -0
- package/src/collision/shape/CollideCirclePolygon.ts +142 -0
- package/src/collision/shape/CollideEdgeCircle.ts +185 -0
- package/src/collision/shape/CollideEdgePolygon.ts +528 -0
- package/src/collision/shape/CollidePolygon.ts +280 -0
- package/src/collision/shape/EdgeShape.ts +316 -0
- package/src/collision/shape/PolygonShape.ts +581 -0
- package/src/common/Geo.ts +589 -0
- package/src/common/Jacobian.ts +17 -0
- package/src/common/Mat22.ts +221 -0
- package/src/common/Mat33.ts +224 -0
- package/src/common/Math.ts +96 -0
- package/src/common/Rot.ts +218 -0
- package/src/common/Sweep.ts +119 -0
- package/src/common/Transform.ts +203 -0
- package/src/common/Vec2.ts +624 -0
- package/src/common/Vec3.ts +188 -0
- package/src/dynamics/Body.ts +1198 -0
- package/src/dynamics/Contact.ts +1366 -0
- package/src/dynamics/Fixture.ts +506 -0
- package/src/dynamics/Joint.ts +226 -0
- package/src/dynamics/Position.ts +44 -0
- package/src/dynamics/Solver.ts +890 -0
- package/src/dynamics/Velocity.ts +18 -0
- package/src/dynamics/World.ts +1169 -0
- package/src/dynamics/joint/DistanceJoint.ts +463 -0
- package/src/dynamics/joint/FrictionJoint.ts +396 -0
- package/src/dynamics/joint/GearJoint.ts +591 -0
- package/src/dynamics/joint/MotorJoint.ts +430 -0
- package/src/dynamics/joint/MouseJoint.ts +390 -0
- package/src/dynamics/joint/PrismaticJoint.ts +903 -0
- package/src/dynamics/joint/PulleyJoint.ts +529 -0
- package/src/dynamics/joint/RevoluteJoint.ts +745 -0
- package/src/dynamics/joint/RopeJoint.ts +383 -0
- package/src/dynamics/joint/WeldJoint.ts +544 -0
- package/src/dynamics/joint/WheelJoint.ts +683 -0
- package/src/dynamics/joint/__test__/DistanceJoint.test.ts +66 -0
- package/src/index.ts +60 -0
- package/src/internal.ts +20 -0
- package/src/main.ts +3 -0
- package/src/serializer/__test__/Serialize.test.ts +52 -0
- package/src/serializer/__test__/Validator.test.ts +55 -0
- package/src/serializer/index.ts +257 -0
- package/src/serializer/schema.json +168 -0
- package/src/util/Pool.ts +120 -0
- package/src/util/Testbed.ts +157 -0
- package/src/util/Timer.ts +15 -0
- package/src/util/options.ts +28 -0
- package/src/util/stats.ts +26 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Planck.js
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Erin Catto, Ali Shakiba
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Vec2, Vec2Value } from "./Vec2";
|
|
11
|
+
|
|
12
|
+
/** @internal */ const _ASSERT = typeof ASSERT === "undefined" ? false : ASSERT;
|
|
13
|
+
|
|
14
|
+
/** A 2-by-2 matrix. Stored in column-major order. */
|
|
15
|
+
export interface Mat22Value {
|
|
16
|
+
ex: Vec2Value;
|
|
17
|
+
ey: Vec2Value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A 2-by-2 matrix. Stored in column-major order.
|
|
22
|
+
*
|
|
23
|
+
* @deprecated Use Mat22Value and geo functions instead.
|
|
24
|
+
*/
|
|
25
|
+
export class Mat22 {
|
|
26
|
+
ex: Vec2;
|
|
27
|
+
ey: Vec2;
|
|
28
|
+
|
|
29
|
+
constructor(a: number, b: number, c: number, d: number);
|
|
30
|
+
constructor(a: { x: number; y: number }, b: { x: number; y: number });
|
|
31
|
+
constructor();
|
|
32
|
+
constructor(a?, b?, c?, d?) {
|
|
33
|
+
if (typeof a === "object" && a !== null) {
|
|
34
|
+
this.ex = Vec2.clone(a);
|
|
35
|
+
this.ey = Vec2.clone(b);
|
|
36
|
+
} else if (typeof a === "number") {
|
|
37
|
+
this.ex = Vec2.neo(a, c);
|
|
38
|
+
this.ey = Vec2.neo(b, d);
|
|
39
|
+
} else {
|
|
40
|
+
this.ex = Vec2.zero();
|
|
41
|
+
this.ey = Vec2.zero();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** @hidden */
|
|
46
|
+
toString(): string {
|
|
47
|
+
return JSON.stringify(this);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static isValid(obj: any): boolean {
|
|
51
|
+
if (obj === null || typeof obj === "undefined") {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return Vec2.isValid(obj.ex) && Vec2.isValid(obj.ey);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static assert(o: any): void {
|
|
58
|
+
if (_ASSERT) console.assert(!Mat22.isValid(o), "Invalid Mat22!", o);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
set(a: Mat22): void;
|
|
62
|
+
set(a: Vec2Value, b: Vec2Value): void;
|
|
63
|
+
set(a: number, b: number, c: number, d: number): void;
|
|
64
|
+
set(a, b?, c?, d?): void {
|
|
65
|
+
if (typeof a === "number" && typeof b === "number" && typeof c === "number" && typeof d === "number") {
|
|
66
|
+
this.ex.setNum(a, c);
|
|
67
|
+
this.ey.setNum(b, d);
|
|
68
|
+
} else if (typeof a === "object" && typeof b === "object") {
|
|
69
|
+
this.ex.setVec2(a);
|
|
70
|
+
this.ey.setVec2(b);
|
|
71
|
+
} else if (typeof a === "object") {
|
|
72
|
+
if (_ASSERT) Mat22.assert(a);
|
|
73
|
+
this.ex.setVec2(a.ex);
|
|
74
|
+
this.ey.setVec2(a.ey);
|
|
75
|
+
} else {
|
|
76
|
+
if (_ASSERT) console.assert(false);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setIdentity(): void {
|
|
81
|
+
this.ex.x = 1.0;
|
|
82
|
+
this.ey.x = 0.0;
|
|
83
|
+
this.ex.y = 0.0;
|
|
84
|
+
this.ey.y = 1.0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
setZero(): void {
|
|
88
|
+
this.ex.x = 0.0;
|
|
89
|
+
this.ey.x = 0.0;
|
|
90
|
+
this.ex.y = 0.0;
|
|
91
|
+
this.ey.y = 0.0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
getInverse(): Mat22 {
|
|
95
|
+
const a = this.ex.x;
|
|
96
|
+
const b = this.ey.x;
|
|
97
|
+
const c = this.ex.y;
|
|
98
|
+
const d = this.ey.y;
|
|
99
|
+
let det = a * d - b * c;
|
|
100
|
+
if (det !== 0.0) {
|
|
101
|
+
det = 1.0 / det;
|
|
102
|
+
}
|
|
103
|
+
const imx = new Mat22();
|
|
104
|
+
imx.ex.x = det * d;
|
|
105
|
+
imx.ey.x = -det * b;
|
|
106
|
+
imx.ex.y = -det * c;
|
|
107
|
+
imx.ey.y = det * a;
|
|
108
|
+
return imx;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Solve A * x = b, where b is a column vector. This is more efficient than
|
|
113
|
+
* computing the inverse in one-shot cases.
|
|
114
|
+
*/
|
|
115
|
+
solve(v: Vec2Value): Vec2 {
|
|
116
|
+
if (_ASSERT) Vec2.assert(v);
|
|
117
|
+
const a = this.ex.x;
|
|
118
|
+
const b = this.ey.x;
|
|
119
|
+
const c = this.ex.y;
|
|
120
|
+
const d = this.ey.y;
|
|
121
|
+
let det = a * d - b * c;
|
|
122
|
+
if (det !== 0.0) {
|
|
123
|
+
det = 1.0 / det;
|
|
124
|
+
}
|
|
125
|
+
const w = Vec2.zero();
|
|
126
|
+
w.x = det * (d * v.x - b * v.y);
|
|
127
|
+
w.y = det * (a * v.y - c * v.x);
|
|
128
|
+
return w;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Multiply a matrix times a vector. If a rotation matrix is provided, then this
|
|
133
|
+
* transforms the vector from one frame to another.
|
|
134
|
+
*/
|
|
135
|
+
static mul(mx: Mat22, my: Mat22): Mat22;
|
|
136
|
+
static mul(mx: Mat22, v: Vec2Value): Vec2;
|
|
137
|
+
static mul(mx, v) {
|
|
138
|
+
if (v && "x" in v && "y" in v) {
|
|
139
|
+
if (_ASSERT) Vec2.assert(v);
|
|
140
|
+
const x = mx.ex.x * v.x + mx.ey.x * v.y;
|
|
141
|
+
const y = mx.ex.y * v.x + mx.ey.y * v.y;
|
|
142
|
+
return Vec2.neo(x, y);
|
|
143
|
+
} else if (v && "ex" in v && "ey" in v) {
|
|
144
|
+
// Mat22
|
|
145
|
+
if (_ASSERT) Mat22.assert(v);
|
|
146
|
+
// return new Mat22(Vec2.mul(mx, v.ex), Vec2.mul(mx, v.ey));
|
|
147
|
+
const a = mx.ex.x * v.ex.x + mx.ey.x * v.ex.y;
|
|
148
|
+
const b = mx.ex.x * v.ey.x + mx.ey.x * v.ey.y;
|
|
149
|
+
const c = mx.ex.y * v.ex.x + mx.ey.y * v.ex.y;
|
|
150
|
+
const d = mx.ex.y * v.ey.x + mx.ey.y * v.ey.y;
|
|
151
|
+
return new Mat22(a, b, c, d);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (_ASSERT) console.assert(false);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static mulVec2(mx: Mat22, v: Vec2Value): Vec2 {
|
|
158
|
+
if (_ASSERT) Vec2.assert(v);
|
|
159
|
+
const x = mx.ex.x * v.x + mx.ey.x * v.y;
|
|
160
|
+
const y = mx.ex.y * v.x + mx.ey.y * v.y;
|
|
161
|
+
return Vec2.neo(x, y);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static mulMat22(mx: Mat22, v: Mat22): Mat22 {
|
|
165
|
+
if (_ASSERT) Mat22.assert(v);
|
|
166
|
+
// return new Mat22(Vec2.mul(mx, v.ex), Vec2.mul(mx, v.ey));
|
|
167
|
+
const a = mx.ex.x * v.ex.x + mx.ey.x * v.ex.y;
|
|
168
|
+
const b = mx.ex.x * v.ey.x + mx.ey.x * v.ey.y;
|
|
169
|
+
const c = mx.ex.y * v.ex.x + mx.ey.y * v.ex.y;
|
|
170
|
+
const d = mx.ex.y * v.ey.x + mx.ey.y * v.ey.y;
|
|
171
|
+
return new Mat22(a, b, c, d);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Multiply a matrix transpose times a vector. If a rotation matrix is provided,
|
|
176
|
+
* then this transforms the vector from one frame to another (inverse
|
|
177
|
+
* transform).
|
|
178
|
+
*/
|
|
179
|
+
static mulT(mx: Mat22, my: Mat22): Mat22;
|
|
180
|
+
static mulT(mx: Mat22, v: Vec2Value): Vec2;
|
|
181
|
+
static mulT(mx, v) {
|
|
182
|
+
if (v && "x" in v && "y" in v) {
|
|
183
|
+
// Vec2
|
|
184
|
+
if (_ASSERT) Vec2.assert(v);
|
|
185
|
+
return Vec2.neo(Vec2.dot(v, mx.ex), Vec2.dot(v, mx.ey));
|
|
186
|
+
} else if (v && "ex" in v && "ey" in v) {
|
|
187
|
+
// Mat22
|
|
188
|
+
if (_ASSERT) Mat22.assert(v);
|
|
189
|
+
const c1 = Vec2.neo(Vec2.dot(mx.ex, v.ex), Vec2.dot(mx.ey, v.ex));
|
|
190
|
+
const c2 = Vec2.neo(Vec2.dot(mx.ex, v.ey), Vec2.dot(mx.ey, v.ey));
|
|
191
|
+
return new Mat22(c1, c2);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (_ASSERT) console.assert(false);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static mulTVec2(mx: Mat22, v: Vec2Value): Vec2 {
|
|
198
|
+
if (_ASSERT) Mat22.assert(mx);
|
|
199
|
+
if (_ASSERT) Vec2.assert(v);
|
|
200
|
+
return Vec2.neo(Vec2.dot(v, mx.ex), Vec2.dot(v, mx.ey));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static mulTMat22(mx: Mat22, v: Mat22): Mat22 {
|
|
204
|
+
if (_ASSERT) Mat22.assert(mx);
|
|
205
|
+
if (_ASSERT) Mat22.assert(v);
|
|
206
|
+
const c1 = Vec2.neo(Vec2.dot(mx.ex, v.ex), Vec2.dot(mx.ey, v.ex));
|
|
207
|
+
const c2 = Vec2.neo(Vec2.dot(mx.ex, v.ey), Vec2.dot(mx.ey, v.ey));
|
|
208
|
+
return new Mat22(c1, c2);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static abs(mx: Mat22): Mat22 {
|
|
212
|
+
if (_ASSERT) Mat22.assert(mx);
|
|
213
|
+
return new Mat22(Vec2.abs(mx.ex), Vec2.abs(mx.ey));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static add(mx1: Mat22, mx2: Mat22): Mat22 {
|
|
217
|
+
if (_ASSERT) Mat22.assert(mx1);
|
|
218
|
+
if (_ASSERT) Mat22.assert(mx2);
|
|
219
|
+
return new Mat22(Vec2.add(mx1.ex, mx2.ex), Vec2.add(mx1.ey, mx2.ey));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Planck.js
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Erin Catto, Ali Shakiba
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Vec2, Vec2Value } from "./Vec2";
|
|
11
|
+
import { Vec3, Vec3Value } from "./Vec3";
|
|
12
|
+
|
|
13
|
+
/** @internal */ const _ASSERT = typeof ASSERT === "undefined" ? false : ASSERT;
|
|
14
|
+
|
|
15
|
+
/** A 3-by-3 matrix. Stored in column-major order. */
|
|
16
|
+
export interface Mat33Value {
|
|
17
|
+
ex: Vec3Value;
|
|
18
|
+
ey: Vec3Value;
|
|
19
|
+
ez: Vec3Value;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A 3-by-3 matrix. Stored in column-major order.
|
|
24
|
+
*
|
|
25
|
+
* @deprecated Use Mat33Value and geo functions instead.
|
|
26
|
+
*/
|
|
27
|
+
export class Mat33 {
|
|
28
|
+
ex: Vec3;
|
|
29
|
+
ey: Vec3;
|
|
30
|
+
ez: Vec3;
|
|
31
|
+
|
|
32
|
+
constructor(a: Vec3Value, b: Vec3Value, c: Vec3Value);
|
|
33
|
+
constructor();
|
|
34
|
+
constructor(a?: Vec3Value, b?: Vec3Value, c?: Vec3Value) {
|
|
35
|
+
if (typeof a === "object" && a !== null) {
|
|
36
|
+
this.ex = Vec3.clone(a);
|
|
37
|
+
this.ey = Vec3.clone(b);
|
|
38
|
+
this.ez = Vec3.clone(c);
|
|
39
|
+
} else {
|
|
40
|
+
this.ex = Vec3.zero();
|
|
41
|
+
this.ey = Vec3.zero();
|
|
42
|
+
this.ez = Vec3.zero();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @hidden */
|
|
47
|
+
toString(): string {
|
|
48
|
+
return JSON.stringify(this);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static isValid(obj: any): boolean {
|
|
52
|
+
if (obj === null || typeof obj === "undefined") {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return Vec3.isValid(obj.ex) && Vec3.isValid(obj.ey) && Vec3.isValid(obj.ez);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static assert(o: any): void {
|
|
59
|
+
if (_ASSERT) console.assert(!Mat33.isValid(o), "Invalid Mat33!", o);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set this matrix to all zeros.
|
|
64
|
+
*/
|
|
65
|
+
setZero(): Mat33 {
|
|
66
|
+
this.ex.setZero();
|
|
67
|
+
this.ey.setZero();
|
|
68
|
+
this.ez.setZero();
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Solve A * x = b, where b is a column vector. This is more efficient than
|
|
74
|
+
* computing the inverse in one-shot cases.
|
|
75
|
+
*/
|
|
76
|
+
solve33(v: Vec3Value): Vec3 {
|
|
77
|
+
// let det = matrix.dotVec3(this.ex, matrix.newCrossVec3(this.ey, this.ez));
|
|
78
|
+
let cross_x = this.ey.y * this.ez.z - this.ey.z * this.ez.y;
|
|
79
|
+
let cross_y = this.ey.z * this.ez.x - this.ey.x * this.ez.z;
|
|
80
|
+
let cross_z = this.ey.x * this.ez.y - this.ey.y * this.ez.x;
|
|
81
|
+
let det = this.ex.x * cross_x + this.ex.y * cross_y + this.ex.z * cross_z;
|
|
82
|
+
if (det !== 0.0) {
|
|
83
|
+
det = 1.0 / det;
|
|
84
|
+
}
|
|
85
|
+
const r = new Vec3();
|
|
86
|
+
// r.x = det * matrix.dotVec3(v, matrix.newCrossVec3(this.ey, this.ez));
|
|
87
|
+
cross_x = this.ey.y * this.ez.z - this.ey.z * this.ez.y;
|
|
88
|
+
cross_y = this.ey.z * this.ez.x - this.ey.x * this.ez.z;
|
|
89
|
+
cross_z = this.ey.x * this.ez.y - this.ey.y * this.ez.x;
|
|
90
|
+
r.x = det * (v.x * cross_x + v.y * cross_y + v.z * cross_z);
|
|
91
|
+
|
|
92
|
+
// r.y = det * matrix.dotVec3(this.ex, matrix.newCrossVec3(v, this.ez));
|
|
93
|
+
cross_x = v.y * this.ez.z - v.z * this.ez.y;
|
|
94
|
+
cross_y = v.z * this.ez.x - v.x * this.ez.z;
|
|
95
|
+
cross_z = v.x * this.ez.y - v.y * this.ez.x;
|
|
96
|
+
r.y = det * (this.ex.x * cross_x + this.ex.y * cross_y + this.ex.z * cross_z);
|
|
97
|
+
|
|
98
|
+
// r.z = det * matrix.dotVec3(this.ex, matrix.newCrossVec3(this.ey, v));
|
|
99
|
+
cross_x = this.ey.y * v.z - this.ey.z * v.y;
|
|
100
|
+
cross_y = this.ey.z * v.x - this.ey.x * v.z;
|
|
101
|
+
cross_z = this.ey.x * v.y - this.ey.y * v.x;
|
|
102
|
+
r.z = det * (this.ex.x * cross_x + this.ex.y * cross_y + this.ex.z * cross_z);
|
|
103
|
+
return r;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Solve A * x = b, where b is a column vector. This is more efficient than
|
|
108
|
+
* computing the inverse in one-shot cases. Solve only the upper 2-by-2 matrix
|
|
109
|
+
* equation.
|
|
110
|
+
*/
|
|
111
|
+
solve22(v: Vec2Value): Vec2 {
|
|
112
|
+
const a11 = this.ex.x;
|
|
113
|
+
const a12 = this.ey.x;
|
|
114
|
+
const a21 = this.ex.y;
|
|
115
|
+
const a22 = this.ey.y;
|
|
116
|
+
let det = a11 * a22 - a12 * a21;
|
|
117
|
+
if (det !== 0.0) {
|
|
118
|
+
det = 1.0 / det;
|
|
119
|
+
}
|
|
120
|
+
const r = Vec2.zero();
|
|
121
|
+
r.x = det * (a22 * v.x - a12 * v.y);
|
|
122
|
+
r.y = det * (a11 * v.y - a21 * v.x);
|
|
123
|
+
return r;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get the inverse of this matrix as a 2-by-2. Returns the zero matrix if
|
|
128
|
+
* singular.
|
|
129
|
+
*/
|
|
130
|
+
getInverse22(M: Mat33): void {
|
|
131
|
+
const a = this.ex.x;
|
|
132
|
+
const b = this.ey.x;
|
|
133
|
+
const c = this.ex.y;
|
|
134
|
+
const d = this.ey.y;
|
|
135
|
+
let det = a * d - b * c;
|
|
136
|
+
if (det !== 0.0) {
|
|
137
|
+
det = 1.0 / det;
|
|
138
|
+
}
|
|
139
|
+
M.ex.x = det * d;
|
|
140
|
+
M.ey.x = -det * b;
|
|
141
|
+
M.ex.z = 0.0;
|
|
142
|
+
M.ex.y = -det * c;
|
|
143
|
+
M.ey.y = det * a;
|
|
144
|
+
M.ey.z = 0.0;
|
|
145
|
+
M.ez.x = 0.0;
|
|
146
|
+
M.ez.y = 0.0;
|
|
147
|
+
M.ez.z = 0.0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get the symmetric inverse of this matrix as a 3-by-3. Returns the zero matrix
|
|
152
|
+
* if singular.
|
|
153
|
+
*/
|
|
154
|
+
getSymInverse33(M: Mat33): void {
|
|
155
|
+
let det = Vec3.dot(this.ex, Vec3.cross(this.ey, this.ez));
|
|
156
|
+
if (det !== 0.0) {
|
|
157
|
+
det = 1.0 / det;
|
|
158
|
+
}
|
|
159
|
+
const a11 = this.ex.x;
|
|
160
|
+
const a12 = this.ey.x;
|
|
161
|
+
const a13 = this.ez.x;
|
|
162
|
+
const a22 = this.ey.y;
|
|
163
|
+
const a23 = this.ez.y;
|
|
164
|
+
const a33 = this.ez.z;
|
|
165
|
+
|
|
166
|
+
M.ex.x = det * (a22 * a33 - a23 * a23);
|
|
167
|
+
M.ex.y = det * (a13 * a23 - a12 * a33);
|
|
168
|
+
M.ex.z = det * (a12 * a23 - a13 * a22);
|
|
169
|
+
|
|
170
|
+
M.ey.x = M.ex.y;
|
|
171
|
+
M.ey.y = det * (a11 * a33 - a13 * a13);
|
|
172
|
+
M.ey.z = det * (a13 * a12 - a11 * a23);
|
|
173
|
+
|
|
174
|
+
M.ez.x = M.ex.z;
|
|
175
|
+
M.ez.y = M.ey.z;
|
|
176
|
+
M.ez.z = det * (a11 * a22 - a12 * a12);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Multiply a matrix times a vector.
|
|
181
|
+
*/
|
|
182
|
+
static mul(a: Mat33, b: Vec2Value): Vec2;
|
|
183
|
+
static mul(a: Mat33, b: Vec3Value): Vec3;
|
|
184
|
+
static mul(a, b) {
|
|
185
|
+
if (_ASSERT) Mat33.assert(a);
|
|
186
|
+
if (b && "z" in b && "y" in b && "x" in b) {
|
|
187
|
+
if (_ASSERT) Vec3.assert(b);
|
|
188
|
+
const x = a.ex.x * b.x + a.ey.x * b.y + a.ez.x * b.z;
|
|
189
|
+
const y = a.ex.y * b.x + a.ey.y * b.y + a.ez.y * b.z;
|
|
190
|
+
const z = a.ex.z * b.x + a.ey.z * b.y + a.ez.z * b.z;
|
|
191
|
+
return new Vec3(x, y, z);
|
|
192
|
+
} else if (b && "y" in b && "x" in b) {
|
|
193
|
+
if (_ASSERT) Vec2.assert(b);
|
|
194
|
+
const x = a.ex.x * b.x + a.ey.x * b.y;
|
|
195
|
+
const y = a.ex.y * b.x + a.ey.y * b.y;
|
|
196
|
+
return Vec2.neo(x, y);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (_ASSERT) console.assert(false);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static mulVec3(a: Mat33, b: Vec3Value): Vec3 {
|
|
203
|
+
if (_ASSERT) Mat33.assert(a);
|
|
204
|
+
if (_ASSERT) Vec3.assert(b);
|
|
205
|
+
const x = a.ex.x * b.x + a.ey.x * b.y + a.ez.x * b.z;
|
|
206
|
+
const y = a.ex.y * b.x + a.ey.y * b.y + a.ez.y * b.z;
|
|
207
|
+
const z = a.ex.z * b.x + a.ey.z * b.y + a.ez.z * b.z;
|
|
208
|
+
return new Vec3(x, y, z);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static mulVec2(a: Mat33, b: Vec2Value): Vec2 {
|
|
212
|
+
if (_ASSERT) Mat33.assert(a);
|
|
213
|
+
if (_ASSERT) Vec2.assert(b);
|
|
214
|
+
const x = a.ex.x * b.x + a.ey.x * b.y;
|
|
215
|
+
const y = a.ex.y * b.x + a.ey.y * b.y;
|
|
216
|
+
return Vec2.neo(x, y);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static add(a: Mat33, b: Mat33): Mat33 {
|
|
220
|
+
if (_ASSERT) Mat33.assert(a);
|
|
221
|
+
if (_ASSERT) Mat33.assert(b);
|
|
222
|
+
return new Mat33(Vec3.add(a.ex, b.ex), Vec3.add(a.ey, b.ey), Vec3.add(a.ez, b.ez));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Planck.js
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Erin Catto, Ali Shakiba
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @internal */ const math_random = Math.random;
|
|
11
|
+
|
|
12
|
+
export const EPSILON = 1e-9;
|
|
13
|
+
|
|
14
|
+
/** @internal @deprecated */
|
|
15
|
+
export const isFinite = Number.isFinite;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated
|
|
19
|
+
* Next Largest Power of 2 Given a binary integer value x, the next largest
|
|
20
|
+
* power of 2 can be computed by a SWAR algorithm that recursively "folds" the
|
|
21
|
+
* upper bits into the lower bits. This process yields a bit vector with the
|
|
22
|
+
* same most significant 1 as x, but all 1's below it. Adding 1 to that value
|
|
23
|
+
* yields the next largest power of 2. For a 32-bit value:
|
|
24
|
+
*/
|
|
25
|
+
export function nextPowerOfTwo(x: number): number {
|
|
26
|
+
x |= x >> 1;
|
|
27
|
+
x |= x >> 2;
|
|
28
|
+
x |= x >> 4;
|
|
29
|
+
x |= x >> 8;
|
|
30
|
+
x |= x >> 16;
|
|
31
|
+
return x + 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @deprecated */
|
|
35
|
+
export function isPowerOfTwo(x: number): boolean {
|
|
36
|
+
return x > 0 && (x & (x - 1)) === 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @deprecated */
|
|
40
|
+
export function mod(num: number, min?: number, max?: number): number {
|
|
41
|
+
if (typeof min === "undefined") {
|
|
42
|
+
max = 1;
|
|
43
|
+
min = 0;
|
|
44
|
+
} else if (typeof max === "undefined") {
|
|
45
|
+
max = min;
|
|
46
|
+
min = 0;
|
|
47
|
+
}
|
|
48
|
+
if (max > min) {
|
|
49
|
+
num = (num - min) % (max - min);
|
|
50
|
+
return num + (num < 0 ? max : min);
|
|
51
|
+
} else {
|
|
52
|
+
num = (num - max) % (min - max);
|
|
53
|
+
return num + (num <= 0 ? min : max);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated
|
|
59
|
+
* Returns a min if num is less than min, and max if more than max, otherwise returns num.
|
|
60
|
+
*/
|
|
61
|
+
export function clamp(num: number, min: number, max: number): number {
|
|
62
|
+
if (num < min) {
|
|
63
|
+
return min;
|
|
64
|
+
} else if (num > max) {
|
|
65
|
+
return max;
|
|
66
|
+
} else {
|
|
67
|
+
return num;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated
|
|
73
|
+
* Returns a random number between min and max when two arguments are provided.
|
|
74
|
+
* If one arg is provided between 0 to max.
|
|
75
|
+
* If one arg is passed between 0 to 1.
|
|
76
|
+
*/
|
|
77
|
+
export function random(min?: number, max?: number): number {
|
|
78
|
+
if (typeof min === "undefined") {
|
|
79
|
+
max = 1;
|
|
80
|
+
min = 0;
|
|
81
|
+
} else if (typeof max === "undefined") {
|
|
82
|
+
max = min;
|
|
83
|
+
min = 0;
|
|
84
|
+
}
|
|
85
|
+
return min === max ? min : math_random() * (max - min) + min;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @ignore */
|
|
89
|
+
export const math = Object.create(Math);
|
|
90
|
+
math.EPSILON = EPSILON;
|
|
91
|
+
math.isFinite = isFinite;
|
|
92
|
+
math.nextPowerOfTwo = nextPowerOfTwo;
|
|
93
|
+
math.isPowerOfTwo = isPowerOfTwo;
|
|
94
|
+
math.mod = mod;
|
|
95
|
+
math.clamp = clamp;
|
|
96
|
+
math.random = random;
|