@woosh/meep-engine 3.25.0 → 3.26.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/geom/3d/shape/HeightMapShape3D.d.ts +59 -0
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +285 -0
- package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PosedShape3D.js +57 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +102 -0
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnionShape3D.js +64 -0
- package/src/engine/physics/cloth/MEASUREMENTS.md +582 -0
- package/src/engine/physics/cloth/PLAN.md +330 -49
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +84 -17
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +451 -42
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +65 -7
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +72 -8
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +25 -4
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +75 -8
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts +41 -4
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +207 -63
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts +10 -0
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/WorkerClothSystem.js +17 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +27 -3
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +28 -3
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +75 -10
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +131 -12
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +249 -201
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +21 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +62 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +18 -10
- package/src/engine/physics/cloth/playground/collide_main.js +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +29 -8
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +37 -9
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +12 -2
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +12 -2
- package/src/engine/physics/cloth/solver/cloth_step_instance.js +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +9 -2
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +9 -2
- package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts +23 -9
- package/src/engine/physics/cloth/wind/AbstractClothWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/AbstractClothWind.js +23 -9
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts +7 -5
- package/src/engine/physics/cloth/wind/ClothAmbientWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothAmbientWind.js +12 -9
- package/src/engine/physics/cloth/wind/ClothFluidWind.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/ClothFluidWind.js +5 -2
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts +7 -2
- package/src/engine/physics/cloth/wind/cloth_sample_air.d.ts.map +1 -1
- package/src/engine/physics/cloth/wind/cloth_sample_air.js +12 -5
|
@@ -23,11 +23,22 @@
|
|
|
23
23
|
*
|
|
24
24
|
* ## The query box
|
|
25
25
|
*
|
|
26
|
-
* The cloth's own particle bounds, fattened by
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
26
|
+
* The cloth's own particle bounds, fattened by exactly what
|
|
27
|
+
* `cloth_contact_find` will reach for — no more, because a broadphase that is
|
|
28
|
+
* wider than its narrowphase is collecting colliders it will then throw away.
|
|
29
|
+
* {@link cloth_gather_reach} is that quantity and carries the derivation.
|
|
30
|
+
*
|
|
31
|
+
* It used to be the velocity clamp of §7 P1 read as a distance. That was wrong
|
|
32
|
+
* in both directions at once. The clamp is `4 · shortest_row · substeps ·
|
|
33
|
+
* iterations`, which for a rope of 10 cm links at 2 × 4 is **3.2 m** a step —
|
|
34
|
+
* so the box was fattened by metres to catch motion measured in centimetres,
|
|
35
|
+
* and a garment in a crowd collected every bone in the street and overflowed
|
|
36
|
+
* its table. `cloth_contact_find`'s own docblock had already worked out that
|
|
37
|
+
* this clamp is "about 154 m/s … three orders of magnitude" past real cloth
|
|
38
|
+
* speed and stopped using it (§54); the gather kept it. And being enormous, it
|
|
39
|
+
* hid the fact that it was also **missing** two terms the narrowphase does
|
|
40
|
+
* reach with — collider inflation and the collider's own travel — so a wide
|
|
41
|
+
* enough inflation was a row the gather never handed over.
|
|
31
42
|
*
|
|
32
43
|
* ## Where the table lives, and why it stopped growing
|
|
33
44
|
*
|
|
@@ -50,28 +61,82 @@
|
|
|
50
61
|
* @author Alex Goldring
|
|
51
62
|
* @copyright Company Named Limited (c) 2026
|
|
52
63
|
*/
|
|
64
|
+
/**
|
|
65
|
+
* How far past its own particles a cloth has to look, metres.
|
|
66
|
+
*
|
|
67
|
+
* The gather has one job the solver depends on: the set it hands over must
|
|
68
|
+
* contain every collider `cloth_contact_find` would draw a row against. So the
|
|
69
|
+
* margin is that function's own reach, maximised over the things the gather
|
|
70
|
+
* cannot yet know — which collider, and which particle:
|
|
71
|
+
*
|
|
72
|
+
* (radius + inflation) · (1 + CLOTH_CONTACT_MARGIN) the contact itself
|
|
73
|
+
* + collider travel §20, the collider's approach
|
|
74
|
+
* + |v| · dt §54, the particle's own
|
|
75
|
+
*
|
|
76
|
+
* The radius term is added by {@link cloth_gather_colliders}, which knows the
|
|
77
|
+
* cloth's `contact_radius`; this supplies the rest. Inflation and collider
|
|
78
|
+
* travel come from the index as maxima over every live record, because the
|
|
79
|
+
* gather has not queried yet and so cannot know which records it will get.
|
|
80
|
+
*
|
|
81
|
+
* **The velocity is read before the step and the narrowphase reads it after
|
|
82
|
+
* `damp`**, which only ever scales it down — so this is an upper bound on the
|
|
83
|
+
* travel the rows are actually discovered with, not an estimate of it. That
|
|
84
|
+
* ordering is what makes a margin this tight safe; if a step ever gains speed
|
|
85
|
+
* before `cloth_contact_find`, this stops being a bound and the term has to
|
|
86
|
+
* carry the acceleration too.
|
|
87
|
+
*
|
|
88
|
+
* @param {ClothState} state
|
|
89
|
+
* @param {ClothColliderIndex} index
|
|
90
|
+
* @param {number} dt fixed step, seconds
|
|
91
|
+
* @returns {number} metres
|
|
92
|
+
*/
|
|
93
|
+
export function cloth_gather_reach(state: ClothState, index: ClothColliderIndex, dt: number): number;
|
|
53
94
|
/**
|
|
54
95
|
* Query the index and rewrite the overlapping colliders into the cloth's frame.
|
|
55
96
|
*
|
|
56
97
|
* @param {ClothInstance} instance read for its anchor pose and filter; its
|
|
57
98
|
* state's `collider_table`, `collider_key` and `collider_count` are filled
|
|
58
99
|
* @param {ClothColliderIndex} index
|
|
59
|
-
* @param {number} reach how far
|
|
100
|
+
* @param {number} reach how far past its particles the cloth has to look,
|
|
101
|
+
* metres — {@link cloth_gather_reach}
|
|
60
102
|
* @returns {number} how many colliders were gathered
|
|
61
103
|
*/
|
|
62
104
|
export function cloth_gather_colliders(instance: ClothInstance, index: ClothColliderIndex, reach: number): number;
|
|
63
105
|
/**
|
|
64
|
-
* Whether
|
|
65
|
-
*
|
|
106
|
+
* Whether the colliders overlapping this cloth have changed since the step it
|
|
107
|
+
* last took — §7 P5's "wake on collider motion", asked without waking.
|
|
66
108
|
*
|
|
67
109
|
* A sleeping cloth is not stepped and not written back, so something has to
|
|
68
|
-
* notice when the world it was resting against
|
|
69
|
-
* and it is a broadphase query plus
|
|
110
|
+
* notice when the world it was resting against changes. This is that something,
|
|
111
|
+
* and it is a broadphase query plus two comparisons: cheaper than a step by
|
|
70
112
|
* three orders of magnitude, which is what makes sleep worth having at all.
|
|
71
113
|
*
|
|
114
|
+
* **Two comparisons, and the set is the one M2 did not have.** A pose
|
|
115
|
+
* comparison answers "did anything move", and `ClothColliderSystem#link`
|
|
116
|
+
* *places* a new collider rather than posing it — previous equals current — so
|
|
117
|
+
* a sphere spawned around a sleeping rope is a collider that has not moved.
|
|
118
|
+
* Measured: the rope slept through it and stayed asleep three hundred steps
|
|
119
|
+
* later with four of its six links inside. A handle appearing in the gathered
|
|
120
|
+
* set, or leaving it, is a change to the world the cloth went to sleep in
|
|
121
|
+
* whatever the poses say, and it costs one integer compare per record.
|
|
122
|
+
*
|
|
123
|
+
* The query uses the reach the cloth's last *step* gathered with, so the two
|
|
124
|
+
* sets are answers to the same question. A set built at zero margin against one
|
|
125
|
+
* built at a step's travel would differ for reasons that are about the margin.
|
|
126
|
+
*
|
|
72
127
|
* @param {ClothInstance} instance
|
|
73
128
|
* @param {ClothColliderIndex} index
|
|
74
129
|
* @returns {boolean}
|
|
75
130
|
*/
|
|
76
131
|
export function cloth_colliders_moved(instance: ClothInstance, index: ClothColliderIndex): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Record the set this cloth is about to step against, so the next wake test has
|
|
134
|
+
* something to compare with. Called only where the cloth really will be
|
|
135
|
+
* stepped — a set gathered by the wake test itself is a question, not a step.
|
|
136
|
+
*
|
|
137
|
+
* @param {ClothInstance} instance
|
|
138
|
+
* @param {number} reach the margin the gather used, metres
|
|
139
|
+
* @returns {void}
|
|
140
|
+
*/
|
|
141
|
+
export function cloth_remember_colliders(instance: ClothInstance, reach: number): void;
|
|
77
142
|
//# sourceMappingURL=cloth_gather_colliders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_gather_colliders.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_gather_colliders.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloth_gather_colliders.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_gather_colliders.js"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qFAHW,MAAM,GACJ,MAAM,CAwBlB;AAED;;;;;;;;;GASG;AACH,kGAJW,MAAM,GAEJ,MAAM,CA6JlB;AAgDD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,2FAFa,OAAO,CAoCnB;AAED;;;;;;;;GAQG;AACH,yEAHW,MAAM,GACJ,IAAI,CAehB"}
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
CCR_TZ
|
|
28
28
|
} from "../collider/ClothColliderRecord.js";
|
|
29
29
|
import { cloth_collider_refit_bounds } from "../collider/cloth_collider_bounds.js";
|
|
30
|
+
import { CLOTH_CONTACT_MARGIN } from "../solver/cloth_contact_find.js";
|
|
30
31
|
import { CLOTH_COLLIDER_SLOTS } from "../solver/cloth_solver_constants.js";
|
|
31
32
|
|
|
32
33
|
/**
|
|
@@ -54,11 +55,22 @@ import { CLOTH_COLLIDER_SLOTS } from "../solver/cloth_solver_constants.js";
|
|
|
54
55
|
*
|
|
55
56
|
* ## The query box
|
|
56
57
|
*
|
|
57
|
-
* The cloth's own particle bounds, fattened by
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
58
|
+
* The cloth's own particle bounds, fattened by exactly what
|
|
59
|
+
* `cloth_contact_find` will reach for — no more, because a broadphase that is
|
|
60
|
+
* wider than its narrowphase is collecting colliders it will then throw away.
|
|
61
|
+
* {@link cloth_gather_reach} is that quantity and carries the derivation.
|
|
62
|
+
*
|
|
63
|
+
* It used to be the velocity clamp of §7 P1 read as a distance. That was wrong
|
|
64
|
+
* in both directions at once. The clamp is `4 · shortest_row · substeps ·
|
|
65
|
+
* iterations`, which for a rope of 10 cm links at 2 × 4 is **3.2 m** a step —
|
|
66
|
+
* so the box was fattened by metres to catch motion measured in centimetres,
|
|
67
|
+
* and a garment in a crowd collected every bone in the street and overflowed
|
|
68
|
+
* its table. `cloth_contact_find`'s own docblock had already worked out that
|
|
69
|
+
* this clamp is "about 154 m/s … three orders of magnitude" past real cloth
|
|
70
|
+
* speed and stopped using it (§54); the gather kept it. And being enormous, it
|
|
71
|
+
* hid the fact that it was also **missing** two terms the narrowphase does
|
|
72
|
+
* reach with — collider inflation and the collider's own travel — so a wide
|
|
73
|
+
* enough inflation was a row the gather never handed over.
|
|
62
74
|
*
|
|
63
75
|
* ## Where the table lives, and why it stopped growing
|
|
64
76
|
*
|
|
@@ -82,13 +94,67 @@ import { CLOTH_COLLIDER_SLOTS } from "../solver/cloth_solver_constants.js";
|
|
|
82
94
|
* @copyright Company Named Limited (c) 2026
|
|
83
95
|
*/
|
|
84
96
|
|
|
97
|
+
/**
|
|
98
|
+
* How far past its own particles a cloth has to look, metres.
|
|
99
|
+
*
|
|
100
|
+
* The gather has one job the solver depends on: the set it hands over must
|
|
101
|
+
* contain every collider `cloth_contact_find` would draw a row against. So the
|
|
102
|
+
* margin is that function's own reach, maximised over the things the gather
|
|
103
|
+
* cannot yet know — which collider, and which particle:
|
|
104
|
+
*
|
|
105
|
+
* (radius + inflation) · (1 + CLOTH_CONTACT_MARGIN) the contact itself
|
|
106
|
+
* + collider travel §20, the collider's approach
|
|
107
|
+
* + |v| · dt §54, the particle's own
|
|
108
|
+
*
|
|
109
|
+
* The radius term is added by {@link cloth_gather_colliders}, which knows the
|
|
110
|
+
* cloth's `contact_radius`; this supplies the rest. Inflation and collider
|
|
111
|
+
* travel come from the index as maxima over every live record, because the
|
|
112
|
+
* gather has not queried yet and so cannot know which records it will get.
|
|
113
|
+
*
|
|
114
|
+
* **The velocity is read before the step and the narrowphase reads it after
|
|
115
|
+
* `damp`**, which only ever scales it down — so this is an upper bound on the
|
|
116
|
+
* travel the rows are actually discovered with, not an estimate of it. That
|
|
117
|
+
* ordering is what makes a margin this tight safe; if a step ever gains speed
|
|
118
|
+
* before `cloth_contact_find`, this stops being a bound and the term has to
|
|
119
|
+
* carry the acceleration too.
|
|
120
|
+
*
|
|
121
|
+
* @param {ClothState} state
|
|
122
|
+
* @param {ClothColliderIndex} index
|
|
123
|
+
* @param {number} dt fixed step, seconds
|
|
124
|
+
* @returns {number} metres
|
|
125
|
+
*/
|
|
126
|
+
export function cloth_gather_reach(state, index, dt) {
|
|
127
|
+
const velocity = state.velocity;
|
|
128
|
+
|
|
129
|
+
const particle_count = state.particle_count;
|
|
130
|
+
|
|
131
|
+
let fastest_squared = 0;
|
|
132
|
+
|
|
133
|
+
for (let i = 0; i < particle_count; i++) {
|
|
134
|
+
const p = i * 3;
|
|
135
|
+
|
|
136
|
+
const speed_squared = velocity[p] * velocity[p]
|
|
137
|
+
+ velocity[p + 1] * velocity[p + 1]
|
|
138
|
+
+ velocity[p + 2] * velocity[p + 2];
|
|
139
|
+
|
|
140
|
+
if (speed_squared > fastest_squared) {
|
|
141
|
+
fastest_squared = speed_squared;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return dt * Math.sqrt(fastest_squared)
|
|
146
|
+
+ index.max_collider_travel
|
|
147
|
+
+ index.max_inflation * (1 + CLOTH_CONTACT_MARGIN);
|
|
148
|
+
}
|
|
149
|
+
|
|
85
150
|
/**
|
|
86
151
|
* Query the index and rewrite the overlapping colliders into the cloth's frame.
|
|
87
152
|
*
|
|
88
153
|
* @param {ClothInstance} instance read for its anchor pose and filter; its
|
|
89
154
|
* state's `collider_table`, `collider_key` and `collider_count` are filled
|
|
90
155
|
* @param {ClothColliderIndex} index
|
|
91
|
-
* @param {number} reach how far
|
|
156
|
+
* @param {number} reach how far past its particles the cloth has to look,
|
|
157
|
+
* metres — {@link cloth_gather_reach}
|
|
92
158
|
* @returns {number} how many colliders were gathered
|
|
93
159
|
*/
|
|
94
160
|
export function cloth_gather_colliders(instance, index, reach) {
|
|
@@ -125,7 +191,9 @@ export function cloth_gather_colliders(instance, index, reach) {
|
|
|
125
191
|
return 0;
|
|
126
192
|
}
|
|
127
193
|
|
|
128
|
-
|
|
194
|
+
// The contact's own reach, on the same terms `cloth_contact_find` states
|
|
195
|
+
// it in, plus everything {@link cloth_gather_reach} already folded in.
|
|
196
|
+
const margin = reach + state.contact_radius * (1 + CLOTH_CONTACT_MARGIN);
|
|
129
197
|
|
|
130
198
|
min_x -= margin;
|
|
131
199
|
min_y -= margin;
|
|
@@ -293,20 +361,47 @@ function localise(
|
|
|
293
361
|
}
|
|
294
362
|
|
|
295
363
|
/**
|
|
296
|
-
* Whether
|
|
297
|
-
*
|
|
364
|
+
* Whether the colliders overlapping this cloth have changed since the step it
|
|
365
|
+
* last took — §7 P5's "wake on collider motion", asked without waking.
|
|
298
366
|
*
|
|
299
367
|
* A sleeping cloth is not stepped and not written back, so something has to
|
|
300
|
-
* notice when the world it was resting against
|
|
301
|
-
* and it is a broadphase query plus
|
|
368
|
+
* notice when the world it was resting against changes. This is that something,
|
|
369
|
+
* and it is a broadphase query plus two comparisons: cheaper than a step by
|
|
302
370
|
* three orders of magnitude, which is what makes sleep worth having at all.
|
|
303
371
|
*
|
|
372
|
+
* **Two comparisons, and the set is the one M2 did not have.** A pose
|
|
373
|
+
* comparison answers "did anything move", and `ClothColliderSystem#link`
|
|
374
|
+
* *places* a new collider rather than posing it — previous equals current — so
|
|
375
|
+
* a sphere spawned around a sleeping rope is a collider that has not moved.
|
|
376
|
+
* Measured: the rope slept through it and stayed asleep three hundred steps
|
|
377
|
+
* later with four of its six links inside. A handle appearing in the gathered
|
|
378
|
+
* set, or leaving it, is a change to the world the cloth went to sleep in
|
|
379
|
+
* whatever the poses say, and it costs one integer compare per record.
|
|
380
|
+
*
|
|
381
|
+
* The query uses the reach the cloth's last *step* gathered with, so the two
|
|
382
|
+
* sets are answers to the same question. A set built at zero margin against one
|
|
383
|
+
* built at a step's travel would differ for reasons that are about the margin.
|
|
384
|
+
*
|
|
304
385
|
* @param {ClothInstance} instance
|
|
305
386
|
* @param {ClothColliderIndex} index
|
|
306
387
|
* @returns {boolean}
|
|
307
388
|
*/
|
|
308
389
|
export function cloth_colliders_moved(instance, index) {
|
|
309
|
-
const found = cloth_gather_colliders(instance, index,
|
|
390
|
+
const found = cloth_gather_colliders(instance, index, instance.gather_reach);
|
|
391
|
+
|
|
392
|
+
const keys = instance.state.collider_key;
|
|
393
|
+
|
|
394
|
+
if (found !== instance.collider_key_count) {
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const seen = instance.collider_keys;
|
|
399
|
+
|
|
400
|
+
for (let i = 0; i < found; i++) {
|
|
401
|
+
if (keys[i] !== seen[i]) {
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
310
405
|
|
|
311
406
|
const table = instance.state.collider_table;
|
|
312
407
|
|
|
@@ -327,6 +422,30 @@ export function cloth_colliders_moved(instance, index) {
|
|
|
327
422
|
return false;
|
|
328
423
|
}
|
|
329
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Record the set this cloth is about to step against, so the next wake test has
|
|
427
|
+
* something to compare with. Called only where the cloth really will be
|
|
428
|
+
* stepped — a set gathered by the wake test itself is a question, not a step.
|
|
429
|
+
*
|
|
430
|
+
* @param {ClothInstance} instance
|
|
431
|
+
* @param {number} reach the margin the gather used, metres
|
|
432
|
+
* @returns {void}
|
|
433
|
+
*/
|
|
434
|
+
export function cloth_remember_colliders(instance, reach) {
|
|
435
|
+
const count = instance.state.collider_count;
|
|
436
|
+
|
|
437
|
+
const keys = instance.state.collider_key;
|
|
438
|
+
|
|
439
|
+
const seen = instance.collider_keys;
|
|
440
|
+
|
|
441
|
+
for (let i = 0; i < count; i++) {
|
|
442
|
+
seen[i] = keys[i];
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
instance.collider_key_count = count;
|
|
446
|
+
instance.gather_reach = reach;
|
|
447
|
+
}
|
|
448
|
+
|
|
330
449
|
/**
|
|
331
450
|
* @type {number[]}
|
|
332
451
|
* @private
|
|
@@ -51,4 +51,23 @@
|
|
|
51
51
|
* @param {number} dt
|
|
52
52
|
*/
|
|
53
53
|
export function cloth_seed_rig(instance: ClothInstance, proxy: ClothProxy, joints: number[], ecd: EntityComponentDataset, dt: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Give back every joint's `TransformAttachment` authority that this cloth's
|
|
56
|
+
* seeding took from the GPU.
|
|
57
|
+
*
|
|
58
|
+
* The seed revokes so that the write-back reaches the row at all, and the
|
|
59
|
+
* consequence the module docblock states — "a joint cloth simulates stops being
|
|
60
|
+
* animatable by a clip" — is only the right trade while the cloth is *there*.
|
|
61
|
+
* A garment removed and nothing re-granting leaves its joints owned by a CPU
|
|
62
|
+
* that is no longer writing them: neither animated nor simulated, and stuck in
|
|
63
|
+
* the pose the solver stopped in.
|
|
64
|
+
*
|
|
65
|
+
* Only the joints the revoke actually changed are given back, so a joint that
|
|
66
|
+
* was already the CPU's before cloth arrived stays the CPU's.
|
|
67
|
+
*
|
|
68
|
+
* @param {ClothInstance} instance
|
|
69
|
+
* @param {EntityComponentDataset} ecd
|
|
70
|
+
* @returns {void}
|
|
71
|
+
*/
|
|
72
|
+
export function cloth_release_rig(instance: ClothInstance, ecd: EntityComponentDataset): void;
|
|
54
73
|
//# sourceMappingURL=cloth_seed_rig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloth_seed_rig.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_seed_rig.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloth_seed_rig.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/cloth_seed_rig.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH;;;;;;;;GAQG;AACH,mFAJW,MAAM,EAAE,mCAER,MAAM,QAkFhB;AAoED;;;;;;;;;;;;;;;;;GAiBG;AACH,yFAFa,IAAI,CAoBhB"}
|