@forgeax/engine-math 0.0.0-dev.8d955ade1c79
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.
- package/LICENSE +202 -0
- package/README.md +294 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/_arbs.d.ts +36 -0
- package/dist/__tests__/_arbs.d.ts.map +1 -0
- package/dist/__tests__/_fixtures.d.ts +61 -0
- package/dist/__tests__/_fixtures.d.ts.map +1 -0
- package/dist/__tests__/bounds2.test.d.ts +2 -0
- package/dist/__tests__/bounds2.test.d.ts.map +1 -0
- package/dist/__tests__/box3.test.d.ts +2 -0
- package/dist/__tests__/box3.test.d.ts.map +1 -0
- package/dist/__tests__/easing.test.d.ts +2 -0
- package/dist/__tests__/easing.test.d.ts.map +1 -0
- package/dist/__tests__/euler.test-d.d.ts +2 -0
- package/dist/__tests__/euler.test-d.d.ts.map +1 -0
- package/dist/__tests__/mat3.test-d.d.ts +2 -0
- package/dist/__tests__/mat3.test-d.d.ts.map +1 -0
- package/dist/__tests__/mat4.property.test.d.ts +2 -0
- package/dist/__tests__/mat4.property.test.d.ts.map +1 -0
- package/dist/__tests__/mat4.test-d.d.ts +2 -0
- package/dist/__tests__/mat4.test-d.d.ts.map +1 -0
- package/dist/__tests__/mat4.test.d.ts +2 -0
- package/dist/__tests__/mat4.test.d.ts.map +1 -0
- package/dist/__tests__/noise.test.d.ts +2 -0
- package/dist/__tests__/noise.test.d.ts.map +1 -0
- package/dist/__tests__/quat.basis.test.d.ts +2 -0
- package/dist/__tests__/quat.basis.test.d.ts.map +1 -0
- package/dist/__tests__/quat.interpolation.test.d.ts +2 -0
- package/dist/__tests__/quat.interpolation.test.d.ts.map +1 -0
- package/dist/__tests__/quat.lookat.test.d.ts +2 -0
- package/dist/__tests__/quat.lookat.test.d.ts.map +1 -0
- package/dist/__tests__/quat.property.test.d.ts +2 -0
- package/dist/__tests__/quat.property.test.d.ts.map +1 -0
- package/dist/__tests__/quat.rotateaxis.test.d.ts +2 -0
- package/dist/__tests__/quat.rotateaxis.test.d.ts.map +1 -0
- package/dist/__tests__/quat.test-d.d.ts +2 -0
- package/dist/__tests__/quat.test-d.d.ts.map +1 -0
- package/dist/__tests__/ray.property.test.d.ts +2 -0
- package/dist/__tests__/ray.property.test.d.ts.map +1 -0
- package/dist/__tests__/ray.test.d.ts +2 -0
- package/dist/__tests__/ray.test.d.ts.map +1 -0
- package/dist/__tests__/types.test-d.d.ts +2 -0
- package/dist/__tests__/types.test-d.d.ts.map +1 -0
- package/dist/__tests__/vec-catmull-rom.test.d.ts +2 -0
- package/dist/__tests__/vec-catmull-rom.test.d.ts.map +1 -0
- package/dist/__tests__/vec-smooth-damp.test.d.ts +2 -0
- package/dist/__tests__/vec-smooth-damp.test.d.ts.map +1 -0
- package/dist/__tests__/vec2.test-d.d.ts +2 -0
- package/dist/__tests__/vec2.test-d.d.ts.map +1 -0
- package/dist/__tests__/vec3.property.test.d.ts +2 -0
- package/dist/__tests__/vec3.property.test.d.ts.map +1 -0
- package/dist/__tests__/vec3.test-d.d.ts +2 -0
- package/dist/__tests__/vec3.test-d.d.ts.map +1 -0
- package/dist/__tests__/vec4.test-d.d.ts +2 -0
- package/dist/__tests__/vec4.test-d.d.ts.map +1 -0
- package/dist/_internal/epsilon.d.ts +9 -0
- package/dist/_internal/epsilon.d.ts.map +1 -0
- package/dist/_internal/scalar.d.ts +40 -0
- package/dist/_internal/scalar.d.ts.map +1 -0
- package/dist/box2.d.ts +35 -0
- package/dist/box2.d.ts.map +1 -0
- package/dist/box3.d.ts +76 -0
- package/dist/box3.d.ts.map +1 -0
- package/dist/circle2.d.ts +29 -0
- package/dist/circle2.d.ts.map +1 -0
- package/dist/color.d.ts +64 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/easing.d.ts +18 -0
- package/dist/easing.d.ts.map +1 -0
- package/dist/euler.d.ts +51 -0
- package/dist/euler.d.ts.map +1 -0
- package/dist/f32-to-f16-bytes.d.ts +10 -0
- package/dist/f32-to-f16-bytes.d.ts.map +1 -0
- package/dist/frustum.d.ts +49 -0
- package/dist/frustum.d.ts.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +3688 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mat3.d.ts +70 -0
- package/dist/mat3.d.ts.map +1 -0
- package/dist/mat4.d.ts +329 -0
- package/dist/mat4.d.ts.map +1 -0
- package/dist/noise.d.ts +12 -0
- package/dist/noise.d.ts.map +1 -0
- package/dist/quat.d.ts +312 -0
- package/dist/quat.d.ts.map +1 -0
- package/dist/ray.d.ts +144 -0
- package/dist/ray.d.ts.map +1 -0
- package/dist/ray2.d.ts +38 -0
- package/dist/ray2.d.ts.map +1 -0
- package/dist/sphere.d.ts +41 -0
- package/dist/sphere.d.ts.map +1 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vec2.d.ts +76 -0
- package/dist/vec2.d.ts.map +1 -0
- package/dist/vec3.d.ts +82 -0
- package/dist/vec3.d.ts.map +1 -0
- package/dist/vec4.d.ts +61 -0
- package/dist/vec4.d.ts.map +1 -0
- package/package.json +57 -0
- package/src/__tests__/_arbs.ts +149 -0
- package/src/__tests__/_fixtures.ts +118 -0
- package/src/__tests__/bounds2.test.ts +146 -0
- package/src/__tests__/box3.test.ts +277 -0
- package/src/__tests__/easing.test.ts +109 -0
- package/src/__tests__/euler.test-d.ts +63 -0
- package/src/__tests__/mat3.test-d.ts +47 -0
- package/src/__tests__/mat4.property.test.ts +256 -0
- package/src/__tests__/mat4.test-d.ts +130 -0
- package/src/__tests__/mat4.test.ts +162 -0
- package/src/__tests__/noise.test.ts +75 -0
- package/src/__tests__/quat.basis.test.ts +134 -0
- package/src/__tests__/quat.interpolation.test.ts +45 -0
- package/src/__tests__/quat.lookat.test.ts +103 -0
- package/src/__tests__/quat.property.test.ts +150 -0
- package/src/__tests__/quat.rotateaxis.test.ts +149 -0
- package/src/__tests__/quat.test-d.ts +138 -0
- package/src/__tests__/ray.property.test.ts +105 -0
- package/src/__tests__/ray.test.ts +539 -0
- package/src/__tests__/types.test-d.ts +64 -0
- package/src/__tests__/vec-catmull-rom.test.ts +125 -0
- package/src/__tests__/vec-smooth-damp.test.ts +167 -0
- package/src/__tests__/vec2.test-d.ts +59 -0
- package/src/__tests__/vec3.property.test.ts +72 -0
- package/src/__tests__/vec3.test-d.ts +65 -0
- package/src/__tests__/vec4.test-d.ts +61 -0
- package/src/_internal/epsilon.ts +29 -0
- package/src/_internal/scalar.ts +90 -0
- package/src/box2.ts +168 -0
- package/src/box3.ts +372 -0
- package/src/circle2.ts +134 -0
- package/src/color.ts +177 -0
- package/src/easing.ts +49 -0
- package/src/euler.ts +239 -0
- package/src/f32-to-f16-bytes.ts +71 -0
- package/src/frustum.ts +240 -0
- package/src/index.ts +65 -0
- package/src/mat3.ts +286 -0
- package/src/mat4.ts +1334 -0
- package/src/noise.ts +78 -0
- package/src/quat.ts +847 -0
- package/src/ray.ts +575 -0
- package/src/ray2.ts +198 -0
- package/src/sphere.ts +138 -0
- package/src/types.ts +78 -0
- package/src/vec2.ts +229 -0
- package/src/vec3.ts +294 -0
- package/src/vec4.ts +235 -0
package/dist/quat.d.ts
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import type { EulerOrder, Mat3Like, Quat, QuatLike, Vec3, Vec3Like } from './types';
|
|
2
|
+
export type { Quat, QuatLike };
|
|
3
|
+
/** Create a Quat (default all zero; callers usually call identity() right after). */
|
|
4
|
+
export declare function create(): Quat;
|
|
5
|
+
/** Allocate a new Quat copy. */
|
|
6
|
+
export declare function clone(a: QuatLike): Quat;
|
|
7
|
+
/** out = identity quaternion [0, 0, 0, 1]. Returns out. */
|
|
8
|
+
export declare function identity(out: Quat): Quat;
|
|
9
|
+
/**
|
|
10
|
+
* out = quaternion representing rotation by angleRadians around axis. Returns out.
|
|
11
|
+
*
|
|
12
|
+
* axis does not have to be pre-normalized; this function normalizes it internally.
|
|
13
|
+
*
|
|
14
|
+
* @degrade axis is the zero vector (lengthSq < EPS_NORMALIZE) → out = identity
|
|
15
|
+
* (no throw, registry #8).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* quat.fromAxisAngle(out, [0, 1, 0], Math.PI / 2);
|
|
20
|
+
* // Guard: if (vec3.lengthSq(axis) < EPS_NORMALIZE) skip;
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function fromAxisAngle(out: Quat, axis: Vec3Like, angleRadians: number): Quat;
|
|
24
|
+
/**
|
|
25
|
+
* out = quaternion from intrinsic Euler angles (x, y, z, order). Returns out.
|
|
26
|
+
*
|
|
27
|
+
* Angle unit = **radians** (aligned with wgpu-matrix / Three.js; research §fact-correction 4
|
|
28
|
+
* deviates from gl-matrix's degrees).
|
|
29
|
+
* 6 orders: XYZ / YXZ / ZXY / ZYX / YZX / XZY (intrinsic rotation: literal order x → y → z).
|
|
30
|
+
* Implementation: split each axis rotation into single-axis quaternions, then Hamilton-multiply
|
|
31
|
+
* in `order`.
|
|
32
|
+
*
|
|
33
|
+
* @degrade order outside the EulerOrder union (only possible via `as any` cast) →
|
|
34
|
+
* **silently computes as if 'XYZ'** (D-P2 + AC-06 no throw; registry #9).
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* quat.fromEuler(out, 0.5, 0.3, 0.1, 'XYZ');
|
|
39
|
+
* quat.fromEuler(out, 0.5, 0.3, 0.1, 'unknown' as any); // silently computed as 'XYZ'
|
|
40
|
+
* // Guard: pass an EulerOrder union literal; the TS layer already blocks unknown strings.
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function fromEuler(out: Quat, x: number, y: number, z: number, order: EulerOrder): Quat;
|
|
44
|
+
/**
|
|
45
|
+
* out = quaternion from a 3x3 rotation matrix m (column-major, length 9). Returns out.
|
|
46
|
+
*
|
|
47
|
+
* Implementation: Shepperd's case-split (branch on trace / largest diagonal entry); numerically
|
|
48
|
+
* more stable than the direct trace method (avoids sqrt(0) when trace ≈ -1).
|
|
49
|
+
*
|
|
50
|
+
* Assumption: m is a pure rotation matrix (|det|=1, columns orthogonal). If not, the result is
|
|
51
|
+
* undefined but does not throw.
|
|
52
|
+
*
|
|
53
|
+
* @degrade m is not a pure rotation (contains shear / scale) → numerically undefined but does
|
|
54
|
+
* not throw (AC-06 no throw; callers should normalize column vectors first or avoid
|
|
55
|
+
* introducing non-pure-rotation matrices at the ECS-design layer).
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* quat.fromRotationMatrix(out, mat3InstanceColumnMajor);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function fromRotationMatrix(out: Quat, m: Mat3Like): Quat;
|
|
63
|
+
/**
|
|
64
|
+
* out = orientation quaternion for an object placed at `eye` and facing `target`. Returns out.
|
|
65
|
+
*
|
|
66
|
+
* This is the ergonomic camera/look-at helper: it yields the WORLD-space orientation an entity's
|
|
67
|
+
* Transform.rotation needs so that its local -z axis points from `eye` toward `target` (the camera
|
|
68
|
+
* convention, matching `mat4.lookAt`). Use it instead of hand-wiring
|
|
69
|
+
* `mat4.lookAt → mat4.invert → mat3.fromMat4 → quat.fromRotationMatrix`; that chain is easy to get
|
|
70
|
+
* wrong (notably `fromRotationMatrix` takes a mat3, but `Mat4Like`≡`Mat3Like`≡`ArrayLike<number>`,
|
|
71
|
+
* so passing a mat4 typechecks and silently reads garbage → NaN → nothing renders).
|
|
72
|
+
*
|
|
73
|
+
* Convenience composition (like `mat4.computeViewProj`), not a primitive: it builds the same
|
|
74
|
+
* right/newUp/forward basis as `mat4.lookAt` and reuses `fromRotationMatrix` for the extraction.
|
|
75
|
+
*
|
|
76
|
+
* @degrade eye ≈ target (|eye-target| < EPS_NORMALIZE) → out = identity (same convention as
|
|
77
|
+
* `mat4.lookAt` degenerate #4; no throw, AC-06).
|
|
78
|
+
* @degrade up collinear with the view direction → alternative up auto-selected (same as
|
|
79
|
+
* `mat4.lookAt` #5).
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* // aim a camera at the origin
|
|
84
|
+
* const q = quat.fromLookAt(quat.create(), [-2.5, 4.5, 9], [0, 0, 0], [0, 1, 0]);
|
|
85
|
+
* world.set(cameraEntity, Transform, { pos: [-2.5, 4.5, 9], rot: q });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function fromLookAt(out: Quat, eye: Vec3Like, target: Vec3Like, up: Vec3Like): Quat;
|
|
89
|
+
/**
|
|
90
|
+
* out = quaternion that rotates the unit vector v to w (shortest arc). Returns out.
|
|
91
|
+
*
|
|
92
|
+
* Assumes v and w are normalized; if not, the caller is responsible.
|
|
93
|
+
*
|
|
94
|
+
* @degrade v ≈ w (dot > 1 - EPS_QUAT_PARALLEL) → out = identity (registry #13).
|
|
95
|
+
* @degrade v ≈ -w (dot < -1 + EPS_QUAT_PARALLEL) → pick a perpendicular axis and do a 180°
|
|
96
|
+
* rotation (prefer (0,1,0); fall back to (1,0,0) when collinear with v;
|
|
97
|
+
* registry #12 + D-P18).
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* quat.fromUnitVectors(out, [1,0,0], [0,1,0]); // 90° around Z
|
|
102
|
+
* quat.fromUnitVectors(out, [1,0,0], [-1,0,0]); // 180° opposite: pick (0,1,0) axis
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function fromUnitVectors(out: Quat, v: Vec3Like, w: Vec3Like): Quat;
|
|
106
|
+
/**
|
|
107
|
+
* out = a * b (Hamilton product). Returns out.
|
|
108
|
+
*
|
|
109
|
+
* Aliasing-safe: reads all 8 source elements into locals first.
|
|
110
|
+
*/
|
|
111
|
+
export declare function multiply(out: Quat, a: QuatLike, b: QuatLike): Quat;
|
|
112
|
+
/**
|
|
113
|
+
* out = the orientation `q` after rotating a further `angleRadians` about world-space `axis`,
|
|
114
|
+
* re-normalized. Returns out.
|
|
115
|
+
*
|
|
116
|
+
* This is the ergonomic *incremental rotate* helper — the per-frame spin/animation move. It folds
|
|
117
|
+
* the three steps every rotating demo otherwise hand-wires: build the delta quaternion
|
|
118
|
+
* (`fromAxisAngle`), **pre**-multiply it onto the current orientation (world-space axis, matching
|
|
119
|
+
* **Bevy `Transform::rotate(r)` = `r * self.rotation`** / `rotate_y(θ)`), and — the step that is
|
|
120
|
+
* silently omitted and makes the naive loop wrong — **normalize** to shed the floating-point error
|
|
121
|
+
* that accumulates over thousands of frames into a non-unit quaternion (skew / scale artefacts).
|
|
122
|
+
*
|
|
123
|
+
* Prefer this over hand-writing `quat.multiply(q, delta, q)` in an update system: that loop drifts,
|
|
124
|
+
* so demos work around it with an absolute-angle accumulator + `fromAxisAngle` (can't compose onto an
|
|
125
|
+
* existing orientation) or raw `sin/cos` quaternion literals. `rotateAxis` composes safely.
|
|
126
|
+
*
|
|
127
|
+
* Convenience composition (like `fromLookAt`), not a primitive: same result as
|
|
128
|
+
* `normalize(out, multiply(out, fromAxisAngle(tmp, axis, angleRadians), q))`, fused + aliasing-safe.
|
|
129
|
+
*
|
|
130
|
+
* @degrade `axis` zero-length → the delta is identity (degenerate registry #8), so out = normalize(q)
|
|
131
|
+
* (no rotation applied; no throw, consistent with the sibling helpers).
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* // in an Update system: spin a cube about +Y at `speed` rad/s using the frame delta
|
|
136
|
+
* const dt = world.getResource(Time).delta;
|
|
137
|
+
* const t = world.get(entity, Transform).unwrap();
|
|
138
|
+
* quat.rotateAxis(t.quat, t.quat, [0, 1, 0], speed * dt); // in-place accumulate, no drift
|
|
139
|
+
* world.set(entity, Transform, t);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export declare function rotateAxis(out: Quat, q: QuatLike, axis: Vec3Like, angleRadians: number): Quat;
|
|
143
|
+
/**
|
|
144
|
+
* out = spherical linear interpolation(a, b, t). Returns out.
|
|
145
|
+
*
|
|
146
|
+
* t is not clamped (extrapolation semantics matches vec.lerp).
|
|
147
|
+
*
|
|
148
|
+
* @degrade dot(a, b) < -EPS_SLERP_DOT_LIMIT (anti-parallel) → **negate b' = -b then slerp**
|
|
149
|
+
* (D-P6; q and -q represent the same rotation; registry #10).
|
|
150
|
+
* @degrade |dot(a, b)| > 1 - EPS_SLERP_DOT_LIMIT (endpoint coincidence or near-coincidence) →
|
|
151
|
+
* falls back to nlerp (avoids acos blow-up; registry #11).
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* quat.slerp(out, a, b, 0.5);
|
|
156
|
+
* // Anti-parallel (dot ≈ -1): caller does not need to pre-process; the negation fall-back
|
|
157
|
+
* // happens internally.
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export declare function slerp(out: Quat, a: QuatLike, b: QuatLike, t: number): Quat;
|
|
161
|
+
/**
|
|
162
|
+
* out = normalized lerp(a, b, t). Returns out.
|
|
163
|
+
*
|
|
164
|
+
* Faster than slerp but the angular velocity is non-uniform; use it as a slerp substitute near endpoints.
|
|
165
|
+
* Like slerp, automatically handles dot < 0 by negating b to keep the shortest arc.
|
|
166
|
+
*
|
|
167
|
+
* @degrade lerp result is near zero (very rare) → out = identity.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* quat.nlerp(out, qA, qB, 0.5);
|
|
172
|
+
* // Very rare: lerp result lengthSq < EPS_NORMALIZE → out = (0, 0, 0, 1)
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export declare function nlerp(out: Quat, a: QuatLike, b: QuatLike, t: number): Quat;
|
|
176
|
+
/**
|
|
177
|
+
* out = inverse of a (conjugate / lengthSq). Returns out.
|
|
178
|
+
*
|
|
179
|
+
* For unit quaternions, invert is equivalent to conjugate (and faster); this implementation uses
|
|
180
|
+
* the general a/|a|² form to support non-unit inputs.
|
|
181
|
+
*
|
|
182
|
+
* @degrade lengthSq(a) < EPS_NORMALIZE (zero quaternion) → out = identity (does not return NaN;
|
|
183
|
+
* same convention as mat invert).
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* quat.invert(out, q);
|
|
188
|
+
* quat.invert(out, quat.create(0, 0, 0, 0)); // → out = identity (0, 0, 0, 1), AC-06 no throw
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export declare function invert(out: Quat, a: QuatLike): Quat;
|
|
192
|
+
/** out = conjugate quaternion [-x, -y, -z, w] (aliasing-safe). Returns out. */
|
|
193
|
+
export declare function conjugate(out: Quat, a: QuatLike): Quat;
|
|
194
|
+
/** dot(a, b) = ax*bx + ay*by + az*bz + aw*bw (returns scalar). */
|
|
195
|
+
export declare function dot(a: QuatLike, b: QuatLike): number;
|
|
196
|
+
/** sqrt(x² + y² + z² + w²). Delegates to lengthSq + Math.sqrt (canonical pattern; see clone-5-quat-audit.md). */
|
|
197
|
+
export declare function length(a: QuatLike): number;
|
|
198
|
+
/** x² + y² + z² + w² (no sqrt). */
|
|
199
|
+
export declare function lengthSq(a: QuatLike): number;
|
|
200
|
+
/**
|
|
201
|
+
* out = q · v · q⁻¹ (rotate vec3 v by the unit quaternion q). Returns out.
|
|
202
|
+
*
|
|
203
|
+
* Rodrigues optimized form (research Finding 3, 18 mul + 12 add):
|
|
204
|
+
* t = 2 · cross(q.xyz, v)
|
|
205
|
+
* out = v + q.w · t + cross(q.xyz, t)
|
|
206
|
+
*
|
|
207
|
+
* 3-5× faster than going through mat4 (fromQuat → transformVec3); same shape as gl-matrix
|
|
208
|
+
* `vec3.transformQuat` / Three.js `Vector3.applyQuaternion` (industry consensus).
|
|
209
|
+
*
|
|
210
|
+
* Aliasing-safe: reads v.xyz / q.xyzw into locals before writing out.
|
|
211
|
+
*
|
|
212
|
+
* @degrade q must be a unit-length quaternion. A non-unit q introduces implicit scaling
|
|
213
|
+
* (D-4 silent convention; no throw; AI users always get unit-length q from
|
|
214
|
+
* quat.fromAxisAngle / fromEuler / normalize / slerp, so this branch is not hit).
|
|
215
|
+
* When q = (0,0,0,0), t = 0 → out = v (the natural result of the formula; matches
|
|
216
|
+
* gl-matrix / Three.js; non-NaN, no throw).
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* const q = quat.fromAxisAngle(quat.create(), [0, 1, 0], Math.PI / 2);
|
|
221
|
+
* const out = vec3.create();
|
|
222
|
+
* quat.transformVec3(out, q, [1, 0, 0]); // → out ≈ (0, 0, -1)
|
|
223
|
+
* // Guard: q derived from the quat surface is always unit-length; callers do not need to normalize.
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
export declare function transformVec3(out: Vec3, q: QuatLike, v: Vec3Like): Vec3;
|
|
227
|
+
/**
|
|
228
|
+
* out = a / length(a). Returns out.
|
|
229
|
+
*
|
|
230
|
+
* @degrade lengthSq(a) < EPS_NORMALIZE → out = [0, 0, 0, 0] (same convention as vec.normalize;
|
|
231
|
+
* does not write identity, preserving the "zero quaternion" semantics; if the caller
|
|
232
|
+
* needs identity it should use fromAxisAngle with 0-axis).
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```ts
|
|
236
|
+
* quat.normalize(out, q);
|
|
237
|
+
* quat.normalize(out, quat.create(0, 0, 0, 0)); // → out = (0, 0, 0, 0); zero-quaternion semantics preserved
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
export declare function normalize(out: Quat, a: QuatLike): Quat;
|
|
241
|
+
/**
|
|
242
|
+
* Convenience: quaternion representing rotation `theta` radians around the
|
|
243
|
+
* Y axis. Equivalent to `quat.fromEuler(out, 0, theta, 0, 'YXZ')` but
|
|
244
|
+
* allocates its own output `Quat`.
|
|
245
|
+
*
|
|
246
|
+
* Formula: `(0, sin(theta/2), 0, cos(theta/2))`.
|
|
247
|
+
*
|
|
248
|
+
* @degrade eulerY(0) → identity, eulerY(2pi) → identity within epsilon.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* const yaw45 = quat.eulerY(Math.PI / 4);
|
|
253
|
+
* // yaw45 ≈ [0, 0.3826834, 0, 0.9238795]
|
|
254
|
+
* ```
|
|
255
|
+
*
|
|
256
|
+
* @example Equivalent to the verbose form:
|
|
257
|
+
* ```ts
|
|
258
|
+
* const q1 = quat.eulerY(theta);
|
|
259
|
+
* const q2 = quat.fromEuler(quat.create(), 0, theta, 0, 'YXZ');
|
|
260
|
+
* // q1 === q2 (within epsilon)
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export declare function eulerY(theta: number): Quat;
|
|
264
|
+
/**
|
|
265
|
+
* Local right axis: the world-space direction the rotation's own +X axis points.
|
|
266
|
+
* `right(out, q) = quat.transformVec3(out, q, [1, 0, 0])`. Mirrors
|
|
267
|
+
* `mat4.getRight`; matches Bevy `Transform::local_x` / `Transform::right`.
|
|
268
|
+
*
|
|
269
|
+
* @degrade q must be unit-length (guaranteed by the quat surface); a unit q
|
|
270
|
+
* yields a unit result. q = (0,0,0,0) → out = (1,0,0) (the natural
|
|
271
|
+
* transformVec3 result; non-NaN, no throw).
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* const q = quat.eulerY(Math.PI / 2); // 90° about +Y
|
|
276
|
+
* quat.right(vec3.create(), q); // → (0, 0, -1): +X yawed a quarter-turn
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
export declare function right(out: Vec3, q: QuatLike): Vec3;
|
|
280
|
+
/**
|
|
281
|
+
* Local up axis: the world-space direction the rotation's own +Y axis points.
|
|
282
|
+
* `up(out, q) = quat.transformVec3(out, q, [0, 1, 0])`. Mirrors `mat4.getUp`;
|
|
283
|
+
* matches Bevy `Transform::local_y` / `Transform::up`.
|
|
284
|
+
*
|
|
285
|
+
* @degrade q must be unit-length (guaranteed by the quat surface); a unit q
|
|
286
|
+
* yields a unit result. q = (0,0,0,0) → out = (0,1,0).
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```ts
|
|
290
|
+
* const q = quat.fromAxisAngle(quat.create(), [1, 0, 0], Math.PI / 2); // pitch 90°
|
|
291
|
+
* quat.up(vec3.create(), q); // → (0, 0, 1): +Y pitched onto +Z
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
export declare function up(out: Vec3, q: QuatLike): Vec3;
|
|
295
|
+
/**
|
|
296
|
+
* Local forward axis: the world-space direction the rotation's own −Z axis
|
|
297
|
+
* points (−Z look convention, RL-4). `forward(out, q) =
|
|
298
|
+
* quat.transformVec3(out, q, [0, 0, -1])`. Mirrors `mat4.getForward`; matches
|
|
299
|
+
* Bevy `Transform::forward` (Bevy also uses −Z). A quat from `fromLookAt(eye,
|
|
300
|
+
* target, up)` has `forward(q)` ≈ normalize(target − eye).
|
|
301
|
+
*
|
|
302
|
+
* @degrade q must be unit-length (guaranteed by the quat surface); a unit q
|
|
303
|
+
* yields a unit result. q = (0,0,0,0) → out = (0,0,-1).
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* const q = quat.eulerY(Math.PI / 2); // 90° about +Y
|
|
308
|
+
* quat.forward(vec3.create(), q); // → (-1, 0, 0): -Z yawed a quarter-turn
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
export declare function forward(out: Vec3, q: QuatLike): Vec3;
|
|
312
|
+
//# sourceMappingURL=quat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quat.d.ts","sourceRoot":"","sources":["../src/quat.ts"],"names":[],"mappings":"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"}
|
package/dist/ray.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { Box3Like } from './box3';
|
|
2
|
+
import type { Mat4Like, Vec2, Vec3, Vec3Like } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Result of a ray-triangle intersection test (Moller-Trumbore).
|
|
5
|
+
* `t` = ray parameter, `u`/`v` = barycentric coordinates.
|
|
6
|
+
*/
|
|
7
|
+
export interface RayTriResult {
|
|
8
|
+
hit: boolean;
|
|
9
|
+
t: number;
|
|
10
|
+
u: number;
|
|
11
|
+
v: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Ray storage: Float32Array length 6 [ox, oy, oz, dx, dy, dz], direction normalized.
|
|
15
|
+
* Local brand (not part of the seven-piece SSOT; same rationale as Box3).
|
|
16
|
+
*/
|
|
17
|
+
export type Ray = Float32Array & {
|
|
18
|
+
readonly __ray: void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Ray readable input: ArrayLike<number> of length 6 (ordering identical to Ray).
|
|
22
|
+
*/
|
|
23
|
+
export type RayLike = ArrayLike<number>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a Ray. Defaults to origin=(0,0,0), direction=(0,0,-1) normalized.
|
|
26
|
+
*
|
|
27
|
+
* When `out` is not provided, a new Float32Array is allocated.
|
|
28
|
+
* When `origin` / `direction` are provided, direction is normalized
|
|
29
|
+
* (zero-length direction falls back to (0,0,0) per gl-matrix style).
|
|
30
|
+
*/
|
|
31
|
+
export declare function create(out?: Float32Array, origin?: Vec3Like, direction?: Vec3Like): Ray;
|
|
32
|
+
/**
|
|
33
|
+
* Copy the origin of `r` into `out`. Returns `out`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getOrigin(out: Vec3, r: RayLike): Vec3;
|
|
36
|
+
/**
|
|
37
|
+
* Copy the direction of `r` into `out`. Returns `out`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getDirection(out: Vec3, r: RayLike): Vec3;
|
|
40
|
+
/**
|
|
41
|
+
* Overwrite the origin of `r` with `o`. Returns `r`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function setOrigin(r: Ray, o: Vec3Like): Ray;
|
|
44
|
+
/**
|
|
45
|
+
* Overwrite the direction of `r` with `d` and normalize it.
|
|
46
|
+
* Zero-length direction falls back to (0,0,0) (gl-matrix style).
|
|
47
|
+
* Returns `r`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function setDirection(r: Ray, d: Vec3Like): Ray;
|
|
50
|
+
/**
|
|
51
|
+
* Result of a ray-AABB intersection test.
|
|
52
|
+
*/
|
|
53
|
+
export interface RayAabbResult {
|
|
54
|
+
hit: boolean;
|
|
55
|
+
/** Entry distance along the ray (clamped to 0 when origin is inside the box). */
|
|
56
|
+
tmin: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Test whether a ray intersects an axis-aligned bounding box using the
|
|
60
|
+
* slab (Kay-Kajiya) method.
|
|
61
|
+
*
|
|
62
|
+
* Six degenerate cases per research Finding 2:
|
|
63
|
+
* 1. hit from outside → `tmin > 0`
|
|
64
|
+
* 2. hit from inside → `tmin = 0`
|
|
65
|
+
* 3. miss (ray away) → `hit = false`
|
|
66
|
+
* 4. parallel-axis miss → natural via ±Inf propagation
|
|
67
|
+
* 5. edge/corner NaN-safe → guard `t1 > t2` NaN scenarios with `Number.isNaN`
|
|
68
|
+
* 6. thin box (1D/2D) → correct via interval shrink
|
|
69
|
+
*
|
|
70
|
+
* Algorithm: precompute `inv = 1/D`, use `inv[i] < 0` (not direction[i] < 0)
|
|
71
|
+
* to handle `-0` direction correctly. On each axis compute `(min - O)*inv` and
|
|
72
|
+
* `(max - O)*inv`, swap when `inv < 0`, then accumulate `t_near = max(t_near, t1)`,
|
|
73
|
+
* `t_far = min(t_far, t2)`. Hit when `t_far >= max(t_near, 0)`.
|
|
74
|
+
*
|
|
75
|
+
* Input: `r` (Ray with normalized direction) + `aabb` (Box3Like, 6 floats).
|
|
76
|
+
* Output: `{ hit: boolean, tmin: number }`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function rayAabbIntersects(r: RayLike, aabb: Box3Like): RayAabbResult;
|
|
79
|
+
/**
|
|
80
|
+
* Project a screen-space coordinate into a world-space Ray.
|
|
81
|
+
*
|
|
82
|
+
* `screenX` / `screenY` are in pixels relative to the top-left corner of the viewport
|
|
83
|
+
* (DOM convention: y-down). They are clamped to `[0, vpWidth]` / `[0, vpHeight]` and
|
|
84
|
+
* sanitized against NaN/Inf.
|
|
85
|
+
*
|
|
86
|
+
* `kind` discriminates the projection type so callers can branch on the result if needed;
|
|
87
|
+
* both paths use the same two-point unproject algorithm.
|
|
88
|
+
*
|
|
89
|
+
* @param out The Ray to write into.
|
|
90
|
+
* @param screenX Horizontal pixel coordinate (y-down origin, top-left).
|
|
91
|
+
* @param screenY Vertical pixel coordinate.
|
|
92
|
+
* @param vpWidth Viewport width in pixels.
|
|
93
|
+
* @param vpHeight Viewport height in pixels.
|
|
94
|
+
* @param view Camera view matrix (world→eye).
|
|
95
|
+
* @param proj Camera projection matrix (eye→clip).
|
|
96
|
+
* @param kind `'perspective'` or `'orthographic'`.
|
|
97
|
+
* @returns `out` (same Ray instance).
|
|
98
|
+
*/
|
|
99
|
+
export declare function screenToRay(out: Ray, screenX: number, screenY: number, vpWidth: number, vpHeight: number, view: Mat4Like, proj: Mat4Like, _kind: 'perspective' | 'orthographic'): Ray;
|
|
100
|
+
/** Result of projecting a world-space point to screen-space pixel coordinates. */
|
|
101
|
+
export interface WorldToScreenResult {
|
|
102
|
+
/** True if the NDC coordinates are within clip-space bounds. */
|
|
103
|
+
onScreen: boolean;
|
|
104
|
+
/** True if the original world-space point is behind the camera (w < 0).
|
|
105
|
+
* When true, `out` is meaningless (requirements §7). */
|
|
106
|
+
behind: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Project a world-space point to screen-space pixel coordinates.
|
|
110
|
+
*
|
|
111
|
+
* Performs a full mat4 * vec4 internally to capture the pre-divide `w` component
|
|
112
|
+
* (projectPoint discards `w`, so it cannot report `behind`).
|
|
113
|
+
*
|
|
114
|
+
* Pixel mapping: top-left origin, y-down (DOM convention).
|
|
115
|
+
* px = (ndc.x * 0.5 + 0.5) * canvasW
|
|
116
|
+
* py = (1 - (ndc.y * 0.5 + 0.5)) * canvasH
|
|
117
|
+
*
|
|
118
|
+
* Degenerate viewport (canvasW <= 0 || canvasH <= 0): returns { onScreen: false, behind: false },
|
|
119
|
+
* leaves `out` untouched.
|
|
120
|
+
*
|
|
121
|
+
* @param out Vec2 to write pixel coordinates into (y-down, top-left origin).
|
|
122
|
+
* @param worldPos World-space point (3 floats).
|
|
123
|
+
* @param viewProj Combined view-projection matrix (proj * view, 16 floats).
|
|
124
|
+
* @param canvasW Canvas width in pixels.
|
|
125
|
+
* @param canvasH Canvas height in pixels.
|
|
126
|
+
* @returns { onScreen: boolean, behind: boolean } — pure data flags, no allocation.
|
|
127
|
+
*/
|
|
128
|
+
export declare function worldToScreen(out: Vec2, worldPos: Vec3Like, viewProj: Mat4Like, canvasW: number, canvasH: number): WorldToScreenResult;
|
|
129
|
+
/**
|
|
130
|
+
* Test whether a ray intersects a triangle using the Moller-Trumbore algorithm.
|
|
131
|
+
*
|
|
132
|
+
* Double-sided: both front and back faces are checked (abs(det) < epsilon).
|
|
133
|
+
* Degenerate triangles (collinear / zero-area) return hit=false.
|
|
134
|
+
* Ray origin behind the triangle (t <= 0) is rejected.
|
|
135
|
+
* NaN inputs are guarded against — any NaN input returns hit=false.
|
|
136
|
+
*
|
|
137
|
+
* @param r Ray (RayLike, 6 floats: ox,oy,oz,dx,dy,dz with normalized direction).
|
|
138
|
+
* @param a Triangle vertex A (Vec3Like, 3 floats).
|
|
139
|
+
* @param b Triangle vertex B (Vec3Like, 3 floats).
|
|
140
|
+
* @param c Triangle vertex C (Vec3Like, 3 floats).
|
|
141
|
+
* @returns RayTriResult with hit flag, t (ray parameter), and u/v (barycentric coordinates).
|
|
142
|
+
*/
|
|
143
|
+
export declare function rayTriangleIntersects(r: RayLike, a: Vec3Like, b: Vec3Like, c: Vec3Like): RayTriResult;
|
|
144
|
+
//# sourceMappingURL=ray.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ray.d.ts","sourceRoot":"","sources":["../src/ray.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;GAGG;AACH,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,QAAQ,GAAG,GAAG,CAgCvF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,CAKrD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,CAKxD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,GAAG,GAAG,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,GAAG,GAAG,CAgBrD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,aAAa,CAgE3E;AA0BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,aAAa,GAAG,cAAc,GACpC,GAAG,CAoEL;AAaD,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAC;IAClB;6DACyD;IACzD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,IAAI,EACT,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,mBAAmB,CAkDrB;AAmBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,OAAO,EACV,CAAC,EAAE,QAAQ,EACX,CAAC,EAAE,QAAQ,EACX,CAAC,EAAE,QAAQ,GACV,YAAY,CAiFd"}
|
package/dist/ray2.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Box2Like } from './box2';
|
|
2
|
+
import type { Circle2Like } from './circle2';
|
|
3
|
+
import type { Vec2, Vec2Like } from './types';
|
|
4
|
+
/** 2D ray storage: [originX, originY, directionX, directionY, maxDistance]. */
|
|
5
|
+
export type Ray2 = Float32Array & {
|
|
6
|
+
readonly __ray2: void;
|
|
7
|
+
};
|
|
8
|
+
/** Readable 2D ray input. */
|
|
9
|
+
export type Ray2Like = ArrayLike<number>;
|
|
10
|
+
/** Result shared by AABB, circle, and swept-volume intersection tests. */
|
|
11
|
+
export interface Ray2Intersection {
|
|
12
|
+
hit: boolean;
|
|
13
|
+
/** Entry distance along the normalized ray, clamped to zero when inside. */
|
|
14
|
+
t: number;
|
|
15
|
+
}
|
|
16
|
+
/** Create a normalized finite 2D ray. `maxDistance` defaults to infinity. */
|
|
17
|
+
export declare function create(out?: Float32Array, origin?: Vec2Like, direction?: Vec2Like, maxDistance?: number): Ray2;
|
|
18
|
+
/** Copy the ray origin to out. */
|
|
19
|
+
export declare function getOrigin(out: Vec2, ray: Ray2Like): Vec2;
|
|
20
|
+
/** Copy the normalized ray direction to out. */
|
|
21
|
+
export declare function getDirection(out: Vec2, ray: Ray2Like): Vec2;
|
|
22
|
+
/** Return the ray's finite travel limit. */
|
|
23
|
+
export declare function getMaxDistance(ray: Ray2Like): number;
|
|
24
|
+
/** Set the ray origin. */
|
|
25
|
+
export declare function setOrigin(ray: Ray2, origin: Vec2Like): Ray2;
|
|
26
|
+
/** Set and normalize the ray direction. */
|
|
27
|
+
export declare function setDirection(ray: Ray2, direction: Vec2Like): Ray2;
|
|
28
|
+
/** Set the ray's non-negative travel limit. */
|
|
29
|
+
export declare function setMaxDistance(ray: Ray2, maxDistance: number): Ray2;
|
|
30
|
+
/** Intersect a finite ray with an AABB using the 2D slab method. */
|
|
31
|
+
export declare function rayAabbIntersects(ray: Ray2Like, box: Box2Like): Ray2Intersection;
|
|
32
|
+
/** Intersect a finite ray with a bounding circle. */
|
|
33
|
+
export declare function rayCircleIntersects(ray: Ray2Like, circle: Circle2Like): Ray2Intersection;
|
|
34
|
+
/** Sweep an AABB along a finite ray and intersect it with a target AABB. */
|
|
35
|
+
export declare function aabbCastIntersects(ray: Ray2Like, moving: Box2Like, target: Box2Like): Ray2Intersection;
|
|
36
|
+
/** Sweep a circle along a finite ray and intersect it with a target circle. */
|
|
37
|
+
export declare function circleCastIntersects(ray: Ray2Like, moving: Circle2Like, target: Circle2Like): Ray2Intersection;
|
|
38
|
+
//# sourceMappingURL=ray2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ray2.d.ts","sourceRoot":"","sources":["../src/ray2.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,6BAA6B;AAC7B,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAEzC,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,OAAO,CAAC;IACb,4EAA4E;IAC5E,CAAC,EAAE,MAAM,CAAC;CACX;AAED,6EAA6E;AAC7E,wBAAgB,MAAM,CACpB,GAAG,CAAC,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,QAAQ,EACjB,SAAS,CAAC,EAAE,QAAQ,EACpB,WAAW,SAA2B,GACrC,IAAI,CAiBN;AAED,kCAAkC;AAClC,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAIxD;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAI3D;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAEpD;AAED,0BAA0B;AAC1B,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAI3D;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,CAajE;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAGnE;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAEhF;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAExF;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,GACf,gBAAgB,CAUlB;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,WAAW,GAClB,gBAAgB,CAOlB"}
|
package/dist/sphere.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as box3 from './box3';
|
|
2
|
+
import type { Vec3Like } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Sphere storage: Float32Array length 4 [cx, cy, cz, radius].
|
|
5
|
+
* Local brand (not part of the seven-piece SSOT); see box3.ts rationale.
|
|
6
|
+
*/
|
|
7
|
+
export type Sphere = Float32Array & {
|
|
8
|
+
readonly __sphere: void;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Sphere readable input: ArrayLike<number> of length 4 (ordering identical to Sphere).
|
|
12
|
+
*/
|
|
13
|
+
export type SphereLike = ArrayLike<number>;
|
|
14
|
+
/**
|
|
15
|
+
* Create a Sphere. Defaults to a zero-radius sphere at the origin.
|
|
16
|
+
*/
|
|
17
|
+
export declare function create(cx?: number, cy?: number, cz?: number, radius?: number): Sphere;
|
|
18
|
+
/**
|
|
19
|
+
* Grow the sphere so `point` lies inside (boundary inclusive). Returns `out`.
|
|
20
|
+
*
|
|
21
|
+
* If the sphere was empty (radius < 0) the call re-seeds the center to `point`
|
|
22
|
+
* with radius 0. Otherwise the radius is set to max(current, distance(center, point)).
|
|
23
|
+
*/
|
|
24
|
+
export declare function expandByPoint(out: Sphere, point: Vec3Like): Sphere;
|
|
25
|
+
/**
|
|
26
|
+
* True when `point` is inside `sphere` (boundary inclusive). Empty sphere
|
|
27
|
+
* (radius < 0) contains nothing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function containsPoint(s: SphereLike, point: Vec3Like): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* True when `sphere` overlaps `box` (boundary inclusive). Uses the standard
|
|
32
|
+
* closest-point-on-AABB distance test.
|
|
33
|
+
*/
|
|
34
|
+
export declare function intersectsBox(s: SphereLike, b: box3.Box3Like): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Build an enclosing sphere from `points` via AABB-center + max-distance
|
|
37
|
+
* approximation. Empty `points` leaves the negative-radius empty sphere at
|
|
38
|
+
* the origin.
|
|
39
|
+
*/
|
|
40
|
+
export declare function fromPoints(out: Sphere, points: readonly Vec3Like[]): Sphere;
|
|
41
|
+
//# sourceMappingURL=sphere.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphere.d.ts","sourceRoot":"","sources":["../src/sphere.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAE3C;;GAEG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAI,EAAE,EAAE,SAAI,EAAE,EAAE,SAAI,EAAE,MAAM,SAAI,GAAG,MAAM,CAEjE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,CAkBlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAOrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAmBtE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CA6B3E"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** 2D vector storage: Float32Array length 2, brand=__vec2. */
|
|
2
|
+
export type Vec2 = Float32Array & {
|
|
3
|
+
readonly __vec2: void;
|
|
4
|
+
};
|
|
5
|
+
/** 3D vector storage: Float32Array length 3, brand=__vec3. */
|
|
6
|
+
export type Vec3 = Float32Array & {
|
|
7
|
+
readonly __vec3: void;
|
|
8
|
+
};
|
|
9
|
+
/** 4D vector / homogeneous coordinate storage: Float32Array length 4, brand=__vec4. */
|
|
10
|
+
export type Vec4 = Float32Array & {
|
|
11
|
+
readonly __vec4: void;
|
|
12
|
+
};
|
|
13
|
+
/** Quaternion storage: Float32Array length 4 [x,y,z,w], brand=__quat (mutually exclusive with Vec4). */
|
|
14
|
+
export type Quat = Float32Array & {
|
|
15
|
+
readonly __quat: void;
|
|
16
|
+
};
|
|
17
|
+
/** 3x3 matrix storage: Float32Array length 9 packed layout (D-P4); column-major (toGpuLayout hook reserved). */
|
|
18
|
+
export type Mat3 = Float32Array & {
|
|
19
|
+
readonly __mat3: void;
|
|
20
|
+
};
|
|
21
|
+
/** 4x4 matrix storage: Float32Array length 16 column-major, brand=__mat4. */
|
|
22
|
+
export type Mat4 = Float32Array & {
|
|
23
|
+
readonly __mat4: void;
|
|
24
|
+
};
|
|
25
|
+
/** Linear-space RGBA color: Float32Array length 4 [r,g,b,a] ∈ [0,1], brand=__color (mutually exclusive with Vec4). */
|
|
26
|
+
export type Color = Float32Array & {
|
|
27
|
+
readonly __color: void;
|
|
28
|
+
};
|
|
29
|
+
/** Euler angle: enum of six intrinsic rotation orders (D-P19). */
|
|
30
|
+
export type EulerOrder = 'XYZ' | 'YXZ' | 'ZXY' | 'ZYX' | 'YZX' | 'XZY';
|
|
31
|
+
/**
|
|
32
|
+
* Euler angle interface: x/y/z radians + order rotation order.
|
|
33
|
+
*
|
|
34
|
+
* Not a Float32Array because length=3 plus a string order needs plain-object storage;
|
|
35
|
+
* performance-insensitive (euler is only used at editor/IO boundary; runtime always converts to Quat).
|
|
36
|
+
*/
|
|
37
|
+
export interface Euler {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
z: number;
|
|
41
|
+
order: EulerOrder;
|
|
42
|
+
}
|
|
43
|
+
/** Vec2 readable input: ArrayLike<number> of length 2. */
|
|
44
|
+
export type Vec2Like = ArrayLike<number>;
|
|
45
|
+
/** Vec3 readable input: ArrayLike<number> of length 3. */
|
|
46
|
+
export type Vec3Like = ArrayLike<number>;
|
|
47
|
+
/** Vec4 readable input: ArrayLike<number> of length 4. */
|
|
48
|
+
export type Vec4Like = ArrayLike<number>;
|
|
49
|
+
/** Quat readable input: ArrayLike<number> of length 4. */
|
|
50
|
+
export type QuatLike = ArrayLike<number>;
|
|
51
|
+
/** Mat3 readable input: ArrayLike<number> of length 9. */
|
|
52
|
+
export type Mat3Like = ArrayLike<number>;
|
|
53
|
+
/** Mat4 readable input: ArrayLike<number> of length 16. */
|
|
54
|
+
export type Mat4Like = ArrayLike<number>;
|
|
55
|
+
/** Color readable input: ArrayLike<number> of length 4. */
|
|
56
|
+
export type ColorLike = ArrayLike<number>;
|
|
57
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAmBA,8DAA8D;AAC9D,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,8DAA8D;AAC9D,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,uFAAuF;AACvF,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,wGAAwG;AACxG,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,gHAAgH;AAChH,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,6EAA6E;AAC7E,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAE5D,sHAAsH;AACtH,MAAM,MAAM,KAAK,GAAG,YAAY,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC;AAI9D,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,UAAU,CAAC;CACnB;AAQD,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,2DAA2D;AAC3D,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AACzC,2DAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC"}
|