@woosh/meep-engine 2.152.0 → 2.154.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.
- package/package.json +1 -1
- package/src/core/color/Color.d.ts +26 -6
- package/src/core/color/Color.d.ts.map +1 -1
- package/src/core/color/Color.js +38 -6
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +112 -0
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/ConvexHullShape3D.js +325 -0
- package/src/engine/graphics/ecs/trail2d/Trail2D.d.ts +4 -0
- package/src/engine/graphics/ecs/trail2d/Trail2D.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail2d/Trail2D.js +21 -0
- package/src/engine/physics/PLAN.md +4 -4
- package/src/engine/physics/body/BodyStorage.d.ts +3 -1
- package/src/engine/physics/body/BodyStorage.d.ts.map +1 -1
- package/src/engine/physics/body/BodyStorage.js +452 -450
- package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
- package/src/engine/physics/body/SolverBodyState.js +6 -5
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +9 -1
- package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
- package/src/engine/physics/ccd/linear_sweep.js +237 -238
- package/src/engine/physics/computeInterceptPoint.d.ts.map +1 -1
- package/src/engine/physics/computeInterceptPoint.js +8 -3
- package/src/engine/physics/contact/ManifoldStore.d.ts +0 -16
- package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
- package/src/engine/physics/contact/ManifoldStore.js +1 -38
- package/src/engine/physics/ecs/BodyKind.d.ts +3 -2
- package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -1
- package/src/engine/physics/ecs/BodyKind.js +25 -24
- package/src/engine/physics/ecs/PhysicsEvents.d.ts +4 -5
- package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsEvents.js +15 -16
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +5 -30
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +13 -45
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -1
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +85 -81
- package/src/engine/physics/ecs/is_sensor.d.ts +18 -0
- package/src/engine/physics/ecs/is_sensor.d.ts.map +1 -0
- package/src/engine/physics/ecs/is_sensor.js +27 -0
- package/src/engine/physics/events/ContactEventBuffer.d.ts +2 -1
- package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -1
- package/src/engine/physics/events/ContactEventBuffer.js +84 -83
- package/src/engine/physics/gjk/gjk.d.ts +0 -26
- package/src/engine/physics/gjk/gjk.d.ts.map +1 -1
- package/src/engine/physics/gjk/gjk.js +3 -52
- package/src/engine/physics/gjk/gjk_epa_penetration.d.ts +16 -0
- package/src/engine/physics/gjk/gjk_epa_penetration.d.ts.map +1 -0
- package/src/engine/physics/gjk/gjk_epa_penetration.js +255 -0
- package/src/engine/physics/gjk/minkowski_support.d.ts +4 -9
- package/src/engine/physics/gjk/minkowski_support.d.ts.map +1 -1
- package/src/engine/physics/gjk/minkowski_support.js +70 -75
- package/src/engine/physics/gjk/mpr.d.ts +1 -1
- package/src/engine/physics/gjk/mpr.d.ts.map +1 -1
- package/src/engine/physics/gjk/mpr.js +362 -344
- package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
- package/src/engine/physics/island/IslandBuilder.js +431 -428
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_box_manifold.js +4 -81
- package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/box_triangle_contact.js +4 -39
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/capsule_contacts.js +459 -462
- package/src/engine/physics/narrowphase/clip_against_axis_uv.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/clip_against_axis_uv.js +4 -1
- package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts +83 -0
- package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/convex_convex_manifold.js +425 -0
- package/src/engine/physics/narrowphase/convex_decomposition.d.ts +32 -0
- package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/convex_decomposition.js +293 -0
- package/src/engine/physics/narrowphase/mesh_convex_hull.d.ts +41 -0
- package/src/engine/physics/narrowphase/mesh_convex_hull.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/mesh_convex_hull.js +106 -0
- package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.d.ts +8 -0
- package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +105 -102
- package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts +29 -0
- package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +69 -0
- package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_concave.js +152 -145
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/sphere_box_contact.js +132 -123
- package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
- package/src/engine/physics/queries/overlap_shape.js +16 -17
- package/src/engine/physics/queries/raycast.d.ts +5 -0
- package/src/engine/physics/queries/raycast.d.ts.map +1 -1
- package/src/engine/physics/queries/raycast.js +16 -8
- package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
- package/src/engine/physics/queries/shape_cast.js +13 -7
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
- package/src/engine/physics/solver/solve_contacts.js +8 -11
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
- package/src/engine/physics/vehicle/RaycastVehicle.js +339 -333
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts +0 -13
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +0 -1
- package/src/engine/physics/gjk/expanding_polytope_algorithm.js +0 -399
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Pure JavaScript game engine. Fully featured and production ready.",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"author": "Alexander Goldring",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.154.0",
|
|
10
10
|
"main": "build/meep.module.js",
|
|
11
11
|
"module": "build/meep.module.js",
|
|
12
12
|
"exports": {
|
|
@@ -61,27 +61,27 @@ export class Color {
|
|
|
61
61
|
static from_sRGB_to_linear(input: Color, output?: Color): Color;
|
|
62
62
|
/**
|
|
63
63
|
*
|
|
64
|
-
* @param {number} [r=0] Red from 0 to 1
|
|
65
|
-
* @param {number} [g=0] Green from 0 to 1
|
|
66
|
-
* @param {number} [b=0] Blue from 0 to 1
|
|
64
|
+
* @param {number} [r=0] Red from 0 to 1 for SDR
|
|
65
|
+
* @param {number} [g=0] Green from 0 to 1 for SDR
|
|
66
|
+
* @param {number} [b=0] Blue from 0 to 1 for SDR
|
|
67
67
|
* @param {number} [a=1] Alpha from 0 to 1 (transparency)
|
|
68
68
|
*/
|
|
69
69
|
constructor(r?: number, g?: number, b?: number, a?: number);
|
|
70
70
|
/**
|
|
71
71
|
* Red channel
|
|
72
|
-
* Value from 0 to 1
|
|
72
|
+
* Value from 0 to 1 for SDR
|
|
73
73
|
* @type {number}
|
|
74
74
|
*/
|
|
75
75
|
r: number;
|
|
76
76
|
/**
|
|
77
77
|
* Green channel
|
|
78
|
-
* Value from 0 to 1
|
|
78
|
+
* Value from 0 to 1 for SDR
|
|
79
79
|
* @type {number}
|
|
80
80
|
*/
|
|
81
81
|
g: number;
|
|
82
82
|
/**
|
|
83
83
|
* Blue channel
|
|
84
|
-
* Value from 0 to 1
|
|
84
|
+
* Value from 0 to 1 for SDR
|
|
85
85
|
* @type {number}
|
|
86
86
|
*/
|
|
87
87
|
b: number;
|
|
@@ -136,21 +136,41 @@ export class Color {
|
|
|
136
136
|
* @returns {number}
|
|
137
137
|
*/
|
|
138
138
|
get 3(): number;
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @param {number} v
|
|
142
|
+
*/
|
|
143
|
+
set x(arg: number);
|
|
139
144
|
/**
|
|
140
145
|
*
|
|
141
146
|
* @returns {number}
|
|
142
147
|
*/
|
|
143
148
|
get x(): number;
|
|
149
|
+
/**
|
|
150
|
+
*
|
|
151
|
+
* @param {number} v
|
|
152
|
+
*/
|
|
153
|
+
set y(arg: number);
|
|
144
154
|
/**
|
|
145
155
|
*
|
|
146
156
|
* @returns {number}
|
|
147
157
|
*/
|
|
148
158
|
get y(): number;
|
|
159
|
+
/**
|
|
160
|
+
*
|
|
161
|
+
* @param {number} v
|
|
162
|
+
*/
|
|
163
|
+
set z(arg: number);
|
|
149
164
|
/**
|
|
150
165
|
*
|
|
151
166
|
* @returns {number}
|
|
152
167
|
*/
|
|
153
168
|
get z(): number;
|
|
169
|
+
/**
|
|
170
|
+
*
|
|
171
|
+
* @param {number} v
|
|
172
|
+
*/
|
|
173
|
+
set w(arg: number);
|
|
154
174
|
/**
|
|
155
175
|
*
|
|
156
176
|
* @returns {number}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Color.d.ts","sourceRoot":"","sources":["../../../../src/core/color/Color.js"],"names":[],"mappings":"AAmBA;;;;;;;;GAQG;AACH;
|
|
1
|
+
{"version":3,"file":"Color.d.ts","sourceRoot":"","sources":["../../../../src/core/color/Color.js"],"names":[],"mappings":"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"}
|
package/src/core/color/Color.js
CHANGED
|
@@ -29,9 +29,9 @@ import { sRGB_to_linear } from "./sRGB/sRGB_to_linear.js";
|
|
|
29
29
|
export class Color {
|
|
30
30
|
/**
|
|
31
31
|
*
|
|
32
|
-
* @param {number} [r=0] Red from 0 to 1
|
|
33
|
-
* @param {number} [g=0] Green from 0 to 1
|
|
34
|
-
* @param {number} [b=0] Blue from 0 to 1
|
|
32
|
+
* @param {number} [r=0] Red from 0 to 1 for SDR
|
|
33
|
+
* @param {number} [g=0] Green from 0 to 1 for SDR
|
|
34
|
+
* @param {number} [b=0] Blue from 0 to 1 for SDR
|
|
35
35
|
* @param {number} [a=1] Alpha from 0 to 1 (transparency)
|
|
36
36
|
*/
|
|
37
37
|
constructor(r = 0, g = 0, b = 0, a = 1) {
|
|
@@ -42,19 +42,19 @@ export class Color {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Red channel
|
|
45
|
-
* Value from 0 to 1
|
|
45
|
+
* Value from 0 to 1 for SDR
|
|
46
46
|
* @type {number}
|
|
47
47
|
*/
|
|
48
48
|
this.r = r;
|
|
49
49
|
/**
|
|
50
50
|
* Green channel
|
|
51
|
-
* Value from 0 to 1
|
|
51
|
+
* Value from 0 to 1 for SDR
|
|
52
52
|
* @type {number}
|
|
53
53
|
*/
|
|
54
54
|
this.g = g;
|
|
55
55
|
/**
|
|
56
56
|
* Blue channel
|
|
57
|
-
* Value from 0 to 1
|
|
57
|
+
* Value from 0 to 1 for SDR
|
|
58
58
|
* @type {number}
|
|
59
59
|
*/
|
|
60
60
|
this.b = b;
|
|
@@ -147,6 +147,14 @@ export class Color {
|
|
|
147
147
|
return this.r;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
*
|
|
152
|
+
* @param {number} v
|
|
153
|
+
*/
|
|
154
|
+
set x(v) {
|
|
155
|
+
this.r = v;
|
|
156
|
+
}
|
|
157
|
+
|
|
150
158
|
/**
|
|
151
159
|
*
|
|
152
160
|
* @returns {number}
|
|
@@ -155,6 +163,14 @@ export class Color {
|
|
|
155
163
|
return this.g;
|
|
156
164
|
}
|
|
157
165
|
|
|
166
|
+
/**
|
|
167
|
+
*
|
|
168
|
+
* @param {number} v
|
|
169
|
+
*/
|
|
170
|
+
set y(v) {
|
|
171
|
+
this.g = v;
|
|
172
|
+
}
|
|
173
|
+
|
|
158
174
|
/**
|
|
159
175
|
*
|
|
160
176
|
* @returns {number}
|
|
@@ -163,6 +179,14 @@ export class Color {
|
|
|
163
179
|
return this.b;
|
|
164
180
|
}
|
|
165
181
|
|
|
182
|
+
/**
|
|
183
|
+
*
|
|
184
|
+
* @param {number} v
|
|
185
|
+
*/
|
|
186
|
+
set z(v) {
|
|
187
|
+
this.b = v;
|
|
188
|
+
}
|
|
189
|
+
|
|
166
190
|
/**
|
|
167
191
|
*
|
|
168
192
|
* @returns {number}
|
|
@@ -171,6 +195,14 @@ export class Color {
|
|
|
171
195
|
return this.a;
|
|
172
196
|
}
|
|
173
197
|
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* @param {number} v
|
|
201
|
+
*/
|
|
202
|
+
set w(v) {
|
|
203
|
+
this.a = v;
|
|
204
|
+
}
|
|
205
|
+
|
|
174
206
|
/**
|
|
175
207
|
* Pretending to be an array
|
|
176
208
|
* @return {number}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convex polyhedron collider.
|
|
3
|
+
*
|
|
4
|
+
* Holds a convex triangle surface (`vertices` + outward-CCW `indices`) and the
|
|
5
|
+
* derived face half-spaces. Because it is convex (`is_convex === true`, the
|
|
6
|
+
* default), it routes straight through the narrowphase's GJK + EPA path via
|
|
7
|
+
* {@link support} — no tetrahedralisation, no per-triangle decomposition, no
|
|
8
|
+
* BVH. This is the right shape for authored convex geometry (props, crates,
|
|
9
|
+
* gems, low-poly rocks, an icosphere) and is far cheaper to construct than
|
|
10
|
+
* {@link MeshShape3D}, which tetrahedralises its interior.
|
|
11
|
+
*
|
|
12
|
+
* Contract:
|
|
13
|
+
* - `support` is exact for any convex point set (deepest vertex along the
|
|
14
|
+
* direction) — the precondition GJK relies on.
|
|
15
|
+
* - `contains_point` is the convex half-space test (behind every face plane).
|
|
16
|
+
* - `signed_distance` / `nearest_point_on_surface` scan the surface triangles
|
|
17
|
+
* (O(F)); these are query-path helpers, not on the collision hot path.
|
|
18
|
+
*
|
|
19
|
+
* The input is assumed convex with outward-facing CCW winding — build it via
|
|
20
|
+
* {@link ConvexHullShape3D.from}. A genuine non-convex mesh belongs in
|
|
21
|
+
* {@link MeshShape3D} (and, once decomposition lands, will be represented as a
|
|
22
|
+
* set of these pieces).
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
export class ConvexHullShape3D extends AbstractShape3D {
|
|
28
|
+
/**
|
|
29
|
+
* Build from a convex triangle surface. Vertices must lie on the hull and
|
|
30
|
+
* faces must wind CCW when viewed from outside.
|
|
31
|
+
*
|
|
32
|
+
* @param {Float32Array} vertices flat `(x, y, z)` per vertex
|
|
33
|
+
* @param {Uint32Array} indices three uint32 per triangle, outward CCW
|
|
34
|
+
* @returns {ConvexHullShape3D}
|
|
35
|
+
*/
|
|
36
|
+
static from(vertices: Float32Array, indices: Uint32Array): ConvexHullShape3D;
|
|
37
|
+
/**
|
|
38
|
+
* Hull vertex positions, flat `(x, y, z)` per vertex, in the body's
|
|
39
|
+
* local frame. Fed to {@link support}.
|
|
40
|
+
* @type {Float32Array}
|
|
41
|
+
*/
|
|
42
|
+
vertices: Float32Array;
|
|
43
|
+
/**
|
|
44
|
+
* Surface triangle indices, three uint32 per face (outward CCW). Used by
|
|
45
|
+
* the surface-scan query helpers (signed distance / nearest point).
|
|
46
|
+
* @type {Uint32Array}
|
|
47
|
+
*/
|
|
48
|
+
indices: Uint32Array;
|
|
49
|
+
/**
|
|
50
|
+
* Polygon-face representation for the contact clipper (CSR): face `f`'s
|
|
51
|
+
* vertex loop is `face_loops[face_offsets[f] .. face_offsets[f+1]]`,
|
|
52
|
+
* ordered CCW (outward). Currently one triangle per face; a coplanar-merge
|
|
53
|
+
* pass will collapse coplanar triangles into larger polygon faces.
|
|
54
|
+
* @type {Uint32Array}
|
|
55
|
+
*/
|
|
56
|
+
face_offsets: Uint32Array;
|
|
57
|
+
/** @type {Uint32Array} */
|
|
58
|
+
face_loops: Uint32Array;
|
|
59
|
+
/**
|
|
60
|
+
* Face half-spaces, four doubles per face `(nx, ny, nz, d)` with unit
|
|
61
|
+
* outward normal and `d = n · v` — point is inside iff `n · p − d ≤ 0`
|
|
62
|
+
* for every face. Derived in {@link recompute}.
|
|
63
|
+
* @private
|
|
64
|
+
* @type {Float64Array}
|
|
65
|
+
*/
|
|
66
|
+
private __planes;
|
|
67
|
+
/** @private @type {Float64Array} */
|
|
68
|
+
private __bbox;
|
|
69
|
+
/** @private @type {number} */
|
|
70
|
+
private __volume;
|
|
71
|
+
/** @private @type {number} */
|
|
72
|
+
private __surface_area;
|
|
73
|
+
/**
|
|
74
|
+
* Refresh the cached bbox / face planes / volume / surface area from the
|
|
75
|
+
* current `vertices` / `indices`.
|
|
76
|
+
*/
|
|
77
|
+
recompute(): void;
|
|
78
|
+
compute_bounding_box(result: any): void;
|
|
79
|
+
/**
|
|
80
|
+
* GJK support: the hull vertex furthest along the direction. Exact for a
|
|
81
|
+
* convex point set. Linear scan over the vertices — fine for the modest
|
|
82
|
+
* vertex counts of authored hulls; a hill-climb over vertex adjacency is
|
|
83
|
+
* the acceleration for very large hulls.
|
|
84
|
+
*/
|
|
85
|
+
support(result: any, result_offset: any, direction_x: any, direction_y: any, direction_z: any): void;
|
|
86
|
+
/**
|
|
87
|
+
* Convex half-space test: inside iff the point is behind (or on) every face
|
|
88
|
+
* plane. Exact for a convex polytope.
|
|
89
|
+
*/
|
|
90
|
+
contains_point(point: any): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Unsigned nearest-surface distance via a per-triangle scan, signed by
|
|
93
|
+
* {@link contains_point}. Same approach as {@link MeshShape3D}; O(F).
|
|
94
|
+
*/
|
|
95
|
+
signed_distance_at_point(point: any): number;
|
|
96
|
+
signed_distance_gradient_at_point(result: any, point: any): number;
|
|
97
|
+
nearest_point_on_surface(result: any, reference: any): void;
|
|
98
|
+
sample_random_point_in_volume(result: any, result_offset: any, random: any): void;
|
|
99
|
+
/**
|
|
100
|
+
* @param {ConvexHullShape3D} other
|
|
101
|
+
* @returns {boolean}
|
|
102
|
+
*/
|
|
103
|
+
equals(other: ConvexHullShape3D): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Fast type-check marker.
|
|
106
|
+
* @readonly
|
|
107
|
+
* @type {boolean}
|
|
108
|
+
*/
|
|
109
|
+
readonly isConvexHullShape3D: boolean;
|
|
110
|
+
}
|
|
111
|
+
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
112
|
+
//# sourceMappingURL=ConvexHullShape3D.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConvexHullShape3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/ConvexHullShape3D.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IA+CI;;;;;;;OAOG;IACH,sBAJW,YAAY,WACZ,WAAW,GACT,iBAAiB,CAQ7B;IAxDG;;;;OAIG;IACH,UAFU,YAAY,CAEa;IAEnC;;;;OAIG;IACH,SAFU,WAAW,CAEY;IAEjC;;;;;;OAMG;IACH,cAFU,WAAW,CAEiB;IACtC,0BAA0B;IAC1B,YADW,WAAW,CACc;IAEpC;;;;;;OAMG;IACH,iBAAmC;IAEnC,oCAAoC;IACpC,eAAiC;IACjC,8BAA8B;IAC9B,iBAAiB;IACjB,8BAA8B;IAC9B,uBAAuB;IAmB3B;;;OAGG;IACH,kBAmDC;IAKD,wCAIC;IAED;;;;;OAKG;IACH,qGAgBC;IAED;;;OAGG;IACH,oCAgBC;IAED;;;OAGG;IACH,6CAwBC;IAED,mEAEC;IAED,4DAwBC;IAED,kFAmBC;IAED;;;OAGG;IACH,cAHW,iBAAiB,GACf,OAAO,CAanB;IAcL;;;;OAIG;IACH,8BAFU,OAAO,CAE8B;CAP9C;gCAxT+B,sBAAsB"}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { computeHashFloat } from "../../../primitives/numbers/computeHashFloat.js";
|
|
2
|
+
import { computeTriangleClosestPointToPointBarycentric } from "../triangle/computeTriangleClosestPointToPointBarycentric.js";
|
|
3
|
+
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
4
|
+
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Convex polyhedron collider.
|
|
8
|
+
*
|
|
9
|
+
* Holds a convex triangle surface (`vertices` + outward-CCW `indices`) and the
|
|
10
|
+
* derived face half-spaces. Because it is convex (`is_convex === true`, the
|
|
11
|
+
* default), it routes straight through the narrowphase's GJK + EPA path via
|
|
12
|
+
* {@link support} — no tetrahedralisation, no per-triangle decomposition, no
|
|
13
|
+
* BVH. This is the right shape for authored convex geometry (props, crates,
|
|
14
|
+
* gems, low-poly rocks, an icosphere) and is far cheaper to construct than
|
|
15
|
+
* {@link MeshShape3D}, which tetrahedralises its interior.
|
|
16
|
+
*
|
|
17
|
+
* Contract:
|
|
18
|
+
* - `support` is exact for any convex point set (deepest vertex along the
|
|
19
|
+
* direction) — the precondition GJK relies on.
|
|
20
|
+
* - `contains_point` is the convex half-space test (behind every face plane).
|
|
21
|
+
* - `signed_distance` / `nearest_point_on_surface` scan the surface triangles
|
|
22
|
+
* (O(F)); these are query-path helpers, not on the collision hot path.
|
|
23
|
+
*
|
|
24
|
+
* The input is assumed convex with outward-facing CCW winding — build it via
|
|
25
|
+
* {@link ConvexHullShape3D.from}. A genuine non-convex mesh belongs in
|
|
26
|
+
* {@link MeshShape3D} (and, once decomposition lands, will be represented as a
|
|
27
|
+
* set of these pieces).
|
|
28
|
+
*
|
|
29
|
+
* @author Alex Goldring
|
|
30
|
+
* @copyright Company Named Limited (c) 2026
|
|
31
|
+
*/
|
|
32
|
+
export class ConvexHullShape3D extends AbstractShape3D {
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
super();
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Hull vertex positions, flat `(x, y, z)` per vertex, in the body's
|
|
39
|
+
* local frame. Fed to {@link support}.
|
|
40
|
+
* @type {Float32Array}
|
|
41
|
+
*/
|
|
42
|
+
this.vertices = new Float32Array(0);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Surface triangle indices, three uint32 per face (outward CCW). Used by
|
|
46
|
+
* the surface-scan query helpers (signed distance / nearest point).
|
|
47
|
+
* @type {Uint32Array}
|
|
48
|
+
*/
|
|
49
|
+
this.indices = new Uint32Array(0);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Polygon-face representation for the contact clipper (CSR): face `f`'s
|
|
53
|
+
* vertex loop is `face_loops[face_offsets[f] .. face_offsets[f+1]]`,
|
|
54
|
+
* ordered CCW (outward). Currently one triangle per face; a coplanar-merge
|
|
55
|
+
* pass will collapse coplanar triangles into larger polygon faces.
|
|
56
|
+
* @type {Uint32Array}
|
|
57
|
+
*/
|
|
58
|
+
this.face_offsets = new Uint32Array(0);
|
|
59
|
+
/** @type {Uint32Array} */
|
|
60
|
+
this.face_loops = new Uint32Array(0);
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Face half-spaces, four doubles per face `(nx, ny, nz, d)` with unit
|
|
64
|
+
* outward normal and `d = n · v` — point is inside iff `n · p − d ≤ 0`
|
|
65
|
+
* for every face. Derived in {@link recompute}.
|
|
66
|
+
* @private
|
|
67
|
+
* @type {Float64Array}
|
|
68
|
+
*/
|
|
69
|
+
this.__planes = new Float64Array(0);
|
|
70
|
+
|
|
71
|
+
/** @private @type {Float64Array} */
|
|
72
|
+
this.__bbox = new Float64Array(6);
|
|
73
|
+
/** @private @type {number} */
|
|
74
|
+
this.__volume = 0;
|
|
75
|
+
/** @private @type {number} */
|
|
76
|
+
this.__surface_area = 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Build from a convex triangle surface. Vertices must lie on the hull and
|
|
81
|
+
* faces must wind CCW when viewed from outside.
|
|
82
|
+
*
|
|
83
|
+
* @param {Float32Array} vertices flat `(x, y, z)` per vertex
|
|
84
|
+
* @param {Uint32Array} indices three uint32 per triangle, outward CCW
|
|
85
|
+
* @returns {ConvexHullShape3D}
|
|
86
|
+
*/
|
|
87
|
+
static from(vertices, indices) {
|
|
88
|
+
const s = new ConvexHullShape3D();
|
|
89
|
+
s.vertices = vertices;
|
|
90
|
+
s.indices = indices;
|
|
91
|
+
s.recompute();
|
|
92
|
+
return s;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Refresh the cached bbox / face planes / volume / surface area from the
|
|
97
|
+
* current `vertices` / `indices`.
|
|
98
|
+
*/
|
|
99
|
+
recompute() {
|
|
100
|
+
const v = this.vertices;
|
|
101
|
+
const idx = this.indices;
|
|
102
|
+
|
|
103
|
+
let mnx = Infinity, mny = Infinity, mnz = Infinity;
|
|
104
|
+
let mxx = -Infinity, mxy = -Infinity, mxz = -Infinity;
|
|
105
|
+
const vc = v.length / 3;
|
|
106
|
+
for (let i = 0; i < vc; i++) {
|
|
107
|
+
const x = v[i * 3], y = v[i * 3 + 1], z = v[i * 3 + 2];
|
|
108
|
+
if (x < mnx) mnx = x; if (x > mxx) mxx = x;
|
|
109
|
+
if (y < mny) mny = y; if (y > mxy) mxy = y;
|
|
110
|
+
if (z < mnz) mnz = z; if (z > mxz) mxz = z;
|
|
111
|
+
}
|
|
112
|
+
if (vc === 0) { mnx = mny = mnz = mxx = mxy = mxz = 0; }
|
|
113
|
+
const b = this.__bbox;
|
|
114
|
+
b[0] = mnx; b[1] = mny; b[2] = mnz; b[3] = mxx; b[4] = mxy; b[5] = mxz;
|
|
115
|
+
|
|
116
|
+
const tri = idx.length / 3;
|
|
117
|
+
const planes = new Float64Array(tri * 4);
|
|
118
|
+
let area = 0;
|
|
119
|
+
let vol6 = 0; // 6× the signed volume (Σ a·(b×c) over outward faces)
|
|
120
|
+
for (let f = 0; f < tri; f++) {
|
|
121
|
+
const ia = idx[f * 3] * 3, ib = idx[f * 3 + 1] * 3, ic = idx[f * 3 + 2] * 3;
|
|
122
|
+
const ax = v[ia], ay = v[ia + 1], az = v[ia + 2];
|
|
123
|
+
const bx = v[ib], by = v[ib + 1], bz = v[ib + 2];
|
|
124
|
+
const cx = v[ic], cy = v[ic + 1], cz = v[ic + 2];
|
|
125
|
+
|
|
126
|
+
const e1x = bx - ax, e1y = by - ay, e1z = bz - az;
|
|
127
|
+
const e2x = cx - ax, e2y = cy - ay, e2z = cz - az;
|
|
128
|
+
let nx = e1y * e2z - e1z * e2y;
|
|
129
|
+
let ny = e1z * e2x - e1x * e2z;
|
|
130
|
+
let nz = e1x * e2y - e1y * e2x;
|
|
131
|
+
const len = Math.sqrt(nx * nx + ny * ny + nz * nz) || 1;
|
|
132
|
+
area += 0.5 * len;
|
|
133
|
+
vol6 += ax * (by * cz - bz * cy) + ay * (bz * cx - bx * cz) + az * (bx * cy - by * cx);
|
|
134
|
+
|
|
135
|
+
nx /= len; ny /= len; nz /= len;
|
|
136
|
+
const o = f * 4;
|
|
137
|
+
planes[o] = nx; planes[o + 1] = ny; planes[o + 2] = nz;
|
|
138
|
+
planes[o + 3] = nx * ax + ny * ay + nz * az;
|
|
139
|
+
}
|
|
140
|
+
this.__planes = planes;
|
|
141
|
+
this.__surface_area = area;
|
|
142
|
+
this.__volume = Math.abs(vol6) / 6;
|
|
143
|
+
|
|
144
|
+
// Polygon faces for the clipper. v1: one triangle per face (the contact
|
|
145
|
+
// clipper consumes polygon loops; a tetrahedral piece is exactly this).
|
|
146
|
+
const fo = new Uint32Array(tri + 1);
|
|
147
|
+
for (let f = 0; f <= tri; f++) fo[f] = f * 3;
|
|
148
|
+
this.face_offsets = fo;
|
|
149
|
+
this.face_loops = idx;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
get volume() { return this.__volume; }
|
|
153
|
+
get surface_area() { return this.__surface_area; }
|
|
154
|
+
|
|
155
|
+
compute_bounding_box(result) {
|
|
156
|
+
const b = this.__bbox;
|
|
157
|
+
result[0] = b[0]; result[1] = b[1]; result[2] = b[2];
|
|
158
|
+
result[3] = b[3]; result[4] = b[4]; result[5] = b[5];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* GJK support: the hull vertex furthest along the direction. Exact for a
|
|
163
|
+
* convex point set. Linear scan over the vertices — fine for the modest
|
|
164
|
+
* vertex counts of authored hulls; a hill-climb over vertex adjacency is
|
|
165
|
+
* the acceleration for very large hulls.
|
|
166
|
+
*/
|
|
167
|
+
support(result, result_offset, direction_x, direction_y, direction_z) {
|
|
168
|
+
const v = this.vertices;
|
|
169
|
+
const vc = v.length / 3;
|
|
170
|
+
if (vc === 0) {
|
|
171
|
+
result[result_offset] = 0; result[result_offset + 1] = 0; result[result_offset + 2] = 0;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let best = -Infinity;
|
|
175
|
+
let bi = 0;
|
|
176
|
+
for (let i = 0; i < vc; i++) {
|
|
177
|
+
const d = direction_x * v[i * 3] + direction_y * v[i * 3 + 1] + direction_z * v[i * 3 + 2];
|
|
178
|
+
if (d > best) { best = d; bi = i; }
|
|
179
|
+
}
|
|
180
|
+
result[result_offset] = v[bi * 3];
|
|
181
|
+
result[result_offset + 1] = v[bi * 3 + 1];
|
|
182
|
+
result[result_offset + 2] = v[bi * 3 + 2];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Convex half-space test: inside iff the point is behind (or on) every face
|
|
187
|
+
* plane. Exact for a convex polytope.
|
|
188
|
+
*/
|
|
189
|
+
contains_point(point) {
|
|
190
|
+
const px = point[0], py = point[1], pz = point[2];
|
|
191
|
+
const b = this.__bbox;
|
|
192
|
+
if (px < b[0] || py < b[1] || pz < b[2] || px > b[3] || py > b[4] || pz > b[5]) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const planes = this.__planes;
|
|
196
|
+
const f = planes.length / 4;
|
|
197
|
+
const EPS = 1e-6;
|
|
198
|
+
for (let i = 0; i < f; i++) {
|
|
199
|
+
const o = i * 4;
|
|
200
|
+
if (planes[o] * px + planes[o + 1] * py + planes[o + 2] * pz - planes[o + 3] > EPS) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Unsigned nearest-surface distance via a per-triangle scan, signed by
|
|
209
|
+
* {@link contains_point}. Same approach as {@link MeshShape3D}; O(F).
|
|
210
|
+
*/
|
|
211
|
+
signed_distance_at_point(point) {
|
|
212
|
+
const v = this.vertices;
|
|
213
|
+
const idx = this.indices;
|
|
214
|
+
const tri = idx.length / 3;
|
|
215
|
+
const px = point[0], py = point[1], pz = point[2];
|
|
216
|
+
|
|
217
|
+
let best_d2 = Infinity;
|
|
218
|
+
const baryc = scratch_barycentric;
|
|
219
|
+
for (let i = 0; i < tri; i++) {
|
|
220
|
+
const ia = idx[i * 3] * 3, ib = idx[i * 3 + 1] * 3, ic = idx[i * 3 + 2] * 3;
|
|
221
|
+
const ax = v[ia], ay = v[ia + 1], az = v[ia + 2];
|
|
222
|
+
const bx = v[ib], by = v[ib + 1], bz = v[ib + 2];
|
|
223
|
+
const cx = v[ic], cy = v[ic + 1], cz = v[ic + 2];
|
|
224
|
+
computeTriangleClosestPointToPointBarycentric(baryc, 0, px, py, pz, ax, ay, az, bx, by, bz, cx, cy, cz);
|
|
225
|
+
const u = baryc[0], w = baryc[1], t = 1 - u - w;
|
|
226
|
+
const qx = u * ax + w * bx + t * cx;
|
|
227
|
+
const qy = u * ay + w * by + t * cy;
|
|
228
|
+
const qz = u * az + w * bz + t * cz;
|
|
229
|
+
const dx = qx - px, dy = qy - py, dz = qz - pz;
|
|
230
|
+
const d2 = dx * dx + dy * dy + dz * dz;
|
|
231
|
+
if (d2 < best_d2) best_d2 = d2;
|
|
232
|
+
}
|
|
233
|
+
const dist = Math.sqrt(best_d2);
|
|
234
|
+
return this.contains_point(point) ? -dist : dist;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
signed_distance_gradient_at_point(result, point) {
|
|
238
|
+
return compute_signed_distance_gradient_by_sampling(result, this, point);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
nearest_point_on_surface(result, reference) {
|
|
242
|
+
const v = this.vertices;
|
|
243
|
+
const idx = this.indices;
|
|
244
|
+
const tri = idx.length / 3;
|
|
245
|
+
const px = reference[0], py = reference[1], pz = reference[2];
|
|
246
|
+
|
|
247
|
+
let best_d2 = Infinity;
|
|
248
|
+
let bx_ = 0, by_ = 0, bz_ = 0;
|
|
249
|
+
const baryc = scratch_barycentric;
|
|
250
|
+
for (let i = 0; i < tri; i++) {
|
|
251
|
+
const ia = idx[i * 3] * 3, ib = idx[i * 3 + 1] * 3, ic = idx[i * 3 + 2] * 3;
|
|
252
|
+
const ax = v[ia], ay = v[ia + 1], az = v[ia + 2];
|
|
253
|
+
const bx = v[ib], by = v[ib + 1], bz = v[ib + 2];
|
|
254
|
+
const cx = v[ic], cy = v[ic + 1], cz = v[ic + 2];
|
|
255
|
+
computeTriangleClosestPointToPointBarycentric(baryc, 0, px, py, pz, ax, ay, az, bx, by, bz, cx, cy, cz);
|
|
256
|
+
const u = baryc[0], w = baryc[1], t = 1 - u - w;
|
|
257
|
+
const qx = u * ax + w * bx + t * cx;
|
|
258
|
+
const qy = u * ay + w * by + t * cy;
|
|
259
|
+
const qz = u * az + w * bz + t * cz;
|
|
260
|
+
const dx = qx - px, dy = qy - py, dz = qz - pz;
|
|
261
|
+
const d2 = dx * dx + dy * dy + dz * dz;
|
|
262
|
+
if (d2 < best_d2) { best_d2 = d2; bx_ = qx; by_ = qy; bz_ = qz; }
|
|
263
|
+
}
|
|
264
|
+
result[0] = bx_; result[1] = by_; result[2] = bz_;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
sample_random_point_in_volume(result, result_offset, random) {
|
|
268
|
+
const b = this.__bbox;
|
|
269
|
+
const lx = b[0], ly = b[1], lz = b[2];
|
|
270
|
+
const sx = b[3] - b[0], sy = b[4] - b[1], sz = b[5] - b[2];
|
|
271
|
+
const probe = scratch_point;
|
|
272
|
+
for (let attempt = 0; attempt < 256; attempt++) {
|
|
273
|
+
probe[0] = lx + random() * sx;
|
|
274
|
+
probe[1] = ly + random() * sy;
|
|
275
|
+
probe[2] = lz + random() * sz;
|
|
276
|
+
if (this.contains_point(probe)) {
|
|
277
|
+
result[result_offset] = probe[0];
|
|
278
|
+
result[result_offset + 1] = probe[1];
|
|
279
|
+
result[result_offset + 2] = probe[2];
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
result[result_offset] = lx + sx * 0.5;
|
|
284
|
+
result[result_offset + 1] = ly + sy * 0.5;
|
|
285
|
+
result[result_offset + 2] = lz + sz * 0.5;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* @param {ConvexHullShape3D} other
|
|
290
|
+
* @returns {boolean}
|
|
291
|
+
*/
|
|
292
|
+
equals(other) {
|
|
293
|
+
if (!super.equals(other)) return false;
|
|
294
|
+
if (this.vertices.length !== other.vertices.length) return false;
|
|
295
|
+
if (this.indices.length !== other.indices.length) return false;
|
|
296
|
+
for (let i = 0; i < this.vertices.length; i++) {
|
|
297
|
+
if (this.vertices[i] !== other.vertices[i]) return false;
|
|
298
|
+
}
|
|
299
|
+
for (let i = 0; i < this.indices.length; i++) {
|
|
300
|
+
if (this.indices[i] !== other.indices[i]) return false;
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
hash() {
|
|
306
|
+
const v_count = this.vertices.length / 3 | 0;
|
|
307
|
+
const t_count = this.indices.length / 3 | 0;
|
|
308
|
+
let h = (v_count * 31 + t_count) | 0;
|
|
309
|
+
if (this.vertices.length >= 3) {
|
|
310
|
+
h = (h * 31 + (computeHashFloat(this.vertices[0]))) | 0;
|
|
311
|
+
h = (h * 31 + (computeHashFloat(this.vertices[this.vertices.length - 1]))) | 0;
|
|
312
|
+
}
|
|
313
|
+
return h | 0;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Fast type-check marker.
|
|
319
|
+
* @readonly
|
|
320
|
+
* @type {boolean}
|
|
321
|
+
*/
|
|
322
|
+
ConvexHullShape3D.prototype.isConvexHullShape3D = true;
|
|
323
|
+
|
|
324
|
+
const scratch_barycentric = new Float64Array(2);
|
|
325
|
+
const scratch_point = new Float64Array(3);
|
|
@@ -90,6 +90,10 @@ declare class Trail2D {
|
|
|
90
90
|
*/
|
|
91
91
|
build(segment_count: number): void;
|
|
92
92
|
mesh: import("three").Mesh<import("three").BufferGeometry, import("three").Material | import("three").Material[]>;
|
|
93
|
+
/**
|
|
94
|
+
* Clear the trail's geometry and reset its state.
|
|
95
|
+
*/
|
|
96
|
+
clear(): void;
|
|
93
97
|
fromJSON({ maxAge, width, textureURL, offset, color }: {
|
|
94
98
|
maxAge?: number;
|
|
95
99
|
width?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Trail2D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2D.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Trail2D.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2D.js"],"names":[],"mappings":";AAoBA;IAsKI,oCAMC;IA1KD;;;OAGG;IACH,QAFU,MAAM,CAES;IAEzB;;;OAGG;IACH,OAFU,MAAM,CAEM;IAEtB;;;OAGG;IACH,MAFU,MAAM,CAEP;IAET;;;OAGG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,qBAFU,MAAM,CAEQ;IAExB;;;OAGG;IACH,gBAFU,KAAK,CAEe;IAE9B;;;;OAIG;IACH,iBAFU,OAAO,CAEM;IAEvB;;;OAGG;IACH,QAFU,OAAO,GAAC,IAAI,CAER;IAEd;;;OAGG;IACH,UAFU,mBAAmB,CAEQ;IAErC;;;OAGG;IACH,cAFU,SAAS,CAEG;IAEtB;;;OAGG;IACH,cAAsB;IAEtB,gBAQC;IAMD,4BAEC;IAND,yBAEC;IAMD;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,GACjB,IAAI,CAIhB;IAED;;;;OAIG;IACH,gBAHW,MAAM,GAAC,YAAY,SACnB,OAAO,QAQjB;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,YAAY,GACjB,OAAO,CAInB;IAED;;;OAGG;IACH,qBAFW,MAAM,QAehB;IADG,kHAAgB;IAGpB;;OAEG;IACH,cAeC;IAUD;;;;;;;;;;;aAcC;IAGD;;;;;;;;;;;;;;;MAQC;IAED;;;OAGG;IACH,cAFW,OAAO,WASjB;IAED;;;;;;;OAOG;IACH,cANW,MAAM,KACN,MAAM,KACN,MAAM,YACN,MAAM,GACJ,OAAO,CA2CnB;CAEJ;;;;;;sBA3RqB,iCAAiC;oBACnC,kCAAkC;wBAI9B,0BAA0B;oCACd,sCAAsC;0BAPhD,yCAAyC;6BAStC,mBAAmB;kCADd,wBAAwB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FLOAT32_MAX } from "../../../../core/binary/FLOAT32_MAX.js";
|
|
1
2
|
import { BvhClient } from "../../../../core/bvh2/bvh3/BvhClient.js";
|
|
2
3
|
import { Color } from "../../../../core/color/Color.js";
|
|
3
4
|
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
@@ -163,6 +164,26 @@ class Trail2D {
|
|
|
163
164
|
this.mesh = mesh;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Clear the trail's geometry and reset its state.
|
|
169
|
+
*/
|
|
170
|
+
clear() {
|
|
171
|
+
const ribbon = this.ribbon;
|
|
172
|
+
|
|
173
|
+
if (ribbon === null) {
|
|
174
|
+
// nothing to clear
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const n = ribbon.getCount();
|
|
179
|
+
|
|
180
|
+
for (let i = 0; i < n; i++) {
|
|
181
|
+
ribbon.setPointAttribute_Scalar(i, RIBBON_ATTRIBUTE_ADDRESS_AGE, FLOAT32_MAX);
|
|
182
|
+
ribbon.setPointAlpha(i, 0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
|
|
166
187
|
static fromJSON(json) {
|
|
167
188
|
const r = new Trail2D();
|
|
168
189
|
|