@woosh/meep-engine 3.31.0 → 3.33.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/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/collection/table/RowFirstTable.d.ts +8 -0
- package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
- package/src/core/collection/table/RowFirstTable.js +40 -11
- package/src/engine/graphics/ecs/sprite/Sprite.d.ts +3 -0
- package/src/engine/graphics/ecs/sprite/Sprite.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/Sprite.js +3 -0
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts +3 -0
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +3 -0
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem.js +6 -2
- package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics3/PathDisplaySystem.js +311 -307
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +15 -2
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +5 -0
- package/src/shade/device/ShadeGPUCommandContext.d.ts +15 -2
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +154 -25
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +20 -3
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +21 -3
- package/src/shade/renderer/GraphicsContext.d.ts +20 -1
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +105 -52
- package/src/shade/renderer/Renderer.d.ts +19 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +113 -2
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +10 -7
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +147 -45
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +6 -5
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +241 -240
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.d.ts +62 -2
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.js +306 -38
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.d.ts +60 -0
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.d.ts.map +1 -0
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.js +202 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.d.ts +68 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.d.ts.map +1 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.js +97 -0
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.d.ts +2 -1
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.js +19 -17
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.d.ts +70 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.d.ts.map +1 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.js +257 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.d.ts +20 -7
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +39 -41
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +6 -20
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +42 -36
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts +2 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.js +4 -3
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.d.ts +4 -3
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.js +7 -4
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts +14 -15
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.js +49 -83
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts +19 -3
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +26 -6
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts +2 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +12 -6
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts +3 -2
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +21 -13
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +5 -0
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +19 -0
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +3 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +3 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +134 -88
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +57 -26
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +28 -20
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.d.ts +38 -0
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.js +105 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +20 -0
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +21 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +12 -20
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts +2 -1
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.js +15 -28
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js +8 -1
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts +0 -73
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.d.ts +0 -59
- package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +0 -22
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/shader_terrain_splat.d.ts +0 -26
- package/src/engine/graphics3/terrain/shader_terrain_splat.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_BOUND_TRACK_GROUP_STRUCT.d.ts +0 -25
- package/src/shade/renderer/animation/ANIMATION_BOUND_TRACK_GROUP_STRUCT.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_KEYFRAME_BLOCK_STRUCT.d.ts +0 -26
- package/src/shade/renderer/animation/ANIMATION_KEYFRAME_BLOCK_STRUCT.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_SKIN_JOINT_BLOCK_STRUCT.d.ts +0 -29
- package/src/shade/renderer/animation/ANIMATION_SKIN_JOINT_BLOCK_STRUCT.d.ts.map +0 -1
|
@@ -200,8 +200,8 @@ export class GPUAnimationManager {
|
|
|
200
200
|
*
|
|
201
201
|
* Lazily allocated on first {@link add_skin}; both grow together
|
|
202
202
|
* by doubling. After a grow both buffers are zero-initialised and
|
|
203
|
-
* {@link #
|
|
204
|
-
*
|
|
203
|
+
* {@link #skin_matrix_seed_all} is set so the next prep dispatch
|
|
204
|
+
* seeds all of the "previous" buffer with a copy of the freshly
|
|
205
205
|
* written "current" — without this, the first velocity readback
|
|
206
206
|
* after a grow would interpolate against zero matrices.
|
|
207
207
|
*
|
|
@@ -217,15 +217,31 @@ export class GPUAnimationManager {
|
|
|
217
217
|
#skin_matrices_current_index = 0;
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
220
|
+
* The runs of matrix rows the next prep dispatch seeds "previous" from "current" over, each
|
|
221
|
+
* `[first_row, count]`: a run handed out, and a pending skin's run whose joints were just
|
|
222
|
+
* named. The frame before either is not a pose — "previous" over those rows holds zeros, or
|
|
223
|
+
* the last pose of a skin that had them — so the first velocity read over them has to see
|
|
224
|
+
* matching matrices, which is zero velocity.
|
|
225
|
+
*
|
|
226
|
+
* Only those rows: a settled skin's rows of "previous" hold its pose last frame, which is what
|
|
227
|
+
* its motion is measured from.
|
|
228
|
+
*
|
|
229
|
+
* A skin given back takes its queued runs with it ({@link unregister_skin}), so every run here
|
|
230
|
+
* belongs to a skin still registered and not yet seeded — however long no prep runs, as while
|
|
231
|
+
* a loading screen draws nothing and the game goes on spawning.
|
|
232
|
+
*
|
|
233
|
+
* @type {Array<[number, number]>}
|
|
234
|
+
*/
|
|
235
|
+
#skin_matrix_seed_runs = [];
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* When true, the next prep dispatch seeds all of "previous" from "current", whatever
|
|
239
|
+
* {@link #skin_matrix_seed_runs} holds. Set when the buffers grow: both are made again,
|
|
240
|
+
* zeroed, so no row has a last frame left to keep.
|
|
241
|
+
*
|
|
226
242
|
* @type {boolean}
|
|
227
243
|
*/
|
|
228
|
-
#
|
|
244
|
+
#skin_matrix_seed_all = false;
|
|
229
245
|
|
|
230
246
|
/**
|
|
231
247
|
* Capacity of each of {@link #skin_matrices_buffers} in matrices
|
|
@@ -1056,7 +1072,7 @@ export class GPUAnimationManager {
|
|
|
1056
1072
|
// The joints' matrices are written from the next prep on, and "previous" over their rows
|
|
1057
1073
|
// holds whatever was there before — zeros, or the last pose of a skin that had them — so
|
|
1058
1074
|
// it is seeded, as it is for a run just handed out.
|
|
1059
|
-
this.#
|
|
1075
|
+
this.#skin_matrix_seed_runs.push([pending.joints_first, pending.joint_count]);
|
|
1060
1076
|
|
|
1061
1077
|
return true;
|
|
1062
1078
|
}
|
|
@@ -1436,10 +1452,34 @@ export class GPUAnimationManager {
|
|
|
1436
1452
|
return;
|
|
1437
1453
|
}
|
|
1438
1454
|
|
|
1455
|
+
// Its rows go back owed no seed. Left queued, a run outlives its skin until the next prep,
|
|
1456
|
+
// and while nothing draws that is every spawn since drawing stopped.
|
|
1457
|
+
this.#drop_seed_runs(skins_table.get_word(skin_id, SKIN_JOINTS_FIRST_WORD));
|
|
1458
|
+
|
|
1439
1459
|
// The joints go with the skin — a pending skin's too, nodes or not.
|
|
1440
1460
|
skins_table.remove(skin_id);
|
|
1441
1461
|
}
|
|
1442
1462
|
|
|
1463
|
+
/**
|
|
1464
|
+
* Drop every queued seed run starting at `first_row`: the run of a skin being given back,
|
|
1465
|
+
* queued when it was handed out, and again if its joints have been named since.
|
|
1466
|
+
*
|
|
1467
|
+
* No other skin's run can start there, since a skin's rows are its own until it is given back.
|
|
1468
|
+
*
|
|
1469
|
+
* @param {number} first_row
|
|
1470
|
+
*/
|
|
1471
|
+
#drop_seed_runs(first_row) {
|
|
1472
|
+
const runs = this.#skin_matrix_seed_runs;
|
|
1473
|
+
|
|
1474
|
+
// the prep sorts what it finds, so a dropped run's place goes to the last one
|
|
1475
|
+
for (let i = runs.length - 1; i >= 0; i--) {
|
|
1476
|
+
if (runs[i][0] === first_row) {
|
|
1477
|
+
runs[i] = runs[runs.length - 1];
|
|
1478
|
+
runs.pop();
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1443
1483
|
/**
|
|
1444
1484
|
* Cached wrapper around {@link add_curve}: one upload per distinct curve, where distinct means
|
|
1445
1485
|
* distinct *content*.
|
|
@@ -1541,25 +1581,31 @@ export class GPUAnimationManager {
|
|
|
1541
1581
|
// its rows are fresh or some despawned skin's, so the next prep dispatch has to seed
|
|
1542
1582
|
// "previous" from "current" for it.
|
|
1543
1583
|
//
|
|
1544
|
-
//
|
|
1545
|
-
//
|
|
1546
|
-
//
|
|
1547
|
-
// `
|
|
1548
|
-
//
|
|
1549
|
-
//
|
|
1550
|
-
//
|
|
1551
|
-
|
|
1552
|
-
this.#first_frame_skin_matrices = true;
|
|
1584
|
+
// Whether or not the buffers grew: rows given back by another skin never grow them, and
|
|
1585
|
+
// neither do fresh rows below the capacity, so "previous" over the run holds all-zero
|
|
1586
|
+
// matrices or the last pose of the skin that had those rows before. The skinning pass
|
|
1587
|
+
// reads `prev_skin_matrices[skin_base + j]` unconditionally, so unseeded, the new
|
|
1588
|
+
// character's first frame would take its motion vectors from someone else's pose — a
|
|
1589
|
+
// screen-crossing smear through TAA and motion blur — on exactly the spawn/despawn loop
|
|
1590
|
+
// that reuses rows.
|
|
1591
|
+
this.#skin_matrix_seed_runs.push([joints_first, joints.length]);
|
|
1553
1592
|
|
|
1554
1593
|
return joints_first;
|
|
1555
1594
|
}
|
|
1556
1595
|
|
|
1557
1596
|
/**
|
|
1558
|
-
* Grow the skinning-matrix
|
|
1559
|
-
*
|
|
1560
|
-
*
|
|
1561
|
-
*
|
|
1562
|
-
*
|
|
1597
|
+
* Grow the skinning-matrix buffers if `required_count` exceeds
|
|
1598
|
+
* current capacity. Doubles on grow until the requirement fits.
|
|
1599
|
+
*
|
|
1600
|
+
* Nothing is copied across. "Current" would be rewritten by the
|
|
1601
|
+
* next prep anyway, but "previous" held every skin's pose last
|
|
1602
|
+
* frame, which its motion is measured from: the grow loses that,
|
|
1603
|
+
* and the next prep seeds all of "previous" from "current" instead
|
|
1604
|
+
* ({@link #skin_matrix_seed_all}), so every skinned character has
|
|
1605
|
+
* zero motion vectors for that one frame. Capacity doubles, so
|
|
1606
|
+
* that is a handful of frames over a session.
|
|
1607
|
+
*
|
|
1608
|
+
* The grow also invalidates the {@link #skin_matrices_buffer}
|
|
1563
1609
|
* reference, which is why callers re-fetch through the getter.
|
|
1564
1610
|
*
|
|
1565
1611
|
* @param {number} required_count number of matrices that must fit
|
|
@@ -1578,8 +1624,9 @@ export class GPUAnimationManager {
|
|
|
1578
1624
|
// capacity. After grow both are zero-initialised, so the next
|
|
1579
1625
|
// prep dispatch needs to seed "previous" from "current"
|
|
1580
1626
|
// (otherwise velocity would interpolate against zero
|
|
1581
|
-
// matrices)
|
|
1582
|
-
//
|
|
1627
|
+
// matrices), and all of it: no row has a last frame left to
|
|
1628
|
+
// keep. The flag below tells dispatch_skin_matrix_prep to
|
|
1629
|
+
// issue that copy.
|
|
1583
1630
|
for (let i = 0; i < 2; i++) {
|
|
1584
1631
|
if (this.#skin_matrices_buffers[i] !== null) {
|
|
1585
1632
|
this.#skin_matrices_buffers[i].destroy();
|
|
@@ -1591,7 +1638,7 @@ export class GPUAnimationManager {
|
|
|
1591
1638
|
});
|
|
1592
1639
|
}
|
|
1593
1640
|
this.#skin_matrices_capacity = new_capacity;
|
|
1594
|
-
this.#
|
|
1641
|
+
this.#skin_matrix_seed_all = true;
|
|
1595
1642
|
}
|
|
1596
1643
|
|
|
1597
1644
|
/**
|
|
@@ -1643,8 +1690,10 @@ export class GPUAnimationManager {
|
|
|
1643
1690
|
* correct ping-pong behaviour across frames without leaking the
|
|
1644
1691
|
* buffer-role bookkeeping into every caller.
|
|
1645
1692
|
*
|
|
1646
|
-
* No-op when the joints table has no
|
|
1647
|
-
* (`group_count_x === 0`)
|
|
1693
|
+
* No-op when the joints table has no page for it to walk
|
|
1694
|
+
* (`group_count_x === 0`), which is never while a skin is
|
|
1695
|
+
* registered: a page emptied of joints goes at the next database
|
|
1696
|
+
* update.
|
|
1648
1697
|
*
|
|
1649
1698
|
* Per-frame ordering:
|
|
1650
1699
|
* 1. Flip {@link #skin_matrices_current_index}: last frame's
|
|
@@ -1652,11 +1701,12 @@ export class GPUAnimationManager {
|
|
|
1652
1701
|
* ({@link prev_skin_matrices_buffer}), and the buffer that
|
|
1653
1702
|
* held the frame before it becomes the write target.
|
|
1654
1703
|
* 2. Dispatch the prep shader into the new "current".
|
|
1655
|
-
* 3.
|
|
1656
|
-
* out
|
|
1657
|
-
* since the last dispatch
|
|
1658
|
-
*
|
|
1659
|
-
*
|
|
1704
|
+
* 3. Copy "current" over "previous" on the rows that have no last
|
|
1705
|
+
* frame — every run handed out and every pending skin's run
|
|
1706
|
+
* named since the last dispatch, or all of it after a grow —
|
|
1707
|
+
* so the first velocity read over those rows sees matching
|
|
1708
|
+
* matrices and produces zero velocity. Every other row of
|
|
1709
|
+
* "previous" keeps last frame's matrices.
|
|
1660
1710
|
*
|
|
1661
1711
|
* @param {ShadeGPUCommandContext} cmd_ctx
|
|
1662
1712
|
*/
|
|
@@ -1665,6 +1715,9 @@ export class GPUAnimationManager {
|
|
|
1665
1715
|
.get('animation_skin_joints')
|
|
1666
1716
|
.dispatch_group_count(SKIN_MATRIX_PREP_WORKGROUP_SIZE);
|
|
1667
1717
|
if (groups === 0) {
|
|
1718
|
+
// no page to walk means no skin registered, and a skin given back takes its runs
|
|
1719
|
+
assert.equal(this.#skin_matrix_seed_runs.length, 0, 'seed runs queued for skins no longer registered');
|
|
1720
|
+
|
|
1668
1721
|
return;
|
|
1669
1722
|
}
|
|
1670
1723
|
|
|
@@ -1689,20 +1742,69 @@ export class GPUAnimationManager {
|
|
|
1689
1742
|
},
|
|
1690
1743
|
});
|
|
1691
1744
|
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1745
|
+
this.#seed_previous_skin_matrices(cmd_ctx, current, previous);
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
/**
|
|
1749
|
+
* Copy "current" over "previous" on the rows where "previous" holds no pose of the frame
|
|
1750
|
+
* before: all of it after a grow, otherwise the runs queued since the last prep. Zeros there,
|
|
1751
|
+
* or the last pose of a skin that had the rows, would have the velocity pass produce huge
|
|
1752
|
+
* nonsense on the first frame the skin appears; seeded, the first velocity read yields zero,
|
|
1753
|
+
* which is the right answer — no motion has happened yet.
|
|
1754
|
+
*
|
|
1755
|
+
* Every other row is left alone: a settled skin's rows hold its pose last frame, which its
|
|
1756
|
+
* motion is measured from, and the rest are read by no one. Seeded too, every skinned
|
|
1757
|
+
* character on screen would lose its motion vectors for the frame whenever one spawned.
|
|
1758
|
+
*
|
|
1759
|
+
* Runs are coalesced by sorting — a frame's worth of spawns is a handful of runs — and adjacent
|
|
1760
|
+
* or overlapping ones go as one copy.
|
|
1761
|
+
*
|
|
1762
|
+
* @param {ShadeGPUCommandContext} cmd_ctx
|
|
1763
|
+
* @param {GPUBuffer} current
|
|
1764
|
+
* @param {GPUBuffer} previous
|
|
1765
|
+
*/
|
|
1766
|
+
#seed_previous_skin_matrices(cmd_ctx, current, previous) {
|
|
1767
|
+
const runs = this.#skin_matrix_seed_runs;
|
|
1768
|
+
|
|
1769
|
+
if (this.#skin_matrix_seed_all) {
|
|
1770
|
+
cmd_ctx.copyBufferToBuffer(current, 0, previous, 0, current.size);
|
|
1771
|
+
|
|
1772
|
+
this.#skin_matrix_seed_all = false;
|
|
1773
|
+
runs.length = 0;
|
|
1774
|
+
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
if (runs.length === 0) {
|
|
1779
|
+
// a settled frame: every row of "previous" is last frame's
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
runs.sort((a, b) => a[0] - b[0]);
|
|
1784
|
+
|
|
1785
|
+
let i = 0;
|
|
1786
|
+
|
|
1787
|
+
while (i < runs.length) {
|
|
1788
|
+
const first = runs[i][0];
|
|
1789
|
+
let end = first + runs[i][1];
|
|
1790
|
+
|
|
1791
|
+
i++;
|
|
1792
|
+
|
|
1793
|
+
// a run starting at or before this copy's end is part of it
|
|
1794
|
+
while (i < runs.length && runs[i][0] <= end) {
|
|
1795
|
+
end = Math.max(end, runs[i][0] + runs[i][1]);
|
|
1796
|
+
|
|
1797
|
+
i++;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1699
1800
|
cmd_ctx.copyBufferToBuffer(
|
|
1700
|
-
current,
|
|
1701
|
-
previous,
|
|
1702
|
-
|
|
1801
|
+
current, first * SKIN_MATRIX_BYTES,
|
|
1802
|
+
previous, first * SKIN_MATRIX_BYTES,
|
|
1803
|
+
(end - first) * SKIN_MATRIX_BYTES,
|
|
1703
1804
|
);
|
|
1704
|
-
this.#first_frame_skin_matrices = false;
|
|
1705
1805
|
}
|
|
1806
|
+
|
|
1807
|
+
runs.length = 0;
|
|
1706
1808
|
}
|
|
1707
1809
|
|
|
1708
1810
|
/**
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Persistent `MAP_READ | COPY_DST` buffers for reading GPU data back — {@link GPUBufferStagingAllocator}
|
|
3
3
|
* run the other way.
|
|
4
4
|
*
|
|
5
|
-
* The same shape
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* The same shape: a size-sorted free list, `get(min_size)` serving the smallest buffer that fits
|
|
6
|
+
* and creating one when none does, `release(buffer)` putting it back. Where the staging pool re-maps
|
|
7
|
+
* a buffer on release because the next writer needs it mapped, this one *unmaps*, because the next
|
|
8
|
+
* copy into it needs it unmapped; the mapping is the holder's, taken after the copy has landed and
|
|
9
|
+
* read at the holder's own apply point. Unlike the staging pool, this one has no bound on how much
|
|
10
|
+
* larger than the request a buffer it serves may be, no size classes and no reclaim.
|
|
10
11
|
*
|
|
11
12
|
* Why not `buffer_allocator_main`: `TransientResourcePool`'s reuse safety rests on transients being
|
|
12
13
|
* GPU-only, and a readback buffer is held by the CPU across frames.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUBufferReadbackAllocator.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/buffer/GPUBufferReadbackAllocator.js"],"names":[],"mappings":"AAoCA
|
|
1
|
+
{"version":3,"file":"GPUBufferReadbackAllocator.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/buffer/GPUBufferReadbackAllocator.js"],"names":[],"mappings":"AAoCA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IA4BI;;;;OAIG;IACH;QAF4B,YAAY,GAA7B,MAAM;OAQhB;IAED;;;OAGG;IACH,+BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;OAGG;IACH,6BAEC;IAED;;;OAGG;IACH,0BAEC;IAED;;;;;;OAMG;IACH,oBAHW,MAAM,aAkChB;IAED;;;;;OAKG;IACH,iCAsBC;IAED;;;;;OAKG;IACH,iCAMC;IAkBD,gBAUC;;CACJ"}
|