@woosh/meep-engine 3.21.0 → 3.23.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/README.md +96 -213
- package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
- package/editor/particles/effect/ParticleEffectDocument.js +0 -3
- package/editor/particles/effect/ParticleReferenceSimulation.js +1 -1
- package/editor/persistence/SceneMetadata.d.ts +9 -4
- package/editor/persistence/SceneMetadata.d.ts.map +1 -1
- package/editor/persistence/SceneMetadata.js +4 -3
- package/editor/tools/TransformToolV2.d.ts +2 -1
- package/editor/tools/TransformToolV2.d.ts.map +1 -1
- package/editor/tools/engine/Tool.d.ts +1 -1
- package/editor/tools/engine/Tool.d.ts.map +1 -1
- package/editor/tools/engine/ToolEngine.d.ts +1 -1
- package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
- package/editor/view/ecs/EntityEditor.d.ts +3 -2
- package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
- package/editor/view/ecs/EntityList.d.ts +7 -3
- package/editor/view/ecs/EntityList.d.ts.map +1 -1
- package/editor/view/ecs/EntityList.js +3 -2
- package/editor/view/ecs/components/common/NumericIntervalController.d.ts +8 -3
- package/editor/view/ecs/components/common/NumericIntervalController.d.ts.map +1 -1
- package/editor/view/ecs/components/common/NumericIntervalController.js +3 -2
- package/editor/view/ecs/components/common/TextController.d.ts +7 -3
- package/editor/view/ecs/components/common/TextController.d.ts.map +1 -1
- package/editor/view/ecs/components/common/TextController.js +3 -2
- package/editor/view/library/MeshLibraryView.d.ts.map +1 -1
- package/editor/view/library/MeshLibraryView.js +3 -2
- package/editor/view/node-graph/NodeIconView.d.ts +5 -2
- package/editor/view/node-graph/NodeIconView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeIconView.js +2 -1
- package/editor/view/node-graph/PortView.d.ts +9 -4
- package/editor/view/node-graph/PortView.d.ts.map +1 -1
- package/editor/view/node-graph/PortView.js +4 -3
- package/editor/view/particles/ColorLutGradientView.d.ts +7 -3
- package/editor/view/particles/ColorLutGradientView.d.ts.map +1 -1
- package/editor/view/particles/ColorLutGradientView.js +3 -2
- package/editor/view/particles/ScalarLutCurveView.d.ts +9 -4
- package/editor/view/particles/ScalarLutCurveView.d.ts.map +1 -1
- package/editor/view/particles/ScalarLutCurveView.js +4 -3
- package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleEmitterInspectorView.js +0 -1
- package/editor/view/tools/ToolView.d.ts +7 -3
- package/editor/view/tools/ToolView.d.ts.map +1 -1
- package/editor/view/tools/ToolView.js +3 -2
- package/package.json +2 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts +24 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +101 -1
- package/src/core/binary/type/Field.d.ts +5 -1
- package/src/core/binary/type/Field.d.ts.map +1 -1
- package/src/core/binary/type/Field.js +4 -0
- package/src/core/binary/type/Type.d.ts +4 -0
- package/src/core/binary/type/Type.d.ts.map +1 -1
- package/src/core/binary/type/Type.js +4 -0
- package/src/core/cache/Cache.d.ts +15 -7
- package/src/core/cache/Cache.d.ts.map +1 -1
- package/src/core/cache/Cache.js +7 -6
- package/src/core/cache/wtinylfu/CacheRegionWTinylfu.d.ts +5 -2
- package/src/core/cache/wtinylfu/CacheRegionWTinylfu.d.ts.map +1 -1
- package/src/core/cache/wtinylfu/CacheRegionWTinylfu.js +2 -1
- package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts +20 -10
- package/src/core/cache/wtinylfu/CacheWTinylfu.d.ts.map +1 -1
- package/src/core/cache/wtinylfu/CacheWTinylfu.js +9 -8
- package/src/core/collection/CuckooFilter.d.ts +8 -4
- package/src/core/collection/CuckooFilter.d.ts.map +1 -1
- package/src/core/collection/CuckooFilter.js +3 -2
- package/src/core/collection/list/List.d.ts +0 -1
- package/src/core/collection/list/List.d.ts.map +1 -1
- package/src/core/collection/list/List.js +0 -1
- package/src/core/collection/map/HashMap.d.ts +12 -7
- package/src/core/collection/map/HashMap.d.ts.map +1 -1
- package/src/core/collection/map/HashMap.js +5 -5
- package/src/core/collection/map/ObservedMap.d.ts +1 -2
- package/src/core/collection/map/ObservedMap.d.ts.map +1 -1
- package/src/core/collection/map/ObservedMap.js +0 -1
- package/src/core/collection/table/RowFirstTable.d.ts +1 -0
- package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
- package/src/core/collection/table/RowFirstTable.js +4 -0
- package/src/core/color/Color.d.ts +1 -2
- package/src/core/color/Color.d.ts.map +1 -1
- package/src/core/color/Color.js +5 -4
- package/src/core/color/hsv/hsv2rgb_float.d.ts +23 -1
- package/src/core/color/hsv/hsv2rgb_float.d.ts.map +1 -1
- package/src/core/color/hsv/hsv2rgb_float.js +31 -3
- package/src/core/color/hsv/hsv_to_rgb.d.ts +20 -9
- package/src/core/color/hsv/hsv_to_rgb.d.ts.map +1 -1
- package/src/core/color/hsv/hsv_to_rgb.js +30 -10
- package/src/core/color/hsv/hsv_to_rgb_uint8.d.ts.map +1 -1
- package/src/core/color/hsv/hsv_to_rgb_uint8.js +10 -5
- package/src/core/function/FunctionCompiler.d.ts +9 -4
- package/src/core/function/FunctionCompiler.d.ts.map +1 -1
- package/src/core/function/FunctionCompiler.js +8 -6
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
- package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts +41 -0
- package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/quat3_shortest_arc.js +94 -0
- package/src/core/geom/3d/ray/Ray3.d.ts +5 -5
- package/src/core/geom/3d/ray/Ray3.d.ts.map +1 -1
- package/src/core/geom/3d/ray/Ray3.js +3 -3
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts +1 -0
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/AbstractShape3D.js +4 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +2 -4
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/ConvexHullShape3D.js +0 -2
- package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
- package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts +1 -2
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +0 -1
- package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +6 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +5 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +2 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +5 -0
- package/src/core/geom/Quaternion.d.ts +1 -0
- package/src/core/geom/Quaternion.d.ts.map +1 -1
- package/src/core/geom/Quaternion.js +4 -0
- package/src/core/geom/Vector1.d.ts +8 -0
- package/src/core/geom/Vector1.d.ts.map +1 -1
- package/src/core/geom/Vector1.js +6 -0
- package/src/core/geom/Vector3.d.ts +6 -0
- package/src/core/geom/Vector3.d.ts.map +1 -1
- package/src/core/geom/Vector3.js +5 -0
- package/src/core/geom/Vector4.d.ts +10 -2
- package/src/core/geom/Vector4.d.ts.map +1 -1
- package/src/core/geom/Vector4.js +6 -1
- package/src/core/geom/packing/max-rect/MaxRectanglesPacker.d.ts +4 -4
- package/src/core/geom/packing/max-rect/MaxRectanglesPacker.d.ts.map +1 -1
- package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
- package/src/core/graph/convert_graph_to_dot_string.d.ts +7 -3
- package/src/core/graph/convert_graph_to_dot_string.d.ts.map +1 -1
- package/src/core/graph/convert_graph_to_dot_string.js +3 -2
- package/src/core/localization/Localization.d.ts +3 -2
- package/src/core/localization/Localization.d.ts.map +1 -1
- package/src/core/localization/Localization.js +4 -0
- package/src/core/math/noise/create_simplex_noise_2d.js +6 -6
- package/src/core/model/ObservedValue.d.ts +8 -6
- package/src/core/model/ObservedValue.d.ts.map +1 -1
- package/src/core/model/ObservedValue.js +3 -1
- package/src/core/model/node-graph/Connection.d.ts +1 -0
- package/src/core/model/node-graph/Connection.d.ts.map +1 -1
- package/src/core/model/node-graph/Connection.js +4 -0
- package/src/core/model/node-graph/NodeGraph.d.ts +8 -5
- package/src/core/model/node-graph/NodeGraph.d.ts.map +1 -1
- package/src/core/model/node-graph/NodeGraph.js +3 -3
- package/src/core/model/node-graph/json/serializeNodeGraphToJSON.d.ts +9 -4
- package/src/core/model/node-graph/json/serializeNodeGraphToJSON.d.ts.map +1 -1
- package/src/core/model/node-graph/json/serializeNodeGraphToJSON.js +4 -3
- package/src/core/model/node-graph/node/NodeDescription.d.ts +12 -4
- package/src/core/model/node-graph/node/NodeDescription.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeDescription.js +10 -3
- package/src/core/model/node-graph/node/NodeInstance.d.ts +5 -2
- package/src/core/model/node-graph/node/NodeInstance.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeInstance.js +6 -0
- package/src/core/model/node-graph/node/NodeInstancePortReference.d.ts +5 -2
- package/src/core/model/node-graph/node/NodeInstancePortReference.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeInstancePortReference.js +6 -0
- package/src/core/model/node-graph/node/NodeRegistry.d.ts +2 -1
- package/src/core/model/node-graph/node/NodeRegistry.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeRegistry.js +4 -0
- package/src/core/model/node-graph/node/Port.d.ts +12 -5
- package/src/core/model/node-graph/node/Port.d.ts.map +1 -1
- package/src/core/model/node-graph/node/Port.js +9 -4
- package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.d.ts +5 -2
- package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.d.ts.map +1 -1
- package/src/core/model/node-graph/util/convert_node_graph_to_dot_string.js +2 -1
- package/src/core/model/node-graph/util/graph_clone_by_node_subset.d.ts +5 -2
- package/src/core/model/node-graph/util/graph_clone_by_node_subset.d.ts.map +1 -1
- package/src/core/model/node-graph/util/graph_clone_by_node_subset.js +2 -1
- package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.d.ts +5 -2
- package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.d.ts.map +1 -1
- package/src/core/model/node-graph/util/graph_collect_connections_amongst_nodes.js +2 -1
- package/src/core/primitives/Class.d.ts +15 -0
- package/src/core/primitives/Class.d.ts.map +1 -0
- package/src/core/primitives/Class.js +18 -0
- package/src/core/primitives/TypedArray.d.ts +15 -0
- package/src/core/primitives/TypedArray.d.ts.map +1 -0
- package/src/core/primitives/TypedArray.js +27 -0
- package/src/core/process/ConcurrencyGate.d.ts +103 -0
- package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
- package/src/core/process/ConcurrencyGate.js +207 -0
- package/src/core/process/buildPromiseChain.d.ts +9 -4
- package/src/core/process/buildPromiseChain.d.ts.map +1 -1
- package/src/core/process/buildPromiseChain.js +4 -3
- package/src/core/process/executor/ConcurrentExecutor.d.ts +2 -0
- package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
- package/src/core/process/executor/ConcurrentExecutor.js +5 -0
- package/src/core/process/task/Task.d.ts +17 -7
- package/src/core/process/task/Task.d.ts.map +1 -1
- package/src/core/process/task/Task.js +12 -6
- package/src/engine/Engine.d.ts +17 -7
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +9 -4
- package/src/engine/EngineConfiguration.d.ts +33 -9
- package/src/engine/EngineConfiguration.d.ts.map +1 -1
- package/src/engine/EngineConfiguration.js +22 -4
- package/src/engine/EngineHarness.d.ts +22 -10
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +13 -8
- package/src/engine/EntityCreator.d.ts +26 -11
- package/src/engine/EntityCreator.d.ts.map +1 -1
- package/src/engine/EntityCreator.js +16 -13
- package/src/engine/animation/EntityAnimation.d.ts +1 -1
- package/src/engine/animation/EntityAnimation.d.ts.map +1 -1
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts +28 -18
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts.map +1 -1
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.js +9 -8
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.d.ts +18 -8
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.d.ts.map +1 -1
- package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +8 -7
- package/src/engine/animation/curve/editor/CurveEditorView.d.ts +22 -11
- package/src/engine/animation/curve/editor/CurveEditorView.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/CurveEditorView.js +7 -6
- package/src/engine/animation/curve/editor/DragHandler.d.ts +12 -7
- package/src/engine/animation/curve/editor/DragHandler.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/DragHandler.js +4 -3
- package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts +3 -2
- package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts +21 -10
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.js +10 -9
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts +20 -9
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.js +9 -8
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts +15 -7
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.js +7 -6
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts +39 -18
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +18 -17
- package/src/engine/animation/curve/editor/createPanTool.d.ts +13 -5
- package/src/engine/animation/curve/editor/createPanTool.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/createPanTool.js +5 -4
- package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts +19 -8
- package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts.map +1 -1
- package/src/engine/animation/curve/editor/createSelectionBoxTool.js +8 -7
- package/src/engine/animation/keyed2/AnimationTrackPlayback.d.ts +6 -2
- package/src/engine/animation/keyed2/AnimationTrackPlayback.d.ts.map +1 -1
- package/src/engine/animation/keyed2/AnimationTrackPlayback.js +4 -0
- package/src/engine/animation/removeEntityGenericEffect.d.ts +13 -6
- package/src/engine/animation/removeEntityGenericEffect.d.ts.map +1 -1
- package/src/engine/animation/removeEntityGenericEffect.js +6 -5
- package/src/engine/animation/removeEntityWithMeshParticlesEffect.d.ts +11 -5
- package/src/engine/animation/removeEntityWithMeshParticlesEffect.d.ts.map +1 -1
- package/src/engine/animation/removeEntityWithMeshParticlesEffect.js +5 -4
- package/src/engine/asset/Asset.d.ts +6 -3
- package/src/engine/asset/Asset.d.ts.map +1 -1
- package/src/engine/asset/Asset.js +4 -1
- package/src/engine/asset/AssetManager.d.ts +52 -21
- package/src/engine/asset/AssetManager.d.ts.map +1 -1
- package/src/engine/asset/AssetManager.js +30 -12
- package/src/engine/asset/AssetRequest.d.ts +4 -2
- package/src/engine/asset/AssetRequest.d.ts.map +1 -1
- package/src/engine/asset/AssetRequest.js +5 -0
- package/src/engine/asset/AssetRequestScope.d.ts +1 -0
- package/src/engine/asset/AssetRequestScope.d.ts.map +1 -1
- package/src/engine/asset/AssetRequestScope.js +4 -0
- package/src/engine/asset/AssetTransformer.d.ts +7 -1
- package/src/engine/asset/AssetTransformer.d.ts.map +1 -1
- package/src/engine/asset/AssetTransformer.js +5 -0
- package/src/engine/asset/PendingAsset.d.ts +8 -0
- package/src/engine/asset/PendingAsset.d.ts.map +1 -1
- package/src/engine/asset/PendingAsset.js +6 -0
- package/src/engine/asset/loaders/ArrayBufferLoader.d.ts +6 -3
- package/src/engine/asset/loaders/ArrayBufferLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/ArrayBufferLoader.js +2 -1
- package/src/engine/asset/loaders/AssetLoader.d.ts +8 -2
- package/src/engine/asset/loaders/AssetLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/AssetLoader.js +5 -0
- package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +10 -0
- package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +5 -2
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +2 -1
- package/src/engine/asset/preloader/AssetPreloader.d.ts +2 -1
- package/src/engine/asset/preloader/AssetPreloader.d.ts.map +1 -1
- package/src/engine/asset/preloader/AssetPreloader.js +4 -0
- package/src/engine/development/performance/MetricCollection.d.ts +11 -3
- package/src/engine/development/performance/MetricCollection.d.ts.map +1 -1
- package/src/engine/development/performance/MetricCollection.js +7 -2
- package/src/engine/ecs/Entity.d.ts +3 -2
- package/src/engine/ecs/Entity.d.ts.map +1 -1
- package/src/engine/ecs/Entity.js +9 -1
- package/src/engine/ecs/EntityComponentDataset.d.ts +8 -6
- package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +9 -0
- package/src/engine/ecs/EntityManager.d.ts +2 -1
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +5 -0
- package/src/engine/ecs/EntityObserver.d.ts +4 -0
- package/src/engine/ecs/EntityObserver.d.ts.map +1 -1
- package/src/engine/ecs/EntityObserver.js +4 -0
- package/src/engine/ecs/EntityReference.d.ts +4 -0
- package/src/engine/ecs/EntityReference.d.ts.map +1 -1
- package/src/engine/ecs/EntityReference.js +4 -0
- package/src/engine/ecs/System.d.ts +11 -2
- package/src/engine/ecs/System.d.ts.map +1 -1
- package/src/engine/ecs/System.js +6 -0
- package/src/engine/ecs/async/WorkerSystem.d.ts +10 -0
- package/src/engine/ecs/async/WorkerSystem.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.d.ts +7 -3
- package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.js +3 -2
- package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.d.ts +7 -3
- package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.js +3 -2
- package/src/engine/ecs/gui/menu/radial/RadialContextMenu.d.ts +36 -17
- package/src/engine/ecs/gui/menu/radial/RadialContextMenu.d.ts.map +1 -1
- package/src/engine/ecs/gui/menu/radial/RadialContextMenu.js +17 -16
- package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.d.ts +7 -3
- package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.d.ts.map +1 -1
- package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.js +3 -2
- package/src/engine/ecs/ik/InverseKinematics.d.ts +17 -8
- package/src/engine/ecs/ik/InverseKinematics.d.ts.map +1 -1
- package/src/engine/ecs/ik/InverseKinematics.js +8 -7
- package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.d.ts +9 -0
- package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.js +9 -0
- package/src/engine/ecs/storage/binary/BinaryClassUpgrader.d.ts +4 -0
- package/src/engine/ecs/storage/binary/BinaryClassUpgrader.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/BinaryClassUpgrader.js +4 -0
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts +10 -4
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +5 -0
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.d.ts +5 -2
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.js +2 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.d.ts +7 -3
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +3 -2
- package/src/engine/ecs/systems/ScriptSystem.d.ts +1 -0
- package/src/engine/ecs/systems/ScriptSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts +7 -2
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +8 -0
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSerializationUpgrader_0_1.d.ts +6 -0
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSerializationUpgrader_0_1.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.d.ts +3 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +5 -0
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts +3 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +5 -0
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts +4 -0
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +4 -0
- package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts +7 -2
- package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts +6 -2
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +6 -1
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.d.ts +9 -4
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.d.ts.map +1 -1
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +4 -3
- package/src/engine/ecs/transform/Transform64.d.ts +4 -0
- package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform64.js +4 -0
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
- package/src/engine/graphics/camera/CameraShakeBehavior.d.ts +20 -10
- package/src/engine/graphics/camera/CameraShakeBehavior.d.ts.map +1 -1
- package/src/engine/graphics/camera/CameraShakeBehavior.js +9 -8
- package/src/engine/graphics/camera/CameraShakeTraumaBehavior.d.ts +8 -4
- package/src/engine/graphics/camera/CameraShakeTraumaBehavior.d.ts.map +1 -1
- package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +3 -2
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +11 -5
- package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
- package/src/engine/graphics/camera/makeOrbitalCameraController.js +5 -4
- package/src/engine/graphics/canvas/canvas2d_draw_grid.d.ts +19 -9
- package/src/engine/graphics/canvas/canvas2d_draw_grid.d.ts.map +1 -1
- package/src/engine/graphics/canvas/canvas2d_draw_grid.js +9 -8
- package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts +17 -8
- package/src/engine/graphics/canvas/canvas2d_draw_label.d.ts.map +1 -1
- package/src/engine/graphics/canvas/canvas2d_draw_label.js +8 -7
- package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.d.ts +21 -10
- package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.d.ts.map +1 -1
- package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.js +10 -9
- package/src/engine/graphics/canvas/canvas2d_plot_data_line.d.ts +18 -8
- package/src/engine/graphics/canvas/canvas2d_plot_data_line.d.ts.map +1 -1
- package/src/engine/graphics/canvas/canvas2d_plot_data_line.js +8 -7
- package/src/engine/graphics/ecs/camera/Camera.d.ts +4 -0
- package/src/engine/graphics/ecs/camera/Camera.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/Camera.js +4 -0
- package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.d.ts +11 -5
- package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.js +5 -4
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -1
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +5 -5
- package/src/engine/graphics/ecs/particles/ParticleEffect.js +5 -5
- package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.d.ts +19 -9
- package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.js +9 -8
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +3 -0
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +3 -0
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.d.ts +9 -4
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +4 -3
- package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts +7 -1
- package/src/engine/graphics/render/frame_graph/FrameGraph.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FrameGraph.js +5 -0
- package/src/engine/graphics/render/frame_graph/FrameGraphNode.d.ts +4 -0
- package/src/engine/graphics/render/frame_graph/FrameGraphNode.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FrameGraphNode.js +4 -0
- package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts +9 -1
- package/src/engine/graphics/render/frame_graph/FramePassBuilder.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassBuilder.js +6 -0
- package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts +6 -0
- package/src/engine/graphics/render/frame_graph/FramePassNode.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassNode.js +5 -0
- package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts +7 -1
- package/src/engine/graphics/render/frame_graph/FramePassResources.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/FramePassResources.js +5 -0
- package/src/engine/graphics/render/frame_graph/IFrameGraphContext.d.ts +6 -2
- package/src/engine/graphics/render/frame_graph/IFrameGraphContext.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/IFrameGraphContext.js +4 -0
- package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts +13 -5
- package/src/engine/graphics/render/frame_graph/ResourceEntry.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/ResourceEntry.js +7 -1
- package/src/engine/graphics/render/frame_graph/ResourceNode.d.ts +9 -3
- package/src/engine/graphics/render/frame_graph/ResourceNode.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/ResourceNode.js +6 -1
- package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts +5 -1
- package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/resource/RenderResourceManager.js +4 -0
- package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.d.ts +7 -3
- package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.d.ts.map +1 -1
- package/src/engine/graphics/render/frame_graph/resource/ResourceDescriptor.js +6 -2
- package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts +5 -2
- package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/CachingTextureAtlas.js +2 -1
- package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.d.ts +9 -4
- package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +4 -3
- package/src/engine/graphics/texture/sampler/Sampler2D.d.ts +4 -0
- package/src/engine/graphics/texture/sampler/Sampler2D.d.ts.map +1 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +4 -0
- package/src/engine/graphics/texture/sampler/debug/prototypeSamplerFiltering.js +3 -2
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +0 -5
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine.d.ts +6 -0
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine.js +9 -0
- package/src/engine/graphics3/ParticipatingMedia.d.ts +9 -4
- package/src/engine/graphics3/ParticipatingMedia.d.ts.map +1 -1
- package/src/engine/graphics3/ParticipatingMedia.js +4 -3
- package/src/engine/graphics3/ShadeCameraAdapter.d.ts +5 -1
- package/src/engine/graphics3/ShadeCameraAdapter.d.ts.map +1 -1
- package/src/engine/graphics3/ShadeCameraAdapter.js +4 -0
- package/src/engine/graphics3/TooltipComponentSystem.d.ts +13 -6
- package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
- package/src/engine/graphics3/TooltipComponentSystem.js +6 -5
- package/src/engine/graphics3/VolumetricLightMap.d.ts +5 -2
- package/src/engine/graphics3/VolumetricLightMap.d.ts.map +1 -1
- package/src/engine/graphics3/VolumetricLightMap.js +2 -1
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +74 -101
- package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
- package/src/engine/input/devices/PointerDevice.js +7 -6
- package/src/engine/input/devices/gamepad/GamepadHandle.d.ts +4 -0
- package/src/engine/input/devices/gamepad/GamepadHandle.d.ts.map +1 -1
- package/src/engine/input/devices/gamepad/GamepadHandle.js +4 -0
- package/src/engine/input/devices/touch/observePinch.d.ts +17 -8
- package/src/engine/input/devices/touch/observePinch.d.ts.map +1 -1
- package/src/engine/input/devices/touch/observePinch.js +8 -7
- package/src/engine/input/ecs/components/InputBinding.d.ts +11 -5
- package/src/engine/input/ecs/components/InputBinding.d.ts.map +1 -1
- package/src/engine/input/ecs/components/InputBinding.js +5 -4
- package/src/engine/input/ecs/ism/InputMapSystem.d.ts +4 -0
- package/src/engine/input/ecs/ism/InputMapSystem.d.ts.map +1 -1
- package/src/engine/input/ecs/systems/InputControllerSystem.d.ts +1 -1
- package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
- package/src/engine/input/ecs/util/TerrainCameraTargetSampler.d.ts +5 -2
- package/src/engine/input/ecs/util/TerrainCameraTargetSampler.d.ts.map +1 -1
- package/src/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -1
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts +9 -4
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +4 -3
- package/src/engine/intelligence/behavior/ecs/SendEventBehavior.d.ts +9 -4
- package/src/engine/intelligence/behavior/ecs/SendEventBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/SendEventBehavior.js +4 -3
- package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.d.ts +9 -4
- package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/util/syncExecuteBehaviorToCompletion.js +4 -3
- package/src/engine/intelligence/mcts/MonteCarlo.d.ts +19 -9
- package/src/engine/intelligence/mcts/MonteCarlo.d.ts.map +1 -1
- package/src/engine/intelligence/mcts/MonteCarlo.js +9 -8
- package/src/engine/intelligence/optimization/RandomOptimizer.d.ts +13 -6
- package/src/engine/intelligence/optimization/RandomOptimizer.d.ts.map +1 -1
- package/src/engine/intelligence/optimization/RandomOptimizer.js +6 -5
- package/src/engine/interpolation/InterpolationSystem.d.ts +4 -0
- package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +5 -2
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts.map +1 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +6 -2
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts.map +1 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.js +4 -0
- package/src/engine/knowledge/database/StaticKnowledgeDatabase.d.ts +7 -4
- package/src/engine/knowledge/database/StaticKnowledgeDatabase.d.ts.map +1 -1
- package/src/engine/knowledge/database/StaticKnowledgeDatabase.js +6 -0
- package/src/engine/makeSimpleTaskProgressView.d.ts +10 -4
- package/src/engine/makeSimpleTaskProgressView.d.ts.map +1 -1
- package/src/engine/makeSimpleTaskProgressView.js +4 -3
- package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts +20 -9
- package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/navmesh_build_topology.js +9 -8
- package/src/engine/network/sim/ActionLog.d.ts +1 -2
- package/src/engine/network/sim/ActionLog.d.ts.map +1 -1
- package/src/engine/network/sim/ActionLog.js +0 -1
- package/src/engine/network/state/InputRing.d.ts +1 -2
- package/src/engine/network/state/InputRing.d.ts.map +1 -1
- package/src/engine/network/state/InputRing.js +0 -1
- package/src/engine/notify/Notification.d.ts +15 -9
- package/src/engine/notify/Notification.d.ts.map +1 -1
- package/src/engine/notify/Notification.js +5 -4
- package/src/engine/options/OptionAbstract.d.ts +4 -0
- package/src/engine/options/OptionAbstract.d.ts.map +1 -1
- package/src/engine/options/OptionAbstract.js +4 -0
- package/src/engine/options/OptionsView.d.ts +10 -4
- package/src/engine/options/OptionsView.d.ts.map +1 -1
- package/src/engine/options/OptionsView.js +4 -3
- package/src/engine/physics/ccd/linear_sweep.d.ts +4 -7
- package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
- package/src/engine/physics/ccd/linear_sweep.js +3 -1
- package/src/engine/physics/cloth/MEASUREMENTS.md +2239 -0
- package/src/engine/physics/cloth/PLAN.md +1967 -0
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
- package/src/engine/physics/cloth/ecs/Cloth.d.ts +145 -0
- package/src/engine/physics/cloth/ecs/Cloth.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/Cloth.js +212 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
- package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts +208 -0
- package/src/engine/physics/cloth/ecs/ClothDynamics.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothDynamics.js +331 -0
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.d.ts +10 -0
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -0
- package/src/engine/physics/cloth/ecs/ClothExclude.d.ts +45 -0
- package/src/engine/physics/cloth/ecs/ClothExclude.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothExclude.js +59 -0
- package/src/engine/physics/cloth/ecs/ClothFlags.d.ts +10 -0
- package/src/engine/physics/cloth/ecs/ClothFlags.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothFlags.js +47 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +429 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +178 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +186 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts +235 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_map.js +271 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +59 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +70 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
- package/src/engine/physics/cloth/playground/README.md +339 -0
- package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts +58 -0
- package/src/engine/physics/cloth/playground/cloth_playground_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/cloth_playground_build.js +333 -0
- package/src/engine/physics/cloth/playground/cloth_playground_draw.d.ts +79 -0
- package/src/engine/physics/cloth/playground/cloth_playground_draw.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/cloth_playground_draw.js +519 -0
- package/src/engine/physics/cloth/playground/collide.html +178 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_build.js +315 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_main.js +720 -0
- package/src/engine/physics/cloth/playground/garment.html +182 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_build.js +359 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_main.js +633 -0
- package/src/engine/physics/cloth/playground/index.html +200 -0
- package/src/engine/physics/cloth/playground/main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/main.js +876 -0
- package/src/engine/physics/cloth/playground/rig.html +187 -0
- package/src/engine/physics/cloth/playground/rig_build.d.ts +81 -0
- package/src/engine/physics/cloth/playground/rig_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/rig_build.js +296 -0
- package/src/engine/physics/cloth/playground/rig_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/rig_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/rig_main.js +955 -0
- package/src/engine/physics/cloth/solver/ClothState.d.ts +526 -0
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/ClothState.js +967 -0
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts +67 -0
- package/src/engine/physics/cloth/solver/cloth_color_particles.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_color_particles.js +220 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +16 -0
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +216 -0
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +204 -0
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +213 -0
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +122 -0
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_step.js +401 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts +54 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_vertex_accumulator.js +56 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.d.ts +125 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_bend_row.js +383 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts +112 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_leash_row.js +346 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.d.ts +94 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_stretch_row.js +383 -0
- package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts +27 -0
- package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.js +104 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +5 -7
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +4 -1
- package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts +6 -0
- package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.d.ts.map +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/narrowphase/compute_penetration.d.ts +26 -23
- package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/compute_penetration.js +25 -4
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts +16 -23
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/narrowphase_step.js +15 -4
- package/src/engine/physics/narrowphase/refine_ray_concave.d.ts +4 -6
- package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_concave.js +3 -1
- package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +6 -6
- package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_hit.js +5 -1
- package/src/engine/physics/queries/shape_cast.d.ts +9 -7
- package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
- package/src/engine/physics/queries/shape_cast.js +8 -1
- package/src/engine/platform/EnginePlatform.d.ts +4 -0
- package/src/engine/platform/EnginePlatform.d.ts.map +1 -1
- package/src/engine/platform/EnginePlatform.js +4 -0
- package/src/engine/plugin/EnginePlugin.d.ts +9 -0
- package/src/engine/plugin/EnginePlugin.d.ts.map +1 -1
- package/src/engine/plugin/EnginePlugin.js +9 -0
- package/src/engine/plugin/EnginePluginManager.d.ts +13 -2
- package/src/engine/plugin/EnginePluginManager.d.ts.map +1 -1
- package/src/engine/plugin/EnginePluginManager.js +10 -0
- package/src/engine/save/StorageBackedList.d.ts +8 -4
- package/src/engine/save/StorageBackedList.d.ts.map +1 -1
- package/src/engine/save/StorageBackedList.js +3 -2
- package/src/engine/scene/Scene.d.ts +10 -0
- package/src/engine/scene/Scene.d.ts.map +1 -1
- package/src/engine/scene/Scene.js +7 -0
- package/src/engine/scene/SceneManager.d.ts +4 -0
- package/src/engine/scene/SceneManager.d.ts.map +1 -1
- package/src/engine/scene/SceneManager.js +4 -0
- package/src/engine/scene/SerializedScene.d.ts +8 -4
- package/src/engine/scene/SerializedScene.d.ts.map +1 -1
- package/src/engine/scene/SerializedScene.js +3 -2
- package/src/engine/scene/transitionToScene.d.ts +11 -5
- package/src/engine/scene/transitionToScene.d.ts.map +1 -1
- package/src/engine/scene/transitionToScene.js +5 -4
- package/src/engine/simulation/Ticker.d.ts +5 -2
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +2 -1
- package/src/engine/sound/SoundEngine.d.ts +4 -0
- package/src/engine/sound/SoundEngine.d.ts.map +1 -1
- package/src/engine/sound/SoundEngine.js +4 -0
- package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.d.ts +7 -3
- package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.d.ts.map +1 -1
- package/src/engine/sound/material/concrete/json/deserializeSoundMaterialFromJSON.js +3 -2
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +10 -0
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
- package/src/engine/sound/sopra/SopraEngine.d.ts +5 -0
- package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -1
- package/src/engine/sound/sopra/SopraEngine.js +8 -0
- package/src/engine/sound/sopra/definition/BusDefinition.d.ts +4 -0
- package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/BusDefinition.js +4 -0
- package/src/engine/sound/sopra/definition/EventDescription.d.ts +1 -0
- package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/EventDescription.js +4 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +6 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +5 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +1 -1
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts +1 -0
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +10 -2
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +7 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +1 -1
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +1 -1
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts +4 -0
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/BusGraph.js +4 -0
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts +9 -1
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/EventInstance.js +11 -0
- package/src/engine/sound/sopra/runtime/VoiceManager.d.ts +2 -0
- package/src/engine/sound/sopra/runtime/VoiceManager.d.ts.map +1 -1
- package/src/engine/sound/sopra/runtime/VoiceManager.js +5 -0
- package/src/engine/ui/DraggableAspect.d.ts +14 -6
- package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
- package/src/engine/ui/DraggableAspect.js +6 -5
- package/src/engine/ui/GUIEngine.d.ts +73 -26
- package/src/engine/ui/GUIEngine.d.ts.map +1 -1
- package/src/engine/ui/GUIEngine.js +37 -19
- package/src/engine/ui/bindings/DomElementBindingDescription.d.ts +7 -3
- package/src/engine/ui/bindings/DomElementBindingDescription.d.ts.map +1 -1
- package/src/engine/ui/bindings/DomElementBindingDescription.js +3 -2
- package/src/engine/ui/modal/ModalStack.d.ts +4 -0
- package/src/engine/ui/modal/ModalStack.d.ts.map +1 -1
- package/src/engine/ui/modal/ModalStack.js +4 -0
- package/src/engine/ui/notification/AnimatedObjectEmitter.d.ts +4 -0
- package/src/engine/ui/notification/AnimatedObjectEmitter.d.ts.map +1 -1
- package/src/engine/ui/notification/AnimatedObjectEmitter.js +4 -0
- package/src/engine/ui/notification/NotificationManager.d.ts +21 -8
- package/src/engine/ui/notification/NotificationManager.d.ts.map +1 -1
- package/src/engine/ui/notification/NotificationManager.js +10 -3
- package/src/engine/ui/notification/ViewEmitter.d.ts +8 -2
- package/src/engine/ui/notification/ViewEmitter.d.ts.map +1 -1
- package/src/engine/ui/notification/ViewEmitter.js +6 -1
- package/src/engine/ui/scene/SceneGUIContext.d.ts +4 -0
- package/src/engine/ui/scene/SceneGUIContext.d.ts.map +1 -1
- package/src/engine/ui/scene/SceneGUIContext.js +4 -0
- package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts +9 -4
- package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.d.ts.map +1 -1
- package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +4 -3
- package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts +9 -4
- package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.d.ts.map +1 -1
- package/src/generation/grid/actions/ContinuousGridCellActionWriteObstacle.js +4 -3
- package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts +9 -4
- package/src/generation/grid/generation/GridTaskApplyActionToCells.d.ts.map +1 -1
- package/src/generation/grid/generation/GridTaskApplyActionToCells.js +4 -3
- package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.d.ts +9 -4
- package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.d.ts.map +1 -1
- package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +4 -3
- package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts +11 -5
- package/src/generation/grid/generation/grid/select/CellSupplierBestN.d.ts.map +1 -1
- package/src/generation/grid/generation/grid/select/CellSupplierBestN.js +5 -4
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts +9 -4
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +12 -10
- package/src/generation/grid/generation/util/buildDistanceMapToObjective.d.ts +19 -9
- package/src/generation/grid/generation/util/buildDistanceMapToObjective.d.ts.map +1 -1
- package/src/generation/grid/generation/util/buildDistanceMapToObjective.js +9 -8
- package/src/generation/grid/generation/util/buildPathFromDistanceMap.d.ts +17 -8
- package/src/generation/grid/generation/util/buildPathFromDistanceMap.d.ts.map +1 -1
- package/src/generation/grid/generation/util/buildPathFromDistanceMap.js +8 -7
- package/src/generation/markers/GridActionRuleSet.d.ts +11 -5
- package/src/generation/markers/GridActionRuleSet.d.ts.map +1 -1
- package/src/generation/markers/GridActionRuleSet.js +5 -4
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts +9 -4
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.d.ts.map +1 -1
- package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +4 -3
- package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts +9 -4
- package/src/generation/markers/actions/MarkerNodeActionImaginary.d.ts.map +1 -1
- package/src/generation/markers/actions/MarkerNodeActionImaginary.js +4 -3
- package/src/generation/markers/actions/MarkerProcessingRule.d.ts +11 -5
- package/src/generation/markers/actions/MarkerProcessingRule.d.ts.map +1 -1
- package/src/generation/markers/actions/MarkerProcessingRule.js +5 -4
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts +5 -2
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.d.ts.map +1 -1
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +2 -1
- package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts +13 -6
- package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.d.ts.map +1 -1
- package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +6 -5
- package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.d.ts +7 -3
- package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.d.ts.map +1 -1
- package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.js +3 -2
- package/src/generation/placement/GridCellPlacementRule.d.ts +15 -7
- package/src/generation/placement/GridCellPlacementRule.d.ts.map +1 -1
- package/src/generation/placement/GridCellPlacementRule.js +7 -6
- package/src/shade/descriptor/ObjectDescriptorBase.d.ts +8 -3
- package/src/shade/descriptor/ObjectDescriptorBase.d.ts.map +1 -1
- package/src/shade/descriptor/ObjectDescriptorBase.js +7 -2
- package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.d.ts +12 -0
- package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +8 -0
- package/src/shade/descriptor/binding/BufferBindingLayout.d.ts +11 -6
- package/src/shade/descriptor/binding/BufferBindingLayout.d.ts.map +1 -1
- package/src/shade/descriptor/binding/BufferBindingLayout.js +5 -4
- package/src/shade/descriptor/binding/SamplerBindingLayout.d.ts +2 -2
- package/src/shade/descriptor/binding/SamplerBindingLayout.d.ts.map +1 -1
- package/src/shade/descriptor/binding/SamplerBindingLayout.js +1 -1
- package/src/shade/descriptor/binding/StorageTextureBindingLayout.d.ts +2 -2
- package/src/shade/descriptor/binding/StorageTextureBindingLayout.d.ts.map +1 -1
- package/src/shade/descriptor/binding/StorageTextureBindingLayout.js +1 -1
- package/src/shade/descriptor/binding/TextureBindingLayout.d.ts +4 -4
- package/src/shade/descriptor/binding/TextureBindingLayout.d.ts.map +1 -1
- package/src/shade/descriptor/binding/TextureBindingLayout.js +2 -2
- package/src/shade/descriptor/blend/BlendComponent.d.ts +6 -6
- package/src/shade/descriptor/blend/BlendComponent.d.ts.map +1 -1
- package/src/shade/descriptor/blend/BlendComponent.js +3 -3
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts +12 -0
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +8 -0
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -5
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +14 -4
- package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts +4 -1
- package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/render/DepthStencilState.js +3 -0
- package/src/shade/descriptor/pipeline/render/FragmentState.d.ts +5 -2
- package/src/shade/descriptor/pipeline/render/FragmentState.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/render/FragmentState.js +4 -1
- package/src/shade/descriptor/pipeline/render/PrimitiveState.d.ts +8 -8
- package/src/shade/descriptor/pipeline/render/PrimitiveState.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/render/PrimitiveState.js +4 -4
- package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts +16 -4
- package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/render/StencilFaceState.js +12 -0
- package/src/shade/descriptor/pipeline/render/VertexState.d.ts +5 -2
- package/src/shade/descriptor/pipeline/render/VertexState.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/render/VertexState.js +4 -1
- package/src/shade/descriptor/texture/SamplerDescriptor.d.ts +24 -6
- package/src/shade/descriptor/texture/SamplerDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/texture/SamplerDescriptor.js +18 -0
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -2
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/texture/TextureDescriptor.js +1 -1
- package/src/shade/device/ShadeGPUCommandContext.d.ts +46 -12
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +28 -8
- package/src/shade/device/graph/GraphicsExecutionContext.d.ts +6 -0
- package/src/shade/device/graph/GraphicsExecutionContext.d.ts.map +1 -1
- package/src/shade/device/graph/GraphicsExecutionContext.js +5 -0
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts +13 -6
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/TextureResourceDescriptor.js +6 -5
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +6 -0
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -1
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +5 -0
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +6 -0
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -1
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +5 -0
- package/src/shade/device/pipeline/ComputePipelineManager.d.ts +9 -1
- package/src/shade/device/pipeline/ComputePipelineManager.d.ts.map +1 -1
- package/src/shade/device/pipeline/ComputePipelineManager.js +6 -0
- package/src/shade/device/pipeline/PipelineLayoutManager.d.ts +6 -0
- package/src/shade/device/pipeline/PipelineLayoutManager.d.ts.map +1 -1
- package/src/shade/device/pipeline/PipelineLayoutManager.js +5 -0
- package/src/shade/device/pipeline/RenderPipelineManager.d.ts +7 -1
- package/src/shade/device/pipeline/RenderPipelineManager.d.ts.map +1 -1
- package/src/shade/device/pipeline/RenderPipelineManager.js +5 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts +4 -0
- package/src/shade/device/shader/ShaderModuleCompiler.d.ts.map +1 -1
- package/src/shade/device/shader/ShaderModuleCompiler.js +4 -0
- package/src/shade/device/timing/profile/GPUFrameRecorder.d.ts +6 -0
- package/src/shade/device/timing/profile/GPUFrameRecorder.d.ts.map +1 -1
- package/src/shade/device/timing/profile/GPUFrameRecorder.js +5 -0
- package/src/shade/device/timing/profile/GPUProfileFrame.d.ts +6 -0
- package/src/shade/device/timing/profile/GPUProfileFrame.d.ts.map +1 -1
- package/src/shade/device/timing/profile/GPUProfileFrame.js +5 -0
- package/src/shade/device/timing/profile/GPUProfileSession.d.ts +1 -0
- package/src/shade/device/timing/profile/GPUProfileSession.d.ts.map +1 -1
- package/src/shade/device/timing/profile/GPUProfileSession.js +4 -0
- package/src/shade/device/timing/profile/GPUProfileSpan.d.ts +4 -0
- package/src/shade/device/timing/profile/GPUProfileSpan.d.ts.map +1 -1
- package/src/shade/device/timing/profile/GPUProfileSpan.js +4 -0
- package/src/shade/playground/add_random_meshes.d.ts +19 -8
- package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
- package/src/shade/playground/add_random_meshes.js +8 -7
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts +4 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -1
- package/src/shade/playground/particle_ecs/index.html +0 -2
- package/src/shade/playground/particle_ecs/main.js +8 -29
- package/src/shade/playground/particle_system/main.js +8 -21
- package/src/shade/playground/particle_system/particle_prototype.js +8 -8
- package/src/shade/playground/particle_system/particle_scene.d.ts +0 -61
- package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_scene.js +0 -57
- package/src/shade/playground/ssr_variance/reference.d.ts +1 -1
- package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -1
- package/src/shade/playground/vgeo_viewer/README.md +29 -2
- package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +1 -1
- package/src/shade/playground/vgeo_viewer/cut_geometry.js +3 -40
- package/src/shade/playground/vgeo_viewer/main.js +101 -50
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts +19 -0
- package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +1 -1
- package/src/shade/playground/vgeo_viewer/select_cut.js +53 -9
- package/src/shade/renderer/GPUSamplerManager.d.ts +4 -0
- package/src/shade/renderer/GPUSamplerManager.d.ts.map +1 -1
- package/src/shade/renderer/GPUSamplerManager.js +4 -0
- package/src/shade/renderer/GraphicsContext.d.ts +2 -0
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +5 -0
- package/src/shade/renderer/Renderer.d.ts +14 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +70 -67
- package/src/shade/renderer/ResourceManager.d.ts +10 -0
- package/src/shade/renderer/ResourceManager.d.ts.map +1 -1
- package/src/shade/renderer/ResourceManager.js +7 -0
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +18 -11
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +2063 -1958
- package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +2 -0
- package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
- package/src/shade/renderer/animation/ShadeAnimationChannel.js +5 -0
- package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +4 -0
- package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
- package/src/shade/renderer/animation/ShadeAnimationClip.js +4 -0
- package/src/shade/renderer/animation/Skin.d.ts +6 -0
- package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
- package/src/shade/renderer/animation/Skin.js +5 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +48 -0
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +201 -14
- package/src/shade/renderer/binding/BindGroupDescriptor.d.ts +2 -1
- package/src/shade/renderer/binding/BindGroupDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/binding/BindGroupDescriptor.js +4 -0
- package/src/shade/renderer/binding/BindGroupManager.d.ts +1 -0
- package/src/shade/renderer/binding/BindGroupManager.d.ts.map +1 -1
- package/src/shade/renderer/binding/BindGroupManager.js +4 -0
- package/src/shade/renderer/buffer/GPUBufferAllocatorNative.d.ts +4 -0
- package/src/shade/renderer/buffer/GPUBufferAllocatorNative.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferAllocatorNative.js +4 -0
- package/src/shade/renderer/buffer/GPUTypedBuffer.d.ts +20 -8
- package/src/shade/renderer/buffer/GPUTypedBuffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUTypedBuffer.js +11 -6
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.d.ts +15 -7
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +7 -6
- package/src/shade/renderer/buffer/inspect_gpu_buffer.d.ts +26 -12
- package/src/shade/renderer/buffer/inspect_gpu_buffer.d.ts.map +1 -1
- package/src/shade/renderer/buffer/inspect_gpu_buffer.js +12 -10
- package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.d.ts +13 -6
- package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.d.ts.map +1 -1
- package/src/shade/renderer/buffer/inspect_gpu_buffer_typed.js +6 -5
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +13 -5
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +201 -66
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +97 -3
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +419 -2
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +4 -0
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +4 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts +11 -4
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +9 -3
- package/src/shade/renderer/camera/CameraManager.d.ts +4 -0
- package/src/shade/renderer/camera/CameraManager.d.ts.map +1 -1
- package/src/shade/renderer/camera/CameraManager.js +4 -0
- package/src/shade/renderer/camera/GPUCameraContext.d.ts +4 -2
- package/src/shade/renderer/camera/GPUCameraContext.d.ts.map +1 -1
- package/src/shade/renderer/camera/GPUCameraContext.js +5 -0
- package/src/shade/renderer/extension/FrameContext.d.ts +15 -5
- package/src/shade/renderer/extension/FrameContext.d.ts.map +1 -1
- package/src/shade/renderer/extension/FrameContext.js +7 -0
- package/src/shade/renderer/extension/FrameRecord.d.ts +7 -1
- package/src/shade/renderer/extension/FrameRecord.d.ts.map +1 -1
- package/src/shade/renderer/extension/FrameRecord.js +5 -0
- package/src/shade/renderer/extension/RenderExtension.d.ts +4 -0
- package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
- package/src/shade/renderer/extension/RenderExtension.js +4 -0
- package/src/shade/renderer/geometry/Attribute.d.ts +2 -2
- package/src/shade/renderer/geometry/Attribute.d.ts.map +1 -1
- package/src/shade/renderer/geometry/Attribute.js +1 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.d.ts +30 -2
- package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryManager.js +642 -591
- package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts +4 -0
- package/src/shade/renderer/geometry/GPUGeometryMetadata.d.ts.map +1 -1
- package/src/shade/renderer/geometry/GPUGeometryMetadata.js +4 -0
- package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts +7 -3
- package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUBLASRefitBatch.js +3 -2
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +13 -4
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -730
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
- package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.d.ts +11 -5
- package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/bvh_to_gpu_buffer.js +5 -4
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +29 -4
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +195 -33
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts +1 -0
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +4 -0
- package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts +13 -6
- package/src/shade/renderer/geometry/meshlet_batch_to_bvh.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet_batch_to_bvh.js +6 -5
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -0
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -0
- package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts +13 -6
- package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +6 -5
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +204 -14
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +803 -51
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +11 -5
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +5 -4
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +12 -5
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts +11 -5
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +5 -4
- package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.d.ts +5 -1
- package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/GPULightProbeVolume.js +4 -0
- package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.d.ts +4 -0
- package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/LightProbeVolume.js +4 -0
- package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts +7 -1
- package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +5 -0
- package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.d.ts +11 -5
- package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.js +5 -4
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +9 -4
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +4 -3
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts +9 -4
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +4 -3
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +7 -3
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +3 -2
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts +28 -8
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +17 -6
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts +13 -6
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/border/graph_lpv_paint_border_depth.js +6 -5
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts +15 -7
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +7 -6
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts +17 -8
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +8 -7
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts +17 -8
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +8 -7
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts +15 -7
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +7 -6
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts +19 -9
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +9 -8
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts +9 -4
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/prefix_sum/v1/graph_prefix_scan_csdldf.js +4 -3
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts +11 -5
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +5 -4
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +9 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +6 -0
- package/src/shade/renderer/hiz/generate_downsampler_code.d.ts +11 -5
- package/src/shade/renderer/hiz/generate_downsampler_code.d.ts.map +1 -1
- package/src/shade/renderer/hiz/generate_downsampler_code.js +5 -4
- package/src/shade/renderer/hiz/graph_build_hzb.d.ts +13 -6
- package/src/shade/renderer/hiz/graph_build_hzb.d.ts.map +1 -1
- package/src/shade/renderer/hiz/graph_build_hzb.js +6 -5
- package/src/shade/renderer/light/GPULightCollection.d.ts +4 -1
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +6 -0
- package/src/shade/renderer/light/LightCollection.d.ts +9 -3
- package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/LightCollection.js +5 -0
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts +11 -5
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +17 -14
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts +13 -6
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +6 -5
- package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts +13 -6
- package/src/shade/renderer/light/cluster/graph_build_light_clusters.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/graph_build_light_clusters.js +6 -5
- package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts +7 -3
- package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/graph_filter_environment_map.js +3 -2
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts +11 -5
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +5 -4
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/material/GPUMaterialContext.d.ts +17 -1
- package/src/shade/renderer/material/GPUMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialContext.js +10 -0
- package/src/shade/renderer/material/GPUMaterialManager.d.ts +19 -5
- package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
- package/src/shade/renderer/material/GPUMaterialManager.js +19 -4
- package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -1
- package/src/shade/renderer/material/ShadeMaterial.d.ts.map +1 -1
- package/src/shade/renderer/material/ShadeMaterial.js +4 -0
- package/src/shade/renderer/material/StandardShadeMaterial.d.ts +6 -0
- package/src/shade/renderer/material/StandardShadeMaterial.d.ts.map +1 -1
- package/src/shade/renderer/material/StandardShadeMaterial.js +5 -0
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -0
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -0
- package/src/shade/renderer/particles/DESIGN.md +82 -69
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +93 -48
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +117 -176
- package/src/shade/renderer/particles/ParticleConstants.d.ts +6 -12
- package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
- package/src/shade/renderer/particles/ParticleConstants.js +6 -13
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +4 -4
- package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +6 -6
- package/src/shade/renderer/particles/coherence/particle_program_buckets.d.ts +2 -1
- package/src/shade/renderer/particles/coherence/particle_program_buckets.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/particle_program_buckets.js +6 -8
- package/src/shade/renderer/particles/coherence/shader_particle_bucket.d.ts.map +1 -1
- package/src/shade/renderer/particles/coherence/shader_particle_bucket.js +4 -3
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +10 -14
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +10 -14
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +6 -5
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +6 -5
- package/src/shade/renderer/particles/graph_particles.d.ts +19 -32
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +18 -25
- package/src/shade/renderer/particles/graph_particles_avboit.js +16 -16
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +3 -2
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +31 -27
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +4 -4
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +4 -4
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +4 -4
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts +7 -6
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +7 -6
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +4 -3
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +4 -3
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +2 -2
- package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +10 -10
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +3 -3
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +2 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +13 -16
- package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_render.js +22 -19
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts +10 -3
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +12 -2
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts +7 -3
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +3 -2
- package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.d.ts +11 -5
- package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +5 -4
- package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts +13 -6
- package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +11 -9
- package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts +31 -15
- package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/LigmaDenoiser.js +15 -14
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts +21 -10
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/debug/graph_pass_debug_reprojection.js +10 -9
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts +17 -8
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +8 -7
- package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.d.ts +6 -0
- package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +5 -0
- package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.d.ts +6 -0
- package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +5 -0
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts +14 -6
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +6 -4
- package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts +13 -6
- package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/graph_build_depth_mipmap.js +6 -5
- package/src/shade/renderer/postprocess/gtao/render_copy_texture.d.ts +28 -13
- package/src/shade/renderer/postprocess/gtao/render_copy_texture.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/render_copy_texture.js +13 -11
- package/src/shade/renderer/postprocess/motion_blur/MotionBlur.d.ts +4 -0
- package/src/shade/renderer/postprocess/motion_blur/MotionBlur.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +4 -0
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +7 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.js +5 -0
- package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts +9 -4
- package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/graph_build_depth_max_pyramid.js +4 -3
- package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.d.ts +13 -6
- package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_graph_prefilter_color.js +6 -5
- package/src/shade/renderer/postprocess/taa/TAA.d.ts +15 -7
- package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/taa/TAA.js +7 -6
- package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.d.ts +13 -6
- package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/velocity/graph_add_camera_velocity.js +6 -5
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts +11 -5
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +5 -4
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts +11 -5
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +5 -4
- package/src/shade/renderer/rasterize/execute_rasterization_jobs.d.ts +12 -5
- package/src/shade/renderer/rasterize/execute_rasterization_jobs.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/execute_rasterization_jobs.js +5 -4
- package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts +2 -0
- package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/GPUCollectionLimits.js +5 -0
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts +11 -5
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +5 -4
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts +9 -4
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +4 -3
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts +11 -5
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +5 -4
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts +15 -7
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +7 -6
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.d.ts +15 -7
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_two_way.js +7 -6
- package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.d.ts +13 -6
- package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_expand.js +6 -5
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts +17 -8
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +8 -7
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts +13 -6
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +6 -5
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts +21 -10
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +10 -9
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +13 -6
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +6 -5
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.d.ts +17 -8
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_one_way.js +8 -7
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.d.ts +13 -6
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_triangles_filter_two_way.js +6 -5
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts +15 -7
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/graph_expand_meshes_to_meshlets.js +7 -6
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts +11 -5
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +5 -4
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts +9 -4
- 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 +4 -3
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +80 -37
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +37 -33
- package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts +28 -13
- package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +13 -12
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +12 -11
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +5 -4
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts +9 -4
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +4 -3
- package/src/shade/renderer/restir/di/ReSTIRDI.d.ts +10 -0
- package/src/shade/renderer/restir/di/ReSTIRDI.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/ReSTIRDI.js +7 -0
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +2 -0
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +5 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +4 -0
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +15 -0
- package/src/shade/renderer/scene/InstanceBatch.d.ts +11 -3
- package/src/shade/renderer/scene/InstanceBatch.d.ts.map +1 -1
- package/src/shade/renderer/scene/InstanceBatch.js +6 -0
- package/src/shade/renderer/scene/Mesh.d.ts +8 -2
- package/src/shade/renderer/scene/Mesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/Mesh.js +6 -1
- package/src/shade/renderer/scene/SceneManager.d.ts +6 -0
- package/src/shade/renderer/scene/SceneManager.d.ts.map +1 -1
- package/src/shade/renderer/scene/SceneManager.js +5 -0
- package/src/shade/renderer/scene/SkinnedMesh.d.ts +4 -0
- package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/SkinnedMesh.js +4 -0
- package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +7 -3
- package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
- package/src/shade/renderer/scene/serialization/serialize_scene.js +3 -2
- package/src/shade/renderer/shader/ComputeShader.d.ts +64 -29
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +29 -23
- package/src/shade/renderer/shader/ImageShader.d.ts +9 -4
- package/src/shade/renderer/shader/ImageShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ImageShader.js +4 -3
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts +10 -4
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.js +4 -3
- package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts +7 -3
- package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/brdf/dfg/generate_dfg_texture.js +6 -4
- package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.d.ts +13 -6
- package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/fullscreen/create_full_quad_pipeline_descriptor.js +6 -5
- package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.d.ts +13 -6
- package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/compute/graph_compute_indirect_pass.js +6 -5
- package/src/shade/renderer/shader/graph/compute/graph_compute_pass.d.ts +13 -6
- package/src/shade/renderer/shader/graph/compute/graph_compute_pass.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/compute/graph_compute_pass.js +6 -5
- package/src/shade/renderer/shader/graph/graph_image_pass.d.ts +27 -13
- package/src/shade/renderer/shader/graph/graph_image_pass.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_image_pass.js +13 -12
- package/src/shade/renderer/shader/graph/graph_import_raw_buffer.d.ts +15 -7
- package/src/shade/renderer/shader/graph/graph_import_raw_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_import_raw_buffer.js +7 -6
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts +13 -6
- 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 +6 -5
- package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.d.ts +7 -3
- package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/pass/RenderPassColorAttachmentDescriptor.js +3 -2
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +49 -23
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +23 -20
- package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts +6 -0
- package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceDescriptor.js +9 -0
- package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts +11 -2
- package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.js +7 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts +10 -3
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +9 -2
- package/src/shade/renderer/shader/type/WGSLAttribute.d.ts +2 -2
- package/src/shade/renderer/shader/type/WGSLAttribute.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WGSLAttribute.js +1 -1
- package/src/shade/renderer/shader/type/WGSLStructField.d.ts +6 -2
- package/src/shade/renderer/shader/type/WGSLStructField.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WGSLStructField.js +5 -1
- package/src/shade/renderer/shader/type/WebGPUArray.d.ts +0 -2
- package/src/shade/renderer/shader/type/WebGPUArray.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUStruct.d.ts +2 -4
- package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUStruct.js +1 -1
- package/src/shade/renderer/shader/type/WebGPUType.d.ts +5 -1
- package/src/shade/renderer/shader/type/WebGPUType.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUType.js +4 -0
- package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.d.ts +7 -3
- package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.d.ts.map +1 -1
- package/src/shade/renderer/shadow/evsm/graph_evsm_render_cascade.js +3 -2
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +10 -0
- package/src/shade/renderer/shadow/map/Shadowmap.d.ts +12 -0
- package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/Shadowmap.js +8 -0
- package/src/shade/renderer/shadow/map/SpotLightShadowmap.d.ts +2 -2
- package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.d.ts +7 -3
- package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -2
- package/src/shade/renderer/shadow/map/csm_debug_draw_preview.d.ts +11 -5
- package/src/shade/renderer/shadow/map/csm_debug_draw_preview.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +5 -4
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.d.ts +13 -6
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +6 -5
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts +9 -4
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -3
- package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.d.ts +11 -5
- package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/brixelizer/Brixelizer.js +5 -4
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts +1 -0
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -0
- package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts +13 -6
- package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +6 -5
- package/src/shade/renderer/texture/GPUTextureAllocator.d.ts +4 -0
- package/src/shade/renderer/texture/GPUTextureAllocator.d.ts.map +1 -1
- package/src/shade/renderer/texture/GPUTextureAllocator.js +4 -0
- package/src/shade/renderer/texture/GPUTextureContext.d.ts +1 -0
- package/src/shade/renderer/texture/GPUTextureContext.d.ts.map +1 -1
- package/src/shade/renderer/texture/GPUTextureContext.js +4 -0
- package/src/shade/renderer/texture/RenderTarget.d.ts +7 -3
- package/src/shade/renderer/texture/RenderTarget.d.ts.map +1 -1
- package/src/shade/renderer/texture/RenderTarget.js +3 -2
- package/src/shade/renderer/texture/ShadeTexture.d.ts +2 -1
- package/src/shade/renderer/texture/ShadeTexture.d.ts.map +1 -1
- package/src/shade/renderer/texture/ShadeTexture.js +4 -0
- package/src/shade/renderer/texture/TextureManager.d.ts +1 -0
- package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/TextureManager.js +4 -0
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
- package/src/shade/renderer/texture/debug_draw_texture.d.ts +9 -4
- package/src/shade/renderer/texture/debug_draw_texture.d.ts.map +1 -1
- package/src/shade/renderer/texture/debug_draw_texture.js +4 -3
- package/src/shade/renderer/texture/download_texture_data.d.ts +17 -6
- package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
- package/src/shade/renderer/texture/download_texture_data.js +10 -5
- package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts +26 -12
- package/src/shade/renderer/texture/draw_texture_as_rgba.d.ts.map +1 -1
- package/src/shade/renderer/texture/draw_texture_as_rgba.js +12 -10
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.d.ts.map +1 -1
- package/src/shade/renderer/texture/mipmaps/WebGPUMipmapGenerator.js +5 -4
- package/src/shade/renderer/texture/source/ShadeImage.d.ts +4 -2
- package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/source/ShadeImage.js +5 -0
- package/src/shade/renderer/texture/source/ShadeImageSerializationAdapter.d.ts +12 -0
- package/src/shade/renderer/texture/source/ShadeImageSerializationAdapter.d.ts.map +1 -1
- package/src/shade/renderer/texture/util/make_checkers_texture.d.ts +12 -5
- package/src/shade/renderer/texture/util/make_checkers_texture.d.ts.map +1 -1
- package/src/shade/renderer/texture/util/make_checkers_texture.js +5 -4
- package/src/shade/renderer/texture/virtual/README.md +6 -4
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts +7 -2
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +15 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
- package/src/shade/renderer/util/Uint32BufferSamplingStats.d.ts +2 -0
- package/src/shade/renderer/util/Uint32BufferSamplingStats.d.ts.map +1 -1
- package/src/shade/renderer/util/Uint32BufferSamplingStats.js +5 -0
- package/src/shade/renderer/view/GPUViewContext.d.ts +4 -1
- package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
- package/src/shade/renderer/view/GPUViewContext.js +11 -5
- package/src/shade/renderer/view/View.d.ts +6 -0
- package/src/shade/renderer/view/View.d.ts.map +1 -1
- package/src/shade/renderer/view/View.js +5 -0
- package/src/shade/renderer/view/ViewManager.d.ts +11 -1
- package/src/shade/renderer/view/ViewManager.d.ts.map +1 -1
- package/src/shade/renderer/view/ViewManager.js +7 -0
- package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +6 -0
- package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +5 -0
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +15 -6
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +11 -5
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts +5 -5
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/ParticipatingMediaVolume.js +1 -1
- package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts +4 -0
- package/src/shade/renderer/volumetrics/SceneVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/SceneVolumetrics.js +4 -0
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts +23 -11
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/build_volumetrics_sun_shadow_transform.js +11 -10
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +37 -18
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +30 -26
- package/src/view/View.d.ts +8 -3
- package/src/view/View.d.ts.map +1 -1
- package/src/view/View.js +7 -2
- package/src/view/asset/AssetLoaderStatusView.d.ts +7 -3
- package/src/view/asset/AssetLoaderStatusView.d.ts.map +1 -1
- package/src/view/asset/AssetLoaderStatusView.js +3 -2
- package/src/view/common/ListView.d.ts +21 -15
- package/src/view/common/ListView.d.ts.map +1 -1
- package/src/view/common/ListView.js +8 -7
- package/src/view/common/LocalizedLabelView.d.ts +15 -7
- package/src/view/common/LocalizedLabelView.d.ts.map +1 -1
- package/src/view/common/LocalizedLabelView.js +7 -6
- package/src/view/common/TabbedView.d.ts +14 -6
- package/src/view/common/TabbedView.d.ts.map +1 -1
- package/src/view/common/TabbedView.js +6 -4
- package/src/view/controller/controls/BooleanVector3Control.d.ts +1 -1
- package/src/view/controller/controls/BooleanVector3Control.d.ts.map +1 -1
- package/src/view/controller/controls/GuiControl.d.ts +1 -1
- package/src/view/controller/controls/GuiControl.d.ts.map +1 -1
- package/src/view/controller/controls/NativeListController.d.ts +15 -7
- package/src/view/controller/controls/NativeListController.d.ts.map +1 -1
- package/src/view/controller/controls/NativeListController.js +7 -6
- package/src/view/controller/controls/Vector1Control.d.ts +1 -1
- package/src/view/controller/controls/Vector1Control.d.ts.map +1 -1
- package/src/view/currency/CompositeCurrencyLabelView.d.ts +10 -5
- package/src/view/currency/CompositeCurrencyLabelView.d.ts.map +1 -1
- package/src/view/currency/CompositeCurrencyLabelView.js +4 -3
- package/src/view/currency/CurrencyDenominationLabelView.d.ts +7 -3
- package/src/view/currency/CurrencyDenominationLabelView.d.ts.map +1 -1
- package/src/view/currency/CurrencyDenominationLabelView.js +3 -2
- package/src/view/elements/CheckboxView.d.ts +7 -3
- package/src/view/elements/CheckboxView.d.ts.map +1 -1
- package/src/view/elements/CheckboxView.js +3 -2
- package/src/view/elements/DropDownSelectionView.d.ts +9 -4
- package/src/view/elements/DropDownSelectionView.d.ts.map +1 -1
- package/src/view/elements/DropDownSelectionView.js +3 -2
- package/src/view/elements/EmptyView.d.ts +29 -13
- package/src/view/elements/EmptyView.d.ts.map +1 -1
- package/src/view/elements/EmptyView.js +13 -11
- package/src/view/elements/SimpleWindow.d.ts +1 -1
- package/src/view/elements/SimpleWindow.d.ts.map +1 -1
- package/src/view/elements/button/ButtonView.d.ts +15 -7
- package/src/view/elements/button/ButtonView.d.ts.map +1 -1
- package/src/view/elements/button/ButtonView.js +7 -6
- package/src/view/elements/image/ImageView.d.ts +7 -3
- package/src/view/elements/image/ImageView.d.ts.map +1 -1
- package/src/view/elements/image/ImageView.js +3 -2
- package/src/view/elements/image/SvgImageView.d.ts +5 -2
- package/src/view/elements/image/SvgImageView.d.ts.map +1 -1
- package/src/view/elements/image/SvgImageView.js +2 -1
- package/src/view/elements/label/LabeledValueView.d.ts +14 -7
- package/src/view/elements/label/LabeledValueView.d.ts.map +1 -1
- package/src/view/elements/label/LabeledValueView.js +6 -5
- package/src/view/elements/progress/SmoothProgressBar.d.ts +14 -7
- package/src/view/elements/progress/SmoothProgressBar.d.ts.map +1 -1
- package/src/view/elements/progress/SmoothProgressBar.js +6 -5
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +9 -4
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
- package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +4 -3
- package/src/view/elements/radial/RadialMenu.d.ts +19 -9
- package/src/view/elements/radial/RadialMenu.d.ts.map +1 -1
- package/src/view/elements/radial/RadialMenu.js +9 -8
- package/src/view/elements/radial/RadialMenuElementDefinition.d.ts +63 -31
- package/src/view/elements/radial/RadialMenuElementDefinition.d.ts.map +1 -1
- package/src/view/elements/radial/RadialMenuElementDefinition.js +30 -28
- package/src/view/elements/radial/RadialProgressView.d.ts +1 -1
- package/src/view/elements/radial/RadialProgressView.d.ts.map +1 -1
- package/src/view/elements/radial/RadialText.d.ts +18 -10
- package/src/view/elements/radial/RadialText.d.ts.map +1 -1
- package/src/view/elements/radial/RadialText.js +7 -6
- package/src/view/elements/tiles2d/Tile.d.ts +12 -6
- package/src/view/elements/tiles2d/Tile.d.ts.map +1 -1
- package/src/view/elements/tiles2d/Tile.js +4 -3
- package/src/view/elements/tiles2d/TileGrid.d.ts +23 -10
- package/src/view/elements/tiles2d/TileGrid.d.ts.map +1 -1
- package/src/view/elements/tiles2d/TileGrid.js +10 -9
- package/src/view/elements/video/VideoView.d.ts +7 -3
- package/src/view/elements/video/VideoView.d.ts.map +1 -1
- package/src/view/elements/video/VideoView.js +3 -2
- package/src/view/game/achievements/AchievementNotificationView.d.ts +7 -3
- package/src/view/game/achievements/AchievementNotificationView.d.ts.map +1 -1
- package/src/view/game/achievements/AchievementNotificationView.js +3 -2
- package/src/view/graphics/GraphicsContextFailureView.d.ts +11 -5
- package/src/view/graphics/GraphicsContextFailureView.d.ts.map +1 -1
- package/src/view/graphics/GraphicsContextFailureView.js +5 -4
- package/src/view/interaction/InteractionCommand.d.ts +11 -5
- package/src/view/interaction/InteractionCommand.d.ts.map +1 -1
- package/src/view/interaction/InteractionCommand.js +5 -4
- package/src/view/interaction/InterfaceCommand.d.ts +32 -15
- package/src/view/interaction/InterfaceCommand.d.ts.map +1 -1
- package/src/view/interaction/InterfaceCommand.js +15 -13
- package/src/view/interaction/createInterfaceCommandButton.d.ts +9 -4
- package/src/view/interaction/createInterfaceCommandButton.d.ts.map +1 -1
- package/src/view/interaction/createInterfaceCommandButton.js +4 -3
- package/src/view/layout/DockPanel.d.ts +11 -5
- package/src/view/layout/DockPanel.d.ts.map +1 -1
- package/src/view/layout/DockPanel.js +5 -4
- package/src/view/layout/DrawerView.d.ts +7 -3
- package/src/view/layout/DrawerView.d.ts.map +1 -1
- package/src/view/layout/DrawerView.js +3 -2
- package/src/view/layout/FloatingPanelView.d.ts +7 -3
- package/src/view/layout/FloatingPanelView.d.ts.map +1 -1
- package/src/view/layout/FloatingPanelView.js +3 -2
- package/src/view/layout/SplitView.d.ts +11 -5
- package/src/view/layout/SplitView.d.ts.map +1 -1
- package/src/view/layout/SplitView.js +5 -4
- package/src/view/math/FunctionGraphView.d.ts +8 -4
- package/src/view/math/FunctionGraphView.d.ts.map +1 -1
- package/src/view/math/FunctionGraphView.js +3 -2
- package/src/view/minimap/MinimapCanvasView.d.ts +10 -4
- package/src/view/minimap/MinimapCanvasView.d.ts.map +1 -1
- package/src/view/minimap/MinimapCanvasView.js +4 -3
- package/src/view/minimap/dom/MinimapCameraView.d.ts +2 -1
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapMarkerView.d.ts +31 -9
- package/src/view/minimap/dom/MinimapMarkerView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapTerrainView.d.ts +9 -4
- package/src/view/minimap/dom/MinimapTerrainView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapTerrainView.js +3 -2
- package/src/view/task/TaskProgressView.d.ts +7 -3
- package/src/view/task/TaskProgressView.d.ts.map +1 -1
- package/src/view/task/TaskProgressView.js +3 -2
- package/src/view/tooltip/DomTooltipManager.d.ts +6 -0
- package/src/view/tooltip/DomTooltipManager.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipManager.js +5 -0
- package/src/view/tooltip/DomTooltipObserver.d.ts +4 -0
- package/src/view/tooltip/DomTooltipObserver.d.ts.map +1 -1
- package/src/view/tooltip/DomTooltipObserver.js +4 -0
- package/src/view/tooltip/TooltipManager.d.ts +6 -0
- package/src/view/tooltip/TooltipManager.d.ts.map +1 -1
- package/src/view/tooltip/TooltipManager.js +5 -0
- package/src/view/tooltip/TooltipView.d.ts +7 -3
- package/src/view/tooltip/TooltipView.d.ts.map +1 -1
- package/src/view/tooltip/TooltipView.js +5 -1
- package/src/view/tooltip/VisualTip.d.ts +6 -0
- package/src/view/tooltip/VisualTip.d.ts.map +1 -1
- package/src/view/tooltip/VisualTip.js +5 -0
- package/src/view/tooltip/gml/GMLEngine.d.ts +14 -2
- package/src/view/tooltip/gml/GMLEngine.d.ts.map +1 -1
- package/src/view/tooltip/gml/GMLEngine.js +8 -0
- package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.d.ts +10 -0
- package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.d.ts.map +1 -1
- package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +7 -0
- package/src/view/util/DomSizeObserver.d.ts +9 -2
- package/src/view/util/DomSizeObserver.d.ts.map +1 -1
- package/src/view/util/DomSizeObserver.js +6 -1
- package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
- package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.d.ts +0 -395
- package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.d.ts.map +0 -1
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts +0 -19
- package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +0 -1
- package/src/shade/renderer/particles/ParticleRenderMode.js +0 -33
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts +0 -37
- package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +0 -1
- package/src/shade/renderer/particles/graph_particles_billboard.js +0 -93
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +0 -55
- package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +0 -1
- package/src/shade/renderer/particles/sort/graph_particle_sort.js +0 -130
- package/src/shade/renderer/particles/sort/particle_counting_sort.d.ts +0 -26
- package/src/shade/renderer/particles/sort/particle_counting_sort.d.ts.map +0 -1
- package/src/shade/renderer/particles/sort/particle_counting_sort.js +0 -51
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts +0 -14
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +0 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.js +0 -223
|
@@ -0,0 +1,2239 @@
|
|
|
1
|
+
# Cloth — measurements
|
|
2
|
+
|
|
3
|
+
> Four milestones, appended in order. §1–§8 are **M0**, the solver core;
|
|
4
|
+
> §9–§15 are **M1**, the component and the system; §16–§23 are **M2**,
|
|
5
|
+
> collision; §24–§29 are **M3**, skinned garments. Nothing above a milestone
|
|
6
|
+
> boundary is edited by the milestone below it — a measurement that turned out to
|
|
7
|
+
> be incomplete is corrected by a later section saying so, not by a rewrite.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Cloth — M0 measurements
|
|
12
|
+
|
|
13
|
+
> What the solver core actually does, measured. Written 2026-09-10, against the
|
|
14
|
+
> M0 implementation in `solver/`.
|
|
15
|
+
>
|
|
16
|
+
> Every number here is reproducible from two scripts, both runnable directly
|
|
17
|
+
> under node (through vitest, imported bindings become getters and the
|
|
18
|
+
> cross-module calls that make up the inner loop stop inlining — which is
|
|
19
|
+
> exactly what is being measured):
|
|
20
|
+
>
|
|
21
|
+
> ```
|
|
22
|
+
> node src/engine/physics/cloth/solver/__fixtures__/cloth_constants_sweep.mjs
|
|
23
|
+
> node src/engine/physics/cloth/solver/__fixtures__/cloth_bench.mjs
|
|
24
|
+
> ```
|
|
25
|
+
>
|
|
26
|
+
> There is also a playground, which is where the §6 finding came from:
|
|
27
|
+
> `npm run dev --workspace @woosh/meep-engine`, then
|
|
28
|
+
> `/src/engine/physics/cloth/playground/`. Its presets are the interesting rows
|
|
29
|
+
> of this document, one click each.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 1. What M0 proved wrong in PLAN.md
|
|
34
|
+
|
|
35
|
+
Six things, in the order they were found. Each is folded back into the design
|
|
36
|
+
document; this is the evidence.
|
|
37
|
+
|
|
38
|
+
| # | The design said | The measurement said |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| 0 | §6 — a stretch row carries a material stiffness `k_stretch` | A *penalty* stiffer than about `8·(m/h²)` makes the step **add** energy — measured at +6.8 J on a sheet whose whole potential is 1.2 J — and no iteration count removes it. Cloth's stretch rows have to be hard. §6 below. |
|
|
41
|
+
| 1 | §5.3 — an SPD Hessian means "no update can increase the local energy" | SPD buys a descent **direction**. A full Newton step of 1 overshoots and climbs where the model stops resembling the energy. §5.3 below. |
|
|
42
|
+
| 2 | §5.2 — drop the geometric-stiffness term `fc·∂²C/∂x²` entirely | Its PSD half is what stops the update overshooting sideways. Keep it; the NSD half is still dropped. §5.1 |
|
|
43
|
+
| 3 | §5.2 — the multiplier and the penalty band apply to every row | They apply only to **hard** rows. On a soft row the multiplier drives `C → 0` and makes a 1 kN/m spring 100× stiffer than Hooke. §3 |
|
|
44
|
+
| 4 | §5.2 — `k_min` and `k_max` are stiffnesses | They are only meaningful as **ratios of the row's own `m/h²`** — the same ratio works across five decades of particle mass; a fixed stiffness does not. §4 |
|
|
45
|
+
| 5 | §5.2 — the 3×3 solve "never fails" | The *cofactor* solve fails: a determinant of −4.8e8 on a matrix with eigenvalues 0.12, 0.12, 5.4e8. LDLᵀ does not. §5.2 |
|
|
46
|
+
| 6 | §17 — under 2 ms per frame per character | **3.50 ms** best case, 4.42 ms median, for 1,024 particles at 2×4. Over by 1.75×. And gathering neighbours is *not* what dominates. §7 |
|
|
47
|
+
|
|
48
|
+
A seventh is a gap rather than an error: §7 P5's jitter mechanism (`γ` decaying
|
|
49
|
+
warm-started duals) only reaches hard rows, because a soft row has no multiplier
|
|
50
|
+
to decay. §6.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 2. The constants
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
α = 0.25 γ = 1 β = 1e5 (unexercised) k_min = k_max = 8·(m/h²)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`cloth_solver_constants.js` carries them and says why. The short version:
|
|
61
|
+
|
|
62
|
+
- **α and γ act only through their product.** At a fixed `α·γ` the answer does
|
|
63
|
+
not move at all between `γ = 0.3` and `γ = 1`. `γ` sits at 1 because its
|
|
64
|
+
second job — decaying the penalty — has nothing to do while the band is a
|
|
65
|
+
single point.
|
|
66
|
+
- **`α·γ ≥ 0.5` diverges.** 0.25 is a factor of two clear.
|
|
67
|
+
- **`k_min = k_max` disables the ramp**, which measured as good as any ramped
|
|
68
|
+
alternative for M0's persistent rows and removes a scale-dependence that a
|
|
69
|
+
live ramp reintroduces. The ramp exists for *transient* rows — a contact that
|
|
70
|
+
should arrive soft rather than shock the mesh on its first frame — and M0 has
|
|
71
|
+
none, so **β cannot be chosen from M0 data and M2 must measure it.**
|
|
72
|
+
|
|
73
|
+
### α·γ against the penalty ceiling — 20-link hard chain
|
|
74
|
+
|
|
75
|
+
Cells are `worst |C|/L₀` / `kinetic energy after 400 steps, J`. The kinetic
|
|
76
|
+
column is the one to read: past `α·γ = 0.3` the chain stops settling long before
|
|
77
|
+
it stops being finite.
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
k_max/(m/h²) α·γ=0 α·γ=0.1 α·γ=0.2 α·γ=0.25 α·γ=0.3 α·γ=0.4 α·γ=0.5 α·γ=0.6
|
|
81
|
+
1 3.6e-1/3e-7 3.1e-1/2e-7 2.8e-1/1e-7 2.6e-1/4e-7 2.4e-1/1e-6 2.2e-1/3e-6 1.7e-1/2e-3 8.5e-1/5e-3
|
|
82
|
+
2 1.9e-1/1e-10 1.7e-1/2e-11 1.5e-1/3e-10 1.4e-1/2e-9 1.3e-1/5e-11 1.0e-1/1e-7 9.7e-2/3e-3 diverged
|
|
83
|
+
4 1.0e-1/1e-13 9.1e-2/1e-13 7.9e-2/1e-12 7.3e-2/2e-12 6.7e-2/3e-12 5.7e-2/3e-7 2.8e-1/3e-2 diverged
|
|
84
|
+
8 5.6e-2/2e-13 4.9e-2/3e-14 4.1e-2/3e-13 3.8e-2/1e-11 3.5e-2/2e-9 6.6e-2/3e-4 diverged diverged
|
|
85
|
+
16 4.9e-2/1e-5 2.5e-2/1e-10 2.1e-2/1e-6 4.1e-2/7e-5 3.3e-2/2e-4 2.7e-2/1e-3 diverged diverged
|
|
86
|
+
32 5.5e-2/5e-5 4.9e-2/5e-5 4.4e-2/4e-5 4.1e-2/4e-5 3.9e-2/4e-5 7.6e-2/1e-3 diverged diverged
|
|
87
|
+
128 7.0e-2/3e-4 6.4e-2/2e-4 5.9e-2/2e-4 5.7e-2/2e-4 5.5e-2/2e-4 5.0e-2/2e-4 diverged diverged
|
|
88
|
+
1024 1.3e-1/2e-3 7.3e-2/3e-4 7.6e-2/5e-4 7.3e-2/4e-4 7.1e-2/4e-4 6.6e-2/4e-4 diverged diverged
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 3. Soft rows must not carry a multiplier
|
|
94
|
+
|
|
95
|
+
The first thing the sweep established, and it reshaped everything after it.
|
|
96
|
+
|
|
97
|
+
A row whose material stiffness is finite is representable as a plain penalty,
|
|
98
|
+
and **a plain penalty at the material stiffness is the material law**. There is
|
|
99
|
+
nothing for a multiplier to add, and adding one anyway is not a small error:
|
|
100
|
+
`λ ← λ + k·C` is an augmented Lagrangian on the equality `C = 0`, so it drives
|
|
101
|
+
`C` to zero whatever `k` is. A 0.05 kg mass on a 1 kN/m spring, whose analytic
|
|
102
|
+
extension is 0.49 mm, settled at **4.8 µm — a hundred times stiffer than it was
|
|
103
|
+
authored as.**
|
|
104
|
+
|
|
105
|
+
The fix is that a row is **hard** exactly when its stiffness is `Infinity`,
|
|
106
|
+
which makes §6's table literal rather than introducing a threshold. A hard row
|
|
107
|
+
gets the augmented Lagrangian; a soft row is a pure penalty and carries no
|
|
108
|
+
multiplier. Afterwards a soft row reads exactly Hooke, and reads it whatever the
|
|
109
|
+
five constants are doing:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
chosen extension/Hooke = 1.0000
|
|
113
|
+
α=0 extension/Hooke = 1.0000
|
|
114
|
+
α=1 γ=1 extension/Hooke = 1.0000
|
|
115
|
+
β=0 extension/Hooke = 1.0000
|
|
116
|
+
band ×1024 extension/Hooke = 1.0000
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
That insensitivity is what makes α, β, γ and the band honest as *global* solver
|
|
120
|
+
internals rather than things an author would eventually have to reach for.
|
|
121
|
+
|
|
122
|
+
### What the multiplier actually buys
|
|
123
|
+
|
|
124
|
+
Not a smaller residual. Measured across chain depths of 5 to 40 and stiffnesses
|
|
125
|
+
from 1e2 to 1e9 at the same budget, a hard row and a stiff penalty give
|
|
126
|
+
comparable `|C|/L₀`, and which wins depends on the phase of the oscillation the
|
|
127
|
+
snapshot catches. What it buys is **settling**: a hard 20-link chain comes to
|
|
128
|
+
rest at 1e-14 J where the same chain on a penalty of any stiffness sits in a
|
|
129
|
+
limit cycle at 1e-4 J. Ten orders of magnitude, and it is §7 P5 rather than P2.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 4. The penalty band is a ratio, not a stiffness
|
|
134
|
+
|
|
135
|
+
Same 20-link hard chain, `α·γ = 0.25`, with `k_max` held at a fixed **multiple**
|
|
136
|
+
of the row's own `m/h²` while the particle mass moves across five decades. The
|
|
137
|
+
residual column repeats exactly; against a fixed stiffness in N/m it does not.
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
mass (kg) m/h² ×0.3 ×1 ×2 ×4 ×8 ×16 ×64 ×256
|
|
141
|
+
5e-6 7.2e-2 7.4e-1/4e-6 2.6e-1/4e-9 1.4e-1/2e-11 7.3e-2/2e-14 3.8e-2/1e-13 4.1e-2/7e-7 4.8e-2/1e-6 6.5e-2/3e-6
|
|
142
|
+
5e-4 7.2e+0 7.4e-1/4e-4 2.6e-1/4e-7 1.4e-1/2e-9 7.3e-2/2e-12 3.8e-2/1e-11 4.1e-2/7e-5 4.8e-2/1e-4 6.5e-2/3e-4
|
|
143
|
+
5e-2 7.2e+2 7.4e-1/4e-2 2.6e-1/4e-5 1.4e-1/2e-7 7.3e-2/2e-10 3.8e-2/1e-9 4.1e-2/7e-3 4.8e-2/1e-2 6.5e-2/3e-2
|
|
144
|
+
5e+0 7.2e+4 7.4e-1/4e+0 2.6e-1/4e-3 1.4e-1/2e-5 7.3e-2/2e-8 3.8e-2/2e-7 4.1e-2/7e-1 4.8e-2/1e+0 6.5e-2/3e+0
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
§5.2's own prose already names `k_max/(m/h²)` as the quantity that matters. It
|
|
148
|
+
stopped one step short of making the ratio the parameter.
|
|
149
|
+
|
|
150
|
+
The optimum is ×8: below it the row is too soft to converge, above it the chain
|
|
151
|
+
stops settling (the kinetic column climbs by four orders of magnitude between
|
|
152
|
+
×8 and ×16). The row's scale is its **effective** inertia along the constraint,
|
|
153
|
+
`1/((wᵢ + wⱼ)·h²)`, so a row with one pinned end sees the free particle's own
|
|
154
|
+
`m/h²` and an interior row sees half of it.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 5. The vertex update
|
|
159
|
+
|
|
160
|
+
### 5.1 The geometric-stiffness term, half of it
|
|
161
|
+
|
|
162
|
+
For a distance row `∂²C/∂x² = (I − g gᵀ)/L`, which is positive semidefinite
|
|
163
|
+
exactly when the row is in tension. Dropping the whole term — §5.2's
|
|
164
|
+
instruction — leaves `H` underestimating the curvature perpendicular to the row
|
|
165
|
+
by `fc/L`, so the update overshoots sideways once that passes the mass term.
|
|
166
|
+
One free particle between two anchors, stepping the tension up:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
m/h² fc/L ratio ΔE/E with the term dropped with its PSD half kept
|
|
170
|
+
1.44e+2 1.06e+2 7.33e-1 −65.6% −62.9%
|
|
171
|
+
1.44e+2 5.53e+2 3.84e+0 +21.9% −30.1%
|
|
172
|
+
1.44e+2 5.53e+4 3.84e+2 +80.8% −33.9%
|
|
173
|
+
1.44e+2 1.45e+6 1.01e+4 +718.0% −22.6%
|
|
174
|
+
1.44e+2 9.94e+6 6.90e+4 +4140.0% −19.1%
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The crossover is exactly where the theory puts it, at `fc/L ≈ m/h²`. Keeping the
|
|
178
|
+
PSD half costs nothing structurally: every term in `H` is still positive
|
|
179
|
+
semidefinite on top of a positive definite mass term, so the SPD-by-construction
|
|
180
|
+
argument is intact and there is still no threshold. The compression half stays
|
|
181
|
+
dropped, and dropping it there is conservative — it makes the step shorter than
|
|
182
|
+
Newton, not longer.
|
|
183
|
+
|
|
184
|
+
The term is added whether or not the row is at a clamp. A saturated row applies
|
|
185
|
+
a force of constant *magnitude*, but that force still swings as the row rotates,
|
|
186
|
+
so its geometric curvature is real even though its penalty curvature is gone.
|
|
187
|
+
|
|
188
|
+
### 5.2 LDLᵀ, not a cofactor inverse
|
|
189
|
+
|
|
190
|
+
The two agree in exact arithmetic. In `Float64` they do not. A vertex carrying
|
|
191
|
+
one very stiff row against a small mass term assembles
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
H = [[1.7099e+8, −2.1651e+8, 1.2729e+8],
|
|
195
|
+
[ , 2.7415e+8, −1.6118e+8],
|
|
196
|
+
[ , , 9.4759e+7]]
|
|
197
|
+
|
|
198
|
+
eigenvalues 1.198e−1, 1.198e−1, 5.399e+8 (all positive; condition 4.5e9)
|
|
199
|
+
true determinant 7.752e+6
|
|
200
|
+
cofactor determinant −4.828e+8 ← wrong sign
|
|
201
|
+
LDLᵀ pivots 1.710e+8, 3.120e−1, 1.453e−1 (product 7.752e+6, exact)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The determinant is a sum of triple products that has to cancel by the condition
|
|
205
|
+
number squared; the factorisation never forms them. The dev-build assertion
|
|
206
|
+
checks the three pivots, which *is* positive definiteness rather than a proxy
|
|
207
|
+
for it, and it held across every update in the fuzz.
|
|
208
|
+
|
|
209
|
+
### 5.3 A descent direction is not a monotone step
|
|
210
|
+
|
|
211
|
+
`Δ = H⁻¹f` with `H` positive definite gives `f·Δ = fᵀH⁻¹f > 0`. That guarantees
|
|
212
|
+
the energy falls for a *small enough* step. The update takes a full step of 1,
|
|
213
|
+
and where the quadratic model stops resembling the energy, a full step climbs.
|
|
214
|
+
Walking one such step:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
t E(x₀ + t·Δ) ΔE
|
|
218
|
+
0 −1.9122412072e+7 0
|
|
219
|
+
1e−9 −1.9122412098e+7 −2.6e−2 falling
|
|
220
|
+
1e−7 −1.9122414636e+7 −2.6e+0 falling
|
|
221
|
+
1e−5 −1.9122668457e+7 −2.6e+2 falling
|
|
222
|
+
1e−3 −1.9133645206e+7 −1.1e+4 falling — this is the minimum
|
|
223
|
+
1e−2 −1.8901856618e+7 +2.2e+5 past it
|
|
224
|
+
0.5 −3.1478025715e+6 +1.6e+7
|
|
225
|
+
1 +1.9273328443e+7 +3.8e+7 the step the solver takes
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The direction is right; the length is a thousand times too long. So the step is
|
|
229
|
+
capped at the **shortest row incident on the particle** — the distance over
|
|
230
|
+
which "the direction to a neighbour" means anything. That radius is the mesh's
|
|
231
|
+
own geometry rather than a tuned constant, it is already in hand from the
|
|
232
|
+
accumulation, and for cloth in any ordinary motion it never binds.
|
|
233
|
+
|
|
234
|
+
With all three corrections in place:
|
|
235
|
+
|
|
236
|
+
| | fraction of updates that climb | worst, relative to the local energy scale |
|
|
237
|
+
|---|---|---|
|
|
238
|
+
| realistic cape, hard rows | 0.0040% | 8.6e−2 |
|
|
239
|
+
| realistic cape, soft rows | 0.0041% | 1.5e−1 |
|
|
240
|
+
| absurd fuzz, 3.0M updates | 1.52% | 1.00 |
|
|
241
|
+
|
|
242
|
+
Those are the thresholds the standing gate in `cloth_solve_vertex.spec.js` holds
|
|
243
|
+
the solver to.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 6. Settling, and the gap in P5
|
|
248
|
+
|
|
249
|
+
At the chosen constants a **hard** chain settles hard: a 20-link chain reaches
|
|
250
|
+
1e-11 J and an 80-link one 1e-9 J, and the residual falls monotonically with the
|
|
251
|
+
iteration budget with nothing diverging at any depth.
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
iterations n=1 n=2 n=5 n=10 n=20 n=40 n=80
|
|
255
|
+
1 3.2e-3/0e+0 6.4e-3/1e-16 4.6e-2/3e-5 9.5e-2/6e-7 1.3e-1/2e-3 1.2e+0/2e-2 9.6e-1/3e-1
|
|
256
|
+
2 3.2e-4/0e+0 4.2e-3/0e+0 1.4e-2/2e-16 3.4e-2/1e-6 1.4e-1/6e-4 1.2e-1/7e-3 8.9e-1/1e-2
|
|
257
|
+
4 3.9e-6/0e+0 4.1e-4/0e+0 6.8e-3/1e-16 1.7e-2/2e-15 3.8e-2/1e-11 9.0e-2/3e-5 1.4e-1/7e-3
|
|
258
|
+
8 0.0e+0/0e+0 2.9e-5/1e-17 1.7e-3/1e-16 7.2e-3/1e-15 1.7e-2/9e-14 3.8e-2/8e-13 8.0e-2/1e-4
|
|
259
|
+
16 0.0e+0/0e+0 2.8e-7/0e+0 4.1e-4/5e-16 2.1e-3/1e-15 6.9e-3/3e-14 1.6e-2/2e-13 3.6e-2/9e-10
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
A **soft** row above a certain stiffness does not settle at all, and the reason
|
|
263
|
+
is worse than "nothing is damping it".
|
|
264
|
+
|
|
265
|
+
The threshold is the same ratio §4 turns up: **`k/(m/h²)`**. Below about 8 the
|
|
266
|
+
step is dissipative and the cloth comes to rest; above it the cloth sustains a
|
|
267
|
+
limit cycle for as long as you run it. Measured on a 16×20 sheet, 0.3 kg, hung
|
|
268
|
+
from the top edge at 60 Hz × 2 substeps × 4 iterations, over 1,500 steps:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
row k/(m/h²) final kinetic energy
|
|
272
|
+
hard (AL, k pinned at ×8) 8 1.9e-12 J settles
|
|
273
|
+
soft, 1e2 N/m 7.4 7.4e-09 J settles
|
|
274
|
+
soft, 1e3 N/m 74 1.9e-02 J does not
|
|
275
|
+
soft, 1e4 N/m 740 7.4e-03 J does not
|
|
276
|
+
soft, 1e5 N/m 7400 2.9e-02 J does not
|
|
277
|
+
soft, 1e4 at 16 iterations 740 3.3e-03 J does not
|
|
278
|
+
soft, 1e4 at 8 substeps 740 1.4e-03 J does not
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
More iterations and more substeps shrink it; neither removes it.
|
|
282
|
+
|
|
283
|
+
And the step is **adding energy**, not merely failing to remove it. Tracking the
|
|
284
|
+
full mechanical energy — kinetic plus gravitational plus elastic — from the rest
|
|
285
|
+
configuration:
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
soft 1e2 (ratio 7) −0.016 J, and flat from step 300 onwards dissipative
|
|
289
|
+
soft 1e4 (ratio 740) +6.8 J, wandering between +1 and +7 J creating it
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
For scale, that sheet's entire gravitational potential over its own length is
|
|
293
|
+
about 1.2 J, so at ratio 740 the solve manufactures several times the whole
|
|
294
|
+
system's energy budget and then holds it there. It stays bounded — the SPD
|
|
295
|
+
Hessian and the trust region cap every individual step — but bounded is not
|
|
296
|
+
rest.
|
|
297
|
+
|
|
298
|
+
Two consequences.
|
|
299
|
+
|
|
300
|
+
**§7 P5's mechanism covers hard rows only.** `γ` decays a multiplier and a soft
|
|
301
|
+
row has none, so no value of any solver constant reaches this. What does reach
|
|
302
|
+
it is `ClothDynamics#damping`, which arrives with the component in M1 — which
|
|
303
|
+
means damping is load-bearing for P5 rather than a taste control, and M1's spec
|
|
304
|
+
has to gate on a soft cloth actually settling.
|
|
305
|
+
|
|
306
|
+
**§6's assignment of stretch to a soft material stiffness does not survive.**
|
|
307
|
+
Real fabric wants a stretch stiffness far above `8·(m/h²)` — for a half-gram
|
|
308
|
+
particle at 60 Hz × 2 substeps that boundary is around 60 N/m, which is a rubber
|
|
309
|
+
band, not a fabric. So a cloth's stretch rows have to be **hard**, and the
|
|
310
|
+
augmented Lagrangian is not an optional refinement over a stiff penalty: it is
|
|
311
|
+
the only formulation of that row that rests. That is the same conclusion §3
|
|
312
|
+
reaches from the other direction, and it is why the playground defaults to hard
|
|
313
|
+
rows.
|
|
314
|
+
|
|
315
|
+
### Iteration-count insensitivity
|
|
316
|
+
|
|
317
|
+
§5.1 claims that adding iterations converges towards the *same* answer rather
|
|
318
|
+
than changing which answer it is. On the cape (20×30 at 2 cm, inextensible, hung
|
|
319
|
+
from its top edge and dropped through 90°), the hem across the budget:
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
iterations= 1 hem=−0.6450 m residual=7.2e-1
|
|
323
|
+
iterations= 2 hem=−0.6201 m residual=2.0e-1
|
|
324
|
+
iterations= 4 hem=−0.5993 m residual=7.5e-2
|
|
325
|
+
iterations= 8 hem=−0.5466 m residual=7.2e-2
|
|
326
|
+
iterations=16 hem=−0.5626 m residual=1.4e-2
|
|
327
|
+
iterations=32 hem=−0.5459 m residual=8.0e-3
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The sheet is 0.58 m long, so the answer moves 18% of its own length between 1
|
|
331
|
+
iteration and 32, and the residual moves by two orders of magnitude. The claim
|
|
332
|
+
holds in the sense that matters — the answer converges rather than changing
|
|
333
|
+
character, and one iteration is stable rather than broken — but "insensitive" is
|
|
334
|
+
too strong for a mesh 30 rows deep at this budget. §7 P2's tether row is what
|
|
335
|
+
closes that gap, and it lands in M1.
|
|
336
|
+
|
|
337
|
+
### Hostile regimes
|
|
338
|
+
|
|
339
|
+
All eight survive at the chosen constants.
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
stiff + 5 fps ok 1 kg particles on 1e8 N/m rows, 1 substep, 1 iteration
|
|
343
|
+
light + 240 fps ok 10 mg particles, 4 substeps, 8 iterations
|
|
344
|
+
10 m spacing ok a 6×6 sheet with 10 m between particles at 15 fps
|
|
345
|
+
a thousand g ok gravity at −9810 m/s²
|
|
346
|
+
soft as water ok 1e−2 N/m rows (sags 123 m, which is correct)
|
|
347
|
+
zero g, 100 m/s ok no gravity, particles thrown at 100 m/s
|
|
348
|
+
inextensible ok stiffness Infinity
|
|
349
|
+
inextensible cape ok 600 particles, stiffness Infinity
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 7. The performance budget
|
|
355
|
+
|
|
356
|
+
§17 budgets **under 2 ms per frame per character**, for about 1,000 particles at
|
|
357
|
+
2 substeps × 4 iterations, and says the figure is an estimate to be replaced by
|
|
358
|
+
a measurement. Replaced:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
# 1024 particles (32×32 patch at 2 cm, 0.5 kg), 2 substeps × 4 iterations
|
|
362
|
+
# 2945 stretch rows, 2821 bend rows, 4 colours, 370.4 KiB of state
|
|
363
|
+
# 8192 vertex updates per frame, 16.8 row incidences per particle
|
|
364
|
+
# Node v24.15.0 on win32/x64, 1200 warm-up frames then 1500 measured, 4 rounds
|
|
365
|
+
|
|
366
|
+
round minima 3.504 3.506 3.644 3.484 best 3.48 ms, spread ±5%
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**3.48 ms against a 2.000 ms budget — over by 1.74×**, and 3.55 ms when the
|
|
370
|
+
benchmark runs the same configuration alongside its four variants. The minimum is the
|
|
371
|
+
headline because it is what varies least between runs; a cloth's median moves by
|
|
372
|
+
a factor of two depending on whether it is still swinging, and the mean and p95
|
|
373
|
+
move with whatever else the machine is doing.
|
|
374
|
+
|
|
375
|
+
### What the frame is made of
|
|
376
|
+
|
|
377
|
+
Deleting the workload piece by piece, all five variants in one run so the
|
|
378
|
+
comparison is internally consistent:
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
variant MIN ms median share of the frame
|
|
382
|
+
everything 3.552 5.023
|
|
383
|
+
no bend rows 2.688 3.267 bend rows 0.864 ms 24.3%
|
|
384
|
+
no stretch rows 1.133 2.055 stretch rows 2.419 ms 68.1%
|
|
385
|
+
no rows at all 0.253 0.490 everything else 7.1%
|
|
386
|
+
shuffled within each colour 3.563 4.771 locality +0.3%
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
The rows are the frame; predict, warm start, the dual updates and integrate
|
|
390
|
+
together are 7% of it, and the cost is close to linear in both particles and
|
|
391
|
+
sweeps. The split between the two row kinds moves by a few points between runs
|
|
392
|
+
— bend read 18% in one run and 24% in another — so treat it as "stretch is most
|
|
393
|
+
of it, bend is most of the rest".
|
|
394
|
+
|
|
395
|
+
Two things this table does **not** license, and an earlier draft of this
|
|
396
|
+
document claimed both.
|
|
397
|
+
|
|
398
|
+
It does not say a stretch row costs four times what a bend row costs *per
|
|
399
|
+
visit*. The three variants are in different physical states — a cloth with no
|
|
400
|
+
stretch rows is in free fall rather than draping — so the split measures what
|
|
401
|
+
each row kind *causes* in a running step, not the arithmetic in its accumulate.
|
|
402
|
+
|
|
403
|
+
And it does not license attributing the stretch share to any particular part of
|
|
404
|
+
that accumulate. See below.
|
|
405
|
+
|
|
406
|
+
### A warning, because M2, M4 and M5 are told to re-measure
|
|
407
|
+
|
|
408
|
+
**An isolated loop over one accumulate measures the wrong workload.** Without
|
|
409
|
+
`predict` and `integrate` around it, the solve converges after a few passes and
|
|
410
|
+
the positions stop changing; from then on the loop reads a static array with
|
|
411
|
+
perfectly predictable branches, and every number it produces is of a cloth that
|
|
412
|
+
has stopped moving.
|
|
413
|
+
|
|
414
|
+
The size of the error, measured both ways on the same mesh:
|
|
415
|
+
|
|
416
|
+
```
|
|
417
|
+
isolated loop by deletion, in the running step
|
|
418
|
+
bend accumulate 0.72 ms 0.70 ms agree
|
|
419
|
+
stretch accumulate 0.47 ms 2.64 ms disagree, 5.6×
|
|
420
|
+
both 1.19 ms 3.34 ms
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Bend agrees; stretch does not, and the gap is most of the frame. The dev-build
|
|
424
|
+
assertion machinery is not the explanation — the non-finite tripwire and the
|
|
425
|
+
pivot assertion's message together are 0.118 ms, 3.4% of the step. Nor is it
|
|
426
|
+
`cloth_solve_vertex`'s own arithmetic: the eight colour sweeps called exactly as
|
|
427
|
+
`cloth_step` calls them come to 1.88 ms, and driven on their own — with no
|
|
428
|
+
predict to disturb the cloth — they too are measuring a converged mesh.
|
|
429
|
+
|
|
430
|
+
The honest statement is that **only the end-to-end figures here are
|
|
431
|
+
trustworthy**, and the per-row breakdown an earlier draft gave has been removed
|
|
432
|
+
rather than reconciled. Whoever re-measures at M2 should keep the whole step
|
|
433
|
+
running and vary one thing at a time.
|
|
434
|
+
|
|
435
|
+
### Gathering neighbours is not what dominates
|
|
436
|
+
|
|
437
|
+
§17 predicted it would. The controlled test is to **move every particle to a
|
|
438
|
+
different slot inside its own colour range**. The colouring is untouched — a
|
|
439
|
+
particle's colour *is* which range it sits in, and every particle stays in its
|
|
440
|
+
own — so the sweep does the same work in the same order over the same rows with
|
|
441
|
+
the same branches, and the only thing that moves is the address each particle
|
|
442
|
+
lives at.
|
|
443
|
+
|
|
444
|
+
The control is exact, and checkably so: the reference cloth and the shuffled one
|
|
445
|
+
produce **bit-identical** trajectories, agreeing on the hem position to six
|
|
446
|
+
decimals and on kinetic energy to five significant figures after 200 steps.
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
1024 particles, 370 KiB of state +0.3%
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Destroying within-colour locality entirely costs nothing measurable at the size
|
|
453
|
+
§17 budgets for — the whole state fits in L2 — so **§17's "gathering neighbour
|
|
454
|
+
positions is what will actually dominate" is wrong**, and there is no
|
|
455
|
+
memory-layout optimisation to win here. Whether that survives at four times the
|
|
456
|
+
size is *not* measured: a cruder probe suggested around 11% at 4,096 particles,
|
|
457
|
+
but that probe relabelled the source vertices, which also changed the greedy
|
|
458
|
+
colouring from four colours to ten, so it is not quotable.
|
|
459
|
+
|
|
460
|
+
Two earlier drafts got this wrong before this one got it right. The first used a
|
|
461
|
+
variant labelled "mesh order, not colour order" that did nothing of the kind —
|
|
462
|
+
it left the particles in colour-permuted storage and merely collapsed the colour
|
|
463
|
+
loop. The second relabelled the source numbering, which moves the particles but
|
|
464
|
+
changes the colouring with them. Only shuffling *within* a colour isolates the
|
|
465
|
+
one variable, and it was worth three attempts because this is the number that
|
|
466
|
+
contradicts the plan.
|
|
467
|
+
|
|
468
|
+
### Scaling, and what fits
|
|
469
|
+
|
|
470
|
+
Four rounds each, so the spread is the figure's real precision:
|
|
471
|
+
|
|
472
|
+
```
|
|
473
|
+
config round minima best spread
|
|
474
|
+
1024 @ 2×4 (the §17 workload) 3.504 3.506 3.644 3.484 3.48 ±5%
|
|
475
|
+
1024 @ 2×2 (half the iterations) 1.700 1.713 1.695 1.716 1.69 ±1% inside
|
|
476
|
+
1024 @ 1×4 (half the substeps) 1.683 1.734 1.765 1.703 1.68 ±5% inside
|
|
477
|
+
484 @ 2×4 (half the particles) 1.543 1.586 1.595 1.605 1.54 ±4% inside
|
|
478
|
+
256 @ 2×4 0.792 0.804 0.791 0.785 0.79 ±2% inside
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
§18's levers, priced:
|
|
482
|
+
|
|
483
|
+
| Lever | Result |
|
|
484
|
+
|---|---|
|
|
485
|
+
| Fewer iterations — "safe, the solver is stable at one" | 1,024 particles at 2×2: **1.69 ms**, comfortably inside |
|
|
486
|
+
| Fewer particles in the proxy | ~500 particles at the full 2×4: **1.54 ms** |
|
|
487
|
+
| Fewer substeps | 1,024 at 1×4: **1.68 ms** |
|
|
488
|
+
| The barycentric binding fallback (§11.2) | not needed to reach the budget |
|
|
489
|
+
|
|
490
|
+
Any one lever is enough on its own, and they compose. What the budget is *not*
|
|
491
|
+
reachable at is 1,000 particles at 2×4, which is the figure §17 wrote down.
|
|
492
|
+
|
|
493
|
+
**Note what the worker does not do.** §12 moves this off the main thread; it does
|
|
494
|
+
not make it cheaper. "2 ms on the worker" with several characters in flight is a
|
|
495
|
+
scheduling question this measurement does not answer.
|
|
496
|
+
|
|
497
|
+
## 8. Topology note
|
|
498
|
+
|
|
499
|
+
The benchmark's 32×32 patch carries **16.8 row incidences per particle** against
|
|
500
|
+
§17's "about a dozen". That is the honest number for a triangulated sheet with a
|
|
501
|
+
stretch row per edge — including the quad diagonals — and a quadratic bend row
|
|
502
|
+
per interior edge, and it makes this measurement about 40% conservative against
|
|
503
|
+
the workload §17 imagined. A proxy that dropped the diagonals, or used a
|
|
504
|
+
quad-dominant mesh, would carry fewer.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
# Cloth — M1 measurements
|
|
509
|
+
|
|
510
|
+
> Written 2026-09-10, against the M1 implementation in `ecs/`. Everything above
|
|
511
|
+
> this line is M0's and unchanged.
|
|
512
|
+
>
|
|
513
|
+
> Two scripts, both runnable directly under node — the M0 note applies unchanged,
|
|
514
|
+
> and for the same reason:
|
|
515
|
+
>
|
|
516
|
+
> ```
|
|
517
|
+
> node src/engine/physics/cloth/ecs/__fixtures__/cloth_m1_measure.mjs
|
|
518
|
+
> node src/engine/physics/cloth/ecs/__fixtures__/cloth_library_bench.mjs
|
|
519
|
+
> ```
|
|
520
|
+
>
|
|
521
|
+
> And a second playground page, `playground/rig.html`, which is the entity
|
|
522
|
+
> subtree rather than the solver: a real `EntityManager`, real entities, and
|
|
523
|
+
> `ClothSystem` walking and writing back.
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## 9. What M1 proved wrong in PLAN.md
|
|
528
|
+
|
|
529
|
+
Six things, and the first three are sign and scale errors in §6 and §7 that the
|
|
530
|
+
implementation could not have been written around.
|
|
531
|
+
|
|
532
|
+
| # | The design said | The measurement said |
|
|
533
|
+
|---|---|---|
|
|
534
|
+
| 0 | §6 — slack, tether and strain-limit rows clamp to `(−∞, 0]` | Under the solver's own `f -= fc·g` that is the force which pushes a distance row **apart**. A row bounding a distance from *above* needs `[0, +∞)`, and with the table's clamp it never binds at all. §10 |
|
|
535
|
+
| 1 | §3.4 — the leash radius is `slack · d_geo,i` | That makes `slack = 1` a real constraint: a rope hanging straight down cannot swing through 90°, because its tip would move `√2·d_geo`. `2·d_geo` is *provably* inactive given the tether, so the map is `2·slack·d_geo`. §10 |
|
|
536
|
+
| 2 | §7 P1 — the velocity clamp is derived from `thickness` and `h` | `thickness` is a contact radius, so a clamp built from it is a **tunnelling** bound, and a tunnelling bound sits below ordinary cloth speeds: silk at 4 mm gives 0.24 m/s against a measured 29 m/s. The scale that works is the solver's own correction authority. §13 |
|
|
537
|
+
| 3 | §11.1 — "bend rows along each chain" | A chain has no diamond to build a quadratic hinge stencil on. A **skip row** — an ordinary stretch row to the grandparent — costs no new row kind and holds a curved rest shape the quadratic stencil explicitly cannot. §11 |
|
|
538
|
+
| 4 | §17 — the levers each close the 2 ms budget on their own | M1's rows changed the arithmetic. 1,024 particles at 2×4 is **4.61 ms**, not M0's 3.41, and **no single lever reaches 2 ms**. Every garment entry spends two. §14 |
|
|
539
|
+
| 5 | §6 — a strain-limit row governs how far the fabric may extend | It removes about a third of the peak over-stretch at every budget and **never reaches its own allowance** — at `stretch = 1` it asks for 0.1% and delivers 5.9% at 1×1. `ClothDynamics#stretch` is the weakest field in the parameter set. §11 |
|
|
540
|
+
| 6 | §11.1 — the write-back writes `Transform64` | It has to write the **local** `TransformAttachment#transform` too. Writing only the world one leaves the pose one announcement away from being replaced by the authored one, which makes where cloth runs a correctness question; writing both makes a recomposition reproduce it to 1.7e-15 m. §15 |
|
|
541
|
+
|
|
542
|
+
And one thing §4.1 flagged as possibly impossible, which turned out to be
|
|
543
|
+
exactly that: **neither of the engine's two ordering mechanisms can place cloth
|
|
544
|
+
after a poser**, for a structural reason rather than an arithmetic one. What M1
|
|
545
|
+
ships is not a third mechanism — it is a write-back that does not need one. §15.
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## 10. The leash: tether, slack, and the bound that is not unconditional
|
|
550
|
+
|
|
551
|
+
### The tether is what makes a low budget viable
|
|
552
|
+
|
|
553
|
+
A 30-link × 3-strand rig at 5 cm, authored horizontally and dropped through
|
|
554
|
+
ninety degrees, `worst max(‖x − p_anchor‖ / d_geo)` over 600 steps:
|
|
555
|
+
|
|
556
|
+
```
|
|
557
|
+
budget tethered no tether
|
|
558
|
+
1x1 1.0155 1.4650
|
|
559
|
+
1x2 1.0039 1.1899
|
|
560
|
+
2x2 1.0020 1.0568
|
|
561
|
+
2x4 1.0012 1.0199
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
That is §7 P2's claim with a number on it. At one iteration per substep the
|
|
565
|
+
untethered rig reaches **half again its own length** — the rubber cape — and the
|
|
566
|
+
tethered one is inside 1.6%. Note the second column at 2×4: four times the
|
|
567
|
+
budget gets the untethered rig to 1.020, which is still worse than one iteration
|
|
568
|
+
*with* tethers. The tether is not a cheaper way to buy convergence; it answers a
|
|
569
|
+
question the per-edge rows cannot, because a per-edge force travels one hop per
|
|
570
|
+
iteration and a long-range row does not travel at all.
|
|
571
|
+
|
|
572
|
+
### The clamp direction, which §6 has backwards
|
|
573
|
+
|
|
574
|
+
The solver applies `f -= fc·g`, so a **positive** `fc` on a distance row pulls
|
|
575
|
+
its two ends together — that is what `cloth_stretch_row.js` means when it adds
|
|
576
|
+
geometric stiffness for a row "in tension" at `fc > 0`. A row that bounds a
|
|
577
|
+
distance from above must therefore admit positive force and no negative force.
|
|
578
|
+
|
|
579
|
+
§6's table gives Slack, Tether and Strain limit `f_min = −∞, f_max = 0`, which
|
|
580
|
+
admits only the force that pushes the two ends apart. Such a row does not bind
|
|
581
|
+
weakly; it never binds at all, and it would drive a particle *away* from its
|
|
582
|
+
leash centre. The table's collision and self-collision rows are consistent with
|
|
583
|
+
the correct rule once you notice that the collision row writes `C` with the
|
|
584
|
+
opposite sense, so the fix is one column in three rows plus the gloss above it:
|
|
585
|
+
"`[0, +∞)` is push-only, `(−∞, 0]` is pull-only" is only true relative to a
|
|
586
|
+
particular sign of `C`. The exact rule is **`[0, +∞)` admits only forces that
|
|
587
|
+
reduce `C`, and `(−∞, 0]` only forces that increase it.**
|
|
588
|
+
|
|
589
|
+
`cloth_leash_row.spec.js` demonstrates it directly: a particle five metres out
|
|
590
|
+
on a two-metre leash assembles `f = (−30, 0, 0)`, and under §6's clamp that is
|
|
591
|
+
clamped to zero.
|
|
592
|
+
|
|
593
|
+
### `slack = 1` was a constraint, and should not have been
|
|
594
|
+
|
|
595
|
+
§3.4 sets each particle's leash radius to `slack · d_geo,i`, and says `slack = 1`
|
|
596
|
+
means "a particle may be anywhere within its own reach of its animated
|
|
597
|
+
position". It does mean that, and that is a real bound: a rope hanging straight
|
|
598
|
+
down cannot swing through ninety degrees, because its tip has to move `√2·d_geo`
|
|
599
|
+
to get there and its leash is `d_geo`.
|
|
600
|
+
|
|
601
|
+
The radius at which the row is provably inert is `2·d_geo`, and the proof is two
|
|
602
|
+
lines. The tether already holds every particle within `d_geo` of the anchor; the
|
|
603
|
+
animated position it is leashed to is also within `d_geo` of the anchor, since a
|
|
604
|
+
chord is never longer than the arc it subtends; so by the triangle inequality the
|
|
605
|
+
two are never more than `2·d_geo` apart. `r_i = 2·slack·d_geo,i` therefore makes
|
|
606
|
+
`slack = 1` mean exactly "no leash", with no sentinel value and no
|
|
607
|
+
discontinuity — the row is simply not built, because a row that cannot bind is
|
|
608
|
+
not worth visiting.
|
|
609
|
+
|
|
610
|
+
### The bound is conditional on the solver's correction authority
|
|
611
|
+
|
|
612
|
+
The trust region caps each vertex update at the shortest row incident on the
|
|
613
|
+
particle (§5.3), so one fixed step can move a particle at most
|
|
614
|
+
`shortest_row · substeps · iterations`. Past that, a bound is not being violated
|
|
615
|
+
so much as not being given a chance to act. The same rig, kicked sideways:
|
|
616
|
+
|
|
617
|
+
```
|
|
618
|
+
budget kick correction authority worst final
|
|
619
|
+
1x1 2 m/s 3.0 m/s 1.043 1.0025
|
|
620
|
+
1x1 6 m/s 3.0 m/s 1.227 1.0025
|
|
621
|
+
1x1 16 m/s 3.0 m/s 6.867 1.0025
|
|
622
|
+
2x4 2 m/s 24.0 m/s 1.003 1.0000
|
|
623
|
+
2x4 6 m/s 24.0 m/s 1.001 1.0000
|
|
624
|
+
2x4 16 m/s 24.0 m/s 1.063 1.0000
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
A kick five times the authority reaches **6.9× the cloth's own reach**; the same
|
|
628
|
+
kick against eight times the authority reaches 1.06×. The excursion is transient
|
|
629
|
+
in every case — the final column is the reachable-set guarantee of §7 P4(c)
|
|
630
|
+
holding, error not accumulating — but "no particle is ever further from the
|
|
631
|
+
anchor than `d_geo`" is not true as stated, and §7 P2 should say what it is
|
|
632
|
+
conditional on.
|
|
633
|
+
|
|
634
|
+
This is also where M1's velocity clamp comes from. §13.
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## 11. The strain limit, and what `stretch` is worth
|
|
639
|
+
|
|
640
|
+
A 24-link rope at 5 cm, authored horizontally and dropped, `worst max(link
|
|
641
|
+
length / rest length)` over 600 steps. "Allowance" is what
|
|
642
|
+
`cloth_strain_allowance(stretch)` asks for:
|
|
643
|
+
|
|
644
|
+
```
|
|
645
|
+
budget stretch allowance with the row without it
|
|
646
|
+
1x1 0.2 1.0829 1.0863 1.0922
|
|
647
|
+
1x1 0.5 1.0158 1.0631 1.0922
|
|
648
|
+
1x1 1.0 1.0010 1.0586 1.0922
|
|
649
|
+
2x2 0.2 1.0829 1.0351 1.0351
|
|
650
|
+
2x2 0.5 1.0158 1.0289 1.0351
|
|
651
|
+
2x2 1.0 1.0010 1.0216 1.0351
|
|
652
|
+
2x4 0.2 1.0829 1.0140 1.0140
|
|
653
|
+
2x4 0.5 1.0158 1.0140 1.0140
|
|
654
|
+
2x4 1.0 1.0010 1.0094 1.0140
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
Two readings, and the second is the important one.
|
|
658
|
+
|
|
659
|
+
**The row works**: it removes 34–38% of the peak over-stretch, consistently, at
|
|
660
|
+
every budget. On a chain that costs nothing measurable and it is worth having.
|
|
661
|
+
|
|
662
|
+
**And it does not do what §6 says it does.** At `stretch = 1` it asks for 0.1%
|
|
663
|
+
of strain and delivers 5.9% at 1×1 — a factor of fifty out. The reason is
|
|
664
|
+
structural rather than a tuning failure: a strain-limit row is a *second hard
|
|
665
|
+
row on the same edge with the same gradient*, so it competes for the same trust
|
|
666
|
+
region and the same penalty band as the fabric row it is backing up. It can add
|
|
667
|
+
force in a direction force is already being added in, and nothing more.
|
|
668
|
+
|
|
669
|
+
The consequence for the parameter set is that **`stretch` is a weak control over
|
|
670
|
+
most of its range**. Below about `stretch = 0.35` its allowance is looser than
|
|
671
|
+
what a hard row does unaided and the row is inert — see the 0.2 rows, where
|
|
672
|
+
adding it changes nothing at 2×2 and 2×4. Above it the row helps but cannot
|
|
673
|
+
reach what it was asked for. The library says so by which entries set
|
|
674
|
+
`ClothDynamicsFlags.StrainLimit`: the ones at 2×4, where the residual is already
|
|
675
|
+
around 1%, clear it; the ones at 2×2 and the chains keep it.
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## 12. Settling, sleep, and the damping gate
|
|
680
|
+
|
|
681
|
+
### Every library fabric settles and sleeps
|
|
682
|
+
|
|
683
|
+
A 12-link chain at 8 cm, set swinging at 3 m/s, run until the sleep test fires
|
|
684
|
+
(30 consecutive steps with no particle faster than `1e-3 · reach` per second):
|
|
685
|
+
|
|
686
|
+
```
|
|
687
|
+
SILK 770 steps ROPE 501
|
|
688
|
+
COTTON 438 CHAIN 285
|
|
689
|
+
DENIM 220 HAIR 295
|
|
690
|
+
LEATHER 238
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
Twelve seconds at the slowest, and the order is the damping order, which is what
|
|
694
|
+
it should be. Sleep stops the step **and the write-back**, which is what makes
|
|
695
|
+
§7 P5's "bit-identical across the following 300 steps" a fact rather than a
|
|
696
|
+
hope: a pose that is not rewritten cannot drift, and one that is rewritten from
|
|
697
|
+
unchanged inputs is only probably identical.
|
|
698
|
+
|
|
699
|
+
### Damping is load-bearing, and here is the size of it
|
|
700
|
+
|
|
701
|
+
`MEASUREMENTS.md` §6 measured that a **soft** row above about `8·(m/h²)` makes
|
|
702
|
+
the step add energy, and that no solver constant reaches it because `α·γ` decays
|
|
703
|
+
a multiplier and a soft row has none. M1's mapping never produces such a cloth —
|
|
704
|
+
`stretch` maps to `Infinity` precisely because of that measurement — so the row
|
|
705
|
+
stiffness is written in by hand to reproduce it. A 16-link rope at 5 cm with its
|
|
706
|
+
stretch rows forced to 1e5 N/m, a ratio of about 350 against the particle's
|
|
707
|
+
`m/h²` of 288, after 1,500 steps:
|
|
708
|
+
|
|
709
|
+
```
|
|
710
|
+
damping kinetic energy
|
|
711
|
+
0 2.90e-03 J the limit cycle
|
|
712
|
+
0.02 6.18e-05 J
|
|
713
|
+
0.05 2.39e-05 J
|
|
714
|
+
0.12 1.28e-06 J the library's own value
|
|
715
|
+
0.3 7.30e-11 J
|
|
716
|
+
1 1.82e-12 J
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
Three orders of magnitude between undamped and the library default, and seven at
|
|
720
|
+
the top of the range. Note what damping does *not* do: it does not stop the step
|
|
721
|
+
adding energy, it removes energy faster than the step adds it. The equilibrium
|
|
722
|
+
is bounded rather than zero, which is why the numbers keep falling all the way
|
|
723
|
+
to `damping = 1` instead of hitting a floor.
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
## 13. Teleport, locomotion, and where the velocity clamp comes from
|
|
728
|
+
|
|
729
|
+
### Teleport
|
|
730
|
+
|
|
731
|
+
A 16-link rope at 10 cm, swinging on an anchor that has been moving, then
|
|
732
|
+
teleported a kilometre:
|
|
733
|
+
|
|
734
|
+
```
|
|
735
|
+
mode teleports peak speed first-step local shift tip
|
|
736
|
+
Reset 1 0.000 m/s 1.4890 m (1000.000, −1.600)
|
|
737
|
+
Keep 1 5.582 m/s 0.0779 m (1000.003, −1.600)
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
`Reset` re-seeds at the animated pose with zero velocity and the stabilisation
|
|
741
|
+
window ramps the velocity limit back from nothing over 20 steps; the peak speed
|
|
742
|
+
of exactly zero is what a rope authored hanging straight down does when it is
|
|
743
|
+
put back exactly there. `Keep` carries the shape across: the first-step shift is
|
|
744
|
+
one step of ordinary motion, against a metre and a half for the reset, and the
|
|
745
|
+
peak of 5.6 m/s is the swing it was already carrying.
|
|
746
|
+
|
|
747
|
+
**`Keep` is free, and that is a property of the frame rather than a
|
|
748
|
+
coincidence.** MagicaCloth2's `Keep` applies the anchor delta rigidly to every
|
|
749
|
+
particle; in a frame anchored to the cloth's own entity the particles are
|
|
750
|
+
already anchor-relative, so "apply the delta" is doing nothing at all. The
|
|
751
|
+
implementation of `ClothFlags.TeleportKeep` is a `return`.
|
|
752
|
+
|
|
753
|
+
### Fast locomotion
|
|
754
|
+
|
|
755
|
+
20 links at 10 cm, the anchor running a square wave in velocity — sprint, stop
|
|
756
|
+
dead, sprint back, stop dead, one second a phase, fifteen seconds. "Peak" is the
|
|
757
|
+
fastest particle in the cloth-local frame, which is what the clamp bounds:
|
|
758
|
+
|
|
759
|
+
```
|
|
760
|
+
entry peak clamp headroom teleports worst tether
|
|
761
|
+
SILK 29.32 m/s 192.0 m/s 6.5x 0 1.0000
|
|
762
|
+
COTTON 13.97 192.0 13.7 0 0.9999
|
|
763
|
+
DENIM 13.29 96.0 7.2 0 1.0035
|
|
764
|
+
LEATHER 16.80 96.0 5.7 0 1.0018
|
|
765
|
+
ROPE 13.11 192.0 14.6 0 1.0004
|
|
766
|
+
CHAIN 11.32 288.0 25.4 0 1.0003
|
|
767
|
+
HAIR 13.19 192.0 14.6 0 0.9996
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
Nothing teleports — a sprint is locomotion and the threshold knows it — nothing
|
|
771
|
+
leaves its own reach by more than 0.35%, and the smallest headroom over the
|
|
772
|
+
clamp in the whole library is 5.7×.
|
|
773
|
+
|
|
774
|
+
### Why the clamp is not derived from `thickness`
|
|
775
|
+
|
|
776
|
+
§7 P1 asks for a "per-particle velocity clamp derived from `thickness` and `h`",
|
|
777
|
+
and the table above is why that cannot be M1's clamp. `thickness` is a contact
|
|
778
|
+
radius. A clamp built from it answers "may a swept contact still catch this
|
|
779
|
+
particle", and the answer to that sits *below* ordinary cloth speeds rather than
|
|
780
|
+
above them: silk is 4 mm thick, so at 60 Hz one radius per step is 0.24 m/s
|
|
781
|
+
against the 29.3 m/s the same silk reaches behind a sprinter. Any multiple large
|
|
782
|
+
enough to stop the clamp being a *behaviour* for silk is large enough to be
|
|
783
|
+
meaningless for leather, whose thickness is five times silk's and whose speeds
|
|
784
|
+
are not.
|
|
785
|
+
|
|
786
|
+
The scale that does work is the solver's own **correction authority**,
|
|
787
|
+
`shortest_row · substeps · iterations / dt` — the quantity §10 measured a cloth
|
|
788
|
+
losing its bound past. A clamp at four times it is a bound on the solver being
|
|
789
|
+
asked to do more than it can, it scales with the mesh and the budget rather than
|
|
790
|
+
with a radius nothing reads until M2, and the headroom column above says it is a
|
|
791
|
+
backstop rather than a behaviour. M2 still needs the tunnelling bound; it is a
|
|
792
|
+
different number for a different job and it arrives with the contacts.
|
|
793
|
+
|
|
794
|
+
### Inertia
|
|
795
|
+
|
|
796
|
+
The same profile, 10 links, measuring how far the tip lags the anchor:
|
|
797
|
+
|
|
798
|
+
```
|
|
799
|
+
inertia 0 0.0000 m welded into the anchor frame
|
|
800
|
+
inertia 0.25 0.2031 m
|
|
801
|
+
inertia 0.5 0.3681 m
|
|
802
|
+
inertia 0.75 0.5249 m
|
|
803
|
+
inertia 1 0.6522 m feels all of it
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
Monotone, and zero at zero to the last digit — a cloth that feels none of its
|
|
807
|
+
anchor's motion hangs from a sprinting anchor exactly as it would from a
|
|
808
|
+
stationary one, which is what makes `inertia` a dial rather than a switch with a
|
|
809
|
+
meaningless middle.
|
|
810
|
+
|
|
811
|
+
---
|
|
812
|
+
|
|
813
|
+
## 14. The performance budget, again
|
|
814
|
+
|
|
815
|
+
M0 measured the §17 workload at 3.48 ms and priced three levers that each closed
|
|
816
|
+
it. **M1 added rows, and the levers no longer close it.** A 32×32 sheet at 2 cm,
|
|
817
|
+
2 substeps × 4 iterations, adding M1's rows one at a time to M0's:
|
|
818
|
+
|
|
819
|
+
```
|
|
820
|
+
rows particles / stretch / bend / leash best
|
|
821
|
+
M0 rows only 1024 2945 2821 0 3.412 ms
|
|
822
|
+
+ strain limit 1024 5890 2821 0 4.145 ms
|
|
823
|
+
+ tether 1024 5890 2821 992 4.505 ms
|
|
824
|
+
+ slack 1024 5890 2821 1984 4.605 ms
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
The strain limit is the expensive one, at 0.73 ms — it doubles the stretch
|
|
828
|
+
table, and §7 already said the stretch rows are 69% of the frame. The tether is
|
|
829
|
+
0.36 ms and load-bearing. The slack row is 0.10 ms.
|
|
830
|
+
|
|
831
|
+
Against that, the levers:
|
|
832
|
+
|
|
833
|
+
```
|
|
834
|
+
config with strain limit without it
|
|
835
|
+
1024 @ 2x4 4.669 ms OVER 4.146 ms OVER
|
|
836
|
+
1024 @ 2x2 2.380 OVER 2.106 OVER
|
|
837
|
+
1024 @ 1x4 2.395 OVER 2.071 OVER
|
|
838
|
+
1024 @ 1x2 1.167 inside 1.030 inside
|
|
839
|
+
576 @ 2x2 1.280 inside 1.096 inside
|
|
840
|
+
484 @ 2x4 2.533 OVER 2.019 OVER
|
|
841
|
+
484 @ 2x2 1.093 inside 0.909 inside
|
|
842
|
+
400 @ 2x4 1.721 inside 1.493 inside
|
|
843
|
+
324 @ 2x4 1.400 inside 1.259 inside
|
|
844
|
+
256 @ 2x4 1.107 inside 0.959 inside
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
**No single lever reaches 2 ms.** M0's three — half the iterations, half the
|
|
848
|
+
substeps, half the particles — land at 2.38, 2.40 and 2.53 respectively. Every
|
|
849
|
+
one of them lands *inside* when a second lever is spent with it, and that is what
|
|
850
|
+
the library ships:
|
|
851
|
+
|
|
852
|
+
```
|
|
853
|
+
entry budget particles / stretch / bend / leash / colours best
|
|
854
|
+
SILK 2x4 400 1121 1045 760 4 1.488 ms
|
|
855
|
+
COTTON 2x4 400 1121 1045 760 4 1.484 ms
|
|
856
|
+
DENIM 2x2 576 3266 1541 1104 4 1.256 ms
|
|
857
|
+
LEATHER 2x2 576 3266 1541 1104 4 1.248 ms
|
|
858
|
+
ROPE 2x4 41 119 0 40 3 0.043 ms
|
|
859
|
+
CHAIN 2x6 41 119 0 40 3 0.064 ms
|
|
860
|
+
HAIR 2x4 400 1121 1045 760 4 1.429 ms
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
Node v24.15.0 on win32/x64, 600 warm-up frames then 900 measured, 3 rounds, the
|
|
864
|
+
minimum of the minima. The M0 warning still applies and was heeded: each round
|
|
865
|
+
builds a fresh cloth, because a benchmark that reuses a settled one measures a
|
|
866
|
+
converged mesh.
|
|
867
|
+
|
|
868
|
+
Two notes for whoever re-measures at M2. The 3.412 ms in the first table against
|
|
869
|
+
M0's 3.48 for the same workload is the two harnesses agreeing to 2%, which is
|
|
870
|
+
inside M0's own ±5% spread — the row counts and the topology are the same patch.
|
|
871
|
+
And the unreconciled factor-of-five between deletion and isolated-loop
|
|
872
|
+
attribution that §7 records is **not** resolved here; nothing in M1 re-opened it,
|
|
873
|
+
and nothing here should be quoted as having settled it.
|
|
874
|
+
|
|
875
|
+
---
|
|
876
|
+
|
|
877
|
+
## 15. System ordering: not expressible, and not needed
|
|
878
|
+
|
|
879
|
+
§4.1 named this as M1's to establish and admitted the honest possibility that it
|
|
880
|
+
needs a mechanism the engine does not have. The first half is true. The second
|
|
881
|
+
half was the wrong conclusion to draw from it.
|
|
882
|
+
|
|
883
|
+
### Why neither mechanism reaches it
|
|
884
|
+
|
|
885
|
+
The engine orders systems two ways: registration order, and what each system
|
|
886
|
+
declares in `components_used`. `EntityManager#updateExecutionOrder` scores each
|
|
887
|
+
system as a **sum** over the components it references, weighting `Create` above
|
|
888
|
+
`Write` above `Read`, and sorts descending. A score can therefore only be
|
|
889
|
+
*raised* by touching more components or touching them at a higher access level —
|
|
890
|
+
so the only way to sort **later** is to touch strictly less than the system you
|
|
891
|
+
have to follow, and a consumer of a posed hierarchy touches strictly more.
|
|
892
|
+
|
|
893
|
+
Measured, with the real systems and a poser registered *first*:
|
|
894
|
+
|
|
895
|
+
```
|
|
896
|
+
ClothSystem -> TransformAttachmentSystem -> PoserSystem
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
Registration order cannot rescue it, because ties break by registration and this
|
|
900
|
+
is not a tie. Declaring less is not honestly available either — cloth reads
|
|
901
|
+
`Cloth` to know which entities it owns, and `ClothExclude` and
|
|
902
|
+
`TransformAttachment` to walk them.
|
|
903
|
+
|
|
904
|
+
### What the declaration does buy
|
|
905
|
+
|
|
906
|
+
Half of the ordering, and the half that is a real data dependency. Cloth **writes**
|
|
907
|
+
`TransformAttachment#transform` and `TransformAttachmentSystem` **reads** it, so
|
|
908
|
+
writer-before-reader puts cloth first and the attachment system publishes its
|
|
909
|
+
result. That falls out of `components_used` with nothing else asked for, and it
|
|
910
|
+
is the first line of the order above.
|
|
911
|
+
|
|
912
|
+
### What M1 did about the other half
|
|
913
|
+
|
|
914
|
+
**A first attempt added a third mechanism** — an execution-phase number on
|
|
915
|
+
`System`, sorted ahead of the score, with a `PostPose` value that `ClothSystem`
|
|
916
|
+
declared. It worked, and it was wrong twice over: it put the vocabulary of
|
|
917
|
+
animation and posing into `engine/ecs`, a layer that has none, and it bought an
|
|
918
|
+
ordering the design should not have needed. It is recorded here because the
|
|
919
|
+
reasoning that produced it — "the relation is real, the scheduler cannot express
|
|
920
|
+
it, therefore extend the scheduler" — is exactly the reasoning to be suspicious
|
|
921
|
+
of.
|
|
922
|
+
|
|
923
|
+
What ships instead removes the need. Cloth writes each node's **local**
|
|
924
|
+
`TransformAttachment#transform` alongside its world `Transform64`, so a hierarchy
|
|
925
|
+
recomposition reproduces the simulated pose instead of replacing it with the
|
|
926
|
+
authored one:
|
|
927
|
+
|
|
928
|
+
```
|
|
929
|
+
a full recomposition after the write-back moves the pose by 1.665e-15 m
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
(Compared over the matrix. The quaternion can come back **negated** —
|
|
933
|
+
`multiplyTransforms` decomposes the matrix it just wrote, and `q` and `−q` name
|
|
934
|
+
one rotation, so the sign is the decomposition's to choose. Worth knowing before
|
|
935
|
+
writing any bit-identity assertion over a `Transform64`.)
|
|
936
|
+
|
|
937
|
+
With that, where cloth runs is a quality question. Running before the poser means
|
|
938
|
+
reading last step's anchor pose, so the **shape** is one fixed step stale; the
|
|
939
|
+
**position** is not, because the attachment cascade carries the whole subtree
|
|
940
|
+
rigidly with the anchor from cloth's own local transforms. A 16-link, 1.6 m rope,
|
|
941
|
+
worst world-space difference per node between the two orderings:
|
|
942
|
+
|
|
943
|
+
```
|
|
944
|
+
profile 61 steps 121 steps 240 steps 900 steps
|
|
945
|
+
walk 2.4 m/s 0.046 m 0.032 m 0.050 m 0.049 m
|
|
946
|
+
sprint ±9 m/s 0.149 m 0.131 m 0.349 m 0.142 m
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
Three per cent of the cloth's own length under ordinary motion, up to a fifth of
|
|
950
|
+
it at the sharpest velocity reversal a square wave produces, and **not
|
|
951
|
+
accumulating** — the same figure after fifteen seconds as after two, because the
|
|
952
|
+
leash and the tether bound the reachable set.
|
|
953
|
+
|
|
954
|
+
**`InverseKinematicsSystem` is the same shape and reaches the same conclusion.**
|
|
955
|
+
It reads world `Transform64`s "the hierarchy has already composed" and writes
|
|
956
|
+
local ones back, which is the arrangement above, and is why its scoring being
|
|
957
|
+
ambiguous matters less than it looks.
|
|
958
|
+
|
|
959
|
+
---
|
|
960
|
+
|
|
961
|
+
# Cloth — M2 measurements
|
|
962
|
+
|
|
963
|
+
> Written 2026-09-10, against the M2 implementation in `collider/`, the contact
|
|
964
|
+
> and backstop rows in `solver/constraint/`, and `core/geom/3d/shape/sdf/`.
|
|
965
|
+
> Everything above this line is M0's and M1's and is unchanged.
|
|
966
|
+
>
|
|
967
|
+
> Two scripts, both runnable directly under node — the M0 note applies unchanged,
|
|
968
|
+
> and for the same reason:
|
|
969
|
+
>
|
|
970
|
+
> ```
|
|
971
|
+
> node src/engine/physics/cloth/solver/__fixtures__/cloth_m2_measure.mjs
|
|
972
|
+
> node src/engine/physics/cloth/solver/__fixtures__/cloth_m2_band.mjs
|
|
973
|
+
> ```
|
|
974
|
+
>
|
|
975
|
+
> And a third playground page, `playground/collide.html`, which is the packed
|
|
976
|
+
> collider table rather than the ECS: six scenes, a sweep toggle, and the two
|
|
977
|
+
> contact-band sliders live.
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
## 16. What M2 proved wrong in PLAN.md
|
|
982
|
+
|
|
983
|
+
Six things. The first is a sign error in the design that would have been silent,
|
|
984
|
+
and the second is one M2 made itself and then measured its way out of.
|
|
985
|
+
|
|
986
|
+
| # | The design said | The measurement said |
|
|
987
|
+
|---|---|---|
|
|
988
|
+
| 0 | §8.2 — swept collision interpolates "between the previous and current **matrices**" | A component-wise lerp of two rotation matrices is not a rotation. In the rotation plane it scales by `cos(θ/2)`, so the shape it poses **shrinks**: at the half-radian per step `CLOTH_ANCHOR_ROTATION_LIMIT` already calls a spin, a 25 cm collider loses 7.8 mm halfway through every step — *twice* a silk garment's thickness. A rigid pose interpolates as a translation and a quaternion. §19 |
|
|
989
|
+
| 1 | §8.2 — the sweep is what stops a fast collider being missed | Only if the contact **set** is swept too. Discovery evaluates at the end-of-step pose, so a capsule that crossed the cloth *within* the step is nowhere near it by then: at 20 m/s the pass created **zero rows** and the sheet was untouched — not tunnelled through so much as never noticed. Adding the collider's travel to the discovery reach costs one subtraction a record and makes 2 to 40 m/s behave alike. §20 |
|
|
990
|
+
| 2 | §6 — the collision row carries `k_contact` and friction carries `k_friction` | By M0's own rule a stiffness that is not `Infinity` is a **soft** row, and a soft row's whole force is `k·C` with `k` capped at `8·(m/h²)` — 4.6 N at one thickness of penetration, against the 11 to 376 N the hard row actually produced on a sheet arriving at 1 to 8 m/s. Both rows are hard. §18 |
|
|
991
|
+
| 3 | §6 — friction clamps at `±μ·f_n` | That is the *signed-slip* formulation, which needs a tangent basis chosen per contact — and any choice continuous frame to frame is state, which is what §7 P4(a) exists to keep out. Written as the magnitude of the slip the row is `[0, μ·f_n]`, the same physics with no basis. §18 |
|
|
992
|
+
| 4 | §5.4 — contact rows "never enter" `ClothState` and are applied Jacobi-style | A collider contact is **unary** — one particle against a surface fixed for the substep — so it couples no two particles and there is no Gauss-Seidel/Jacobi distinction to make. It accumulates in the vertex update like a leash row. What is true is that it comes and goes, which is a *storage* problem and not an ordering one. §18 |
|
|
993
|
+
| 5 | §5.2 — Chebyshev acceleration is "available and disabled" | Built, measured against the contacts it is gated on, and removed. It does not help at any spectral radius tried, costs 2–5%, and diverges past `ρ = 0.9`. §21 |
|
|
994
|
+
|
|
995
|
+
And one thing that is a property of a configuration rather than of the solver,
|
|
996
|
+
recorded because it looks like a solver failure: **an exactly axis-aligned rope
|
|
997
|
+
pushed by an exactly axis-aligned plane has no lateral degree of freedom to
|
|
998
|
+
buckle into**, and folds into an accordion that is an exact equilibrium. §22.
|
|
999
|
+
|
|
1000
|
+
---
|
|
1001
|
+
|
|
1002
|
+
## 17. The contact penalty band, and `β` at last
|
|
1003
|
+
|
|
1004
|
+
M0 chose `k_min = k_max` — no ramp — and said so honestly: the ramp exists for
|
|
1005
|
+
**transient** rows, a contact that should arrive soft rather than shock the mesh
|
|
1006
|
+
on its first frame, and M0 had none. M1 had none either. M2 has them, and this
|
|
1007
|
+
is that measurement.
|
|
1008
|
+
|
|
1009
|
+
A 400-particle sheet, 4 mm thick, dropped flat onto a ground plane at 2 substeps
|
|
1010
|
+
× 4 iterations. Cells are worst penetration in metres over the run / kinetic
|
|
1011
|
+
energy after 240 steps. **Every configuration in the grid settles to a resting
|
|
1012
|
+
penetration of 7.9e-8 m** — the differences below are entirely about the
|
|
1013
|
+
transient.
|
|
1014
|
+
|
|
1015
|
+
```
|
|
1016
|
+
arriving at 3 m/s
|
|
1017
|
+
|
|
1018
|
+
k_min/k_max β=0e+0 β=1e+2 β=1e+3 β=1e+4 β=1e+5
|
|
1019
|
+
× 0.00781 1.08e-2/7.65e-9 1.08e-2/2.83e-8 1.08e-2/1.54e-8 1.08e-2/6.91e-9 1.08e-2/4.06e-6
|
|
1020
|
+
× 0.03125 1.08e-2/2.04e-8 1.08e-2/1.56e-8 1.08e-2/3.20e-8 1.08e-2/4.85e-8 1.08e-2/6.42e-5
|
|
1021
|
+
× 0.12500 1.08e-2/2.89e-6 1.08e-2/2.92e-6 1.08e-2/3.19e-6 1.08e-2/7.42e-6 1.08e-2/4.85e-4
|
|
1022
|
+
× 0.50000 2.22e-2/9.77e-3 2.26e-2/1.38e-2 2.29e-2/3.36e-2 1.99e-2/2.08e-2 2.03e-2/5.71e-3
|
|
1023
|
+
× 1.00000 1.60e-2/1.11e-2 1.60e-2/1.11e-2 1.60e-2/1.11e-2 1.60e-2/1.11e-2 1.60e-2/1.11e-2
|
|
1024
|
+
|
|
1025
|
+
arriving at 8 m/s
|
|
1026
|
+
|
|
1027
|
+
k_min/k_max β=0e+0 β=1e+2 β=1e+3 β=1e+4 β=1e+5
|
|
1028
|
+
× 0.00781 1.12e-1/2.51e+0 9.51e-2/3.99e-2 8.11e-2/1.09e-1 1.16e-1/2.55e-1 1.14e-1/2.65e-2
|
|
1029
|
+
× 0.03125 1.06e-1/1.95e+0 1.11e-1/2.74e-1 8.55e-2/1.16e-1 8.99e-2/5.01e-1 8.05e-2/6.16e-1
|
|
1030
|
+
× 0.12500 1.22e-1/5.80e-1 1.18e-1/8.35e-2 9.92e-2/2.77e-1 1.28e-1/2.42e-1 1.25e-1/8.04e-2
|
|
1031
|
+
× 0.50000 1.21e-1/2.48e-1 1.19e-1/2.02e-1 1.25e-1/2.29e-1 1.05e-1/2.65e-1 8.47e-2/2.27e-1
|
|
1032
|
+
× 1.00000 9.34e-2/2.76e-1 9.34e-2/2.76e-1 9.34e-2/2.76e-1 9.34e-2/2.76e-1 9.34e-2/2.76e-1
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
The bottom row is flat across `β` because at `k_min = k_max` the penalty is
|
|
1036
|
+
already at the ceiling and `min(k + β|C|, k_max)` has nothing to do — which is
|
|
1037
|
+
exactly M0's configuration, reproduced here as the control.
|
|
1038
|
+
|
|
1039
|
+
**The floor is what matters, and lower is better.** At `×1` a 3 m/s landing peaks
|
|
1040
|
+
at 18.9 N of contact force and settles at 1.1e-2 J; at `×1/8` it peaks at 0.16 N
|
|
1041
|
+
and settles at 2.9e-6 J, and the *penetration improves* from 1.6 cm to 1.1 cm at
|
|
1042
|
+
the same time. Below about `×1/8` the penetration column stops moving entirely —
|
|
1043
|
+
1.08e-2 to three figures from `×1/8` down to `×1/128`.
|
|
1044
|
+
|
|
1045
|
+
That flatness is the augmented Lagrangian working as designed and is worth
|
|
1046
|
+
stating plainly: **the penalty only has to be large enough to generate a
|
|
1047
|
+
multiplier**, and the multiplier carries the load. A stiffer floor buys nothing
|
|
1048
|
+
except a harder first frame.
|
|
1049
|
+
|
|
1050
|
+
**`β` earns its place at the fast arrival and nowhere else.** At 3 m/s every
|
|
1051
|
+
value from 0 to 1e4 is indistinguishable. At 8 m/s, `β = 0` leaves the penalty at
|
|
1052
|
+
the floor for the whole impact and the residual energy is 1.95 to 2.51 J against
|
|
1053
|
+
0.11 to 0.12 J at `β = 1e3`; and `β = 1e5` reaches the ceiling on millimetre
|
|
1054
|
+
violations, giving back most of what the low floor bought — 6.4e-5 J against
|
|
1055
|
+
3.2e-8 J on the gentle landing.
|
|
1056
|
+
|
|
1057
|
+
**Chosen: `k_min = k_max/32`, `β = 1e3`.** The floor sits in the middle of the
|
|
1058
|
+
flat region with two decades of ramp above it; `β` sits in the middle of the
|
|
1059
|
+
range where the fast arrival is well behaved and the slow one is unaffected.
|
|
1060
|
+
|
|
1061
|
+
### The other direction a contact arrives from
|
|
1062
|
+
|
|
1063
|
+
The grid above is cloth arriving at a stationary collider. A garment's contacts
|
|
1064
|
+
are mostly the other way round — a bone driven into stationary cloth — and a
|
|
1065
|
+
floor low enough to make a landing gentle could plausibly be a floor a pushed
|
|
1066
|
+
collider gets further through. Measured, on a sphere driven 6 cm into a hanging
|
|
1067
|
+
cape at 1 m/s, beside the same landing:
|
|
1068
|
+
|
|
1069
|
+
```
|
|
1070
|
+
floor cape: sphere driven in at 1 m/s sheet: landing at 3 m/s
|
|
1071
|
+
worst resting kinetic worst force N kinetic
|
|
1072
|
+
×1.00000 3.02e-3 3.96e-4 3.59e-2 1.32e-2 1.963 2.11e-3
|
|
1073
|
+
×0.25000 2.60e-3 2.95e-4 2.44e-2 1.08e-2 0.805 1.41e-4
|
|
1074
|
+
×0.12500 2.56e-3 3.04e-4 2.56e-2 1.08e-2 0.800 2.67e-5
|
|
1075
|
+
×0.03125 2.66e-3 2.90e-4 2.25e-2 1.08e-2 0.803 9.99e-7
|
|
1076
|
+
×0.00781 2.71e-3 3.08e-4 2.36e-2 1.08e-2 0.805 5.35e-8
|
|
1077
|
+
|
|
1078
|
+
and the same cape with the sphere driven in faster:
|
|
1079
|
+
|
|
1080
|
+
floor 1 m/s 3 m/s 8 m/s (worst penetration, m)
|
|
1081
|
+
×1.00000 3.02e-3 6.54e-3 3.55e-2
|
|
1082
|
+
×0.12500 2.56e-3 5.53e-3 3.14e-2
|
|
1083
|
+
×0.03125 2.66e-3 5.69e-3 3.25e-2
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
They do not disagree. The cape's penetration stays inside its own 4 mm thickness
|
|
1087
|
+
at every floor and at every speed up to 3 m/s, and the lower floors are
|
|
1088
|
+
marginally *better* rather than worse. The choice above holds on both.
|
|
1089
|
+
|
|
1090
|
+
---
|
|
1091
|
+
|
|
1092
|
+
## 18. The contact row: hard, and what a soft one could have delivered
|
|
1093
|
+
|
|
1094
|
+
§6's table gives Collision a stiffness `k_contact` and Friction a `k_friction`,
|
|
1095
|
+
and M0's rule makes that literal: **a row is hard exactly when its stiffness is
|
|
1096
|
+
`Infinity`**, so a named stiffness is a statement that both rows are soft
|
|
1097
|
+
penalties.
|
|
1098
|
+
|
|
1099
|
+
A soft row's entire force is `k·C`, and M0 measured the largest `k` a soft row
|
|
1100
|
+
may carry and still dissipate: `8·(m/h²)`. So the most force a soft contact can
|
|
1101
|
+
produce before the cloth is a full thickness inside the collider is
|
|
1102
|
+
`8·(m/h²)·thickness`. Against what the hard row actually had to produce:
|
|
1103
|
+
|
|
1104
|
+
```
|
|
1105
|
+
a soft row's ceiling at one thickness of penetration: 4.608 N
|
|
1106
|
+
|
|
1107
|
+
arriving at 0.0 m/s: the hard row produced 0.582 N ( 0.13× the ceiling)
|
|
1108
|
+
arriving at 1.0 m/s: 11.063 N ( 2.40×)
|
|
1109
|
+
arriving at 3.0 m/s: 18.908 N ( 4.10×)
|
|
1110
|
+
arriving at 8.0 m/s: 375.655 N (81.52×)
|
|
1111
|
+
```
|
|
1112
|
+
|
|
1113
|
+
A cloth that is merely *resting* is inside what a soft row could do — 13% of it.
|
|
1114
|
+
Anything that arrives is not. A soft contact row is therefore a contact that
|
|
1115
|
+
holds a draped garment and fails every time the garment is put down, and the
|
|
1116
|
+
failure is proportional to the impact.
|
|
1117
|
+
|
|
1118
|
+
Both rows are hard: `Infinity` stiffness, the penalty band of §17, and the
|
|
1119
|
+
multiplier carrying the load.
|
|
1120
|
+
|
|
1121
|
+
### Friction against the analytic answer
|
|
1122
|
+
|
|
1123
|
+
Coulomb says a body sticks when `μ > tan θ` and slides when it does not. A 20×20
|
|
1124
|
+
sheet released on an inclined plane, metres travelled downhill in four seconds:
|
|
1125
|
+
|
|
1126
|
+
```
|
|
1127
|
+
slope tan θ μ=0.0 μ=0.2 μ=0.4 μ=0.7 μ=1.2
|
|
1128
|
+
10° 0.1763 6.9139 0.0001 0.0000 0.0000 0.0000
|
|
1129
|
+
20° 0.3640 13.5772 5.6235 0.0001 0.0001 0.0000
|
|
1130
|
+
30° 0.5774 19.6705 11.7592 5.0431 0.0002 0.0001
|
|
1131
|
+
40° 0.8391 24.5862 16.9339 10.5951 2.8836 0.0002
|
|
1132
|
+
50° 1.1918 27.4699 20.5496 14.9029 8.1086 0.0007
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
The transition sits on `tan θ` in every row: 0.2 sticks at 10° and slides at 20°,
|
|
1136
|
+
0.4 sticks at 20° and slides at 30°, 0.7 sticks at 30° and slides at 40°, 1.2
|
|
1137
|
+
sticks at 50°. The sticking cells are tenths of a millimetre over four seconds,
|
|
1138
|
+
which is the row holding rather than creeping.
|
|
1139
|
+
|
|
1140
|
+
**The clamp is `[0, μ·f_n]`, not `±μ·f_n`.** §6's symmetric pair is the
|
|
1141
|
+
signed-slip formulation: a row whose `C` is a displacement along a chosen
|
|
1142
|
+
tangent. This row's `C` is the *magnitude* of the slip in the tangent plane, so
|
|
1143
|
+
`C ≥ 0` always and the negative half of the clamp would name a force pulling the
|
|
1144
|
+
particle further from where it stuck. Writing it as a magnitude is also what
|
|
1145
|
+
removes the tangent basis — a signed row needs two of them per contact, and any
|
|
1146
|
+
choice that is continuous frame to frame carries state, which is the thing §7
|
|
1147
|
+
P4(a) exists to keep out of this system.
|
|
1148
|
+
|
|
1149
|
+
**The cap reads the current iteration's normal force, not the previous
|
|
1150
|
+
iteration's multiplier.** VBD uses the multiplier, which is one iteration stale
|
|
1151
|
+
and therefore exactly zero on a contact's first iteration — so at the one
|
|
1152
|
+
iteration per substep §5.1 says the solver must be usable at, friction would
|
|
1153
|
+
never act at all.
|
|
1154
|
+
|
|
1155
|
+
### Contacts are unary, so §5.4's Jacobi treatment is not needed here
|
|
1156
|
+
|
|
1157
|
+
§5.4 says contact rows "cannot be pre-coloured", are "accumulated into a
|
|
1158
|
+
per-particle scratch buffer and applied Jacobi-style", and that this is what
|
|
1159
|
+
makes a step deterministic regardless of how many contacts a particle picked up.
|
|
1160
|
+
|
|
1161
|
+
Half of that is a solution to a problem a *collider* contact does not have. A
|
|
1162
|
+
contact against a collider touches **one** particle: the collider is fixed for
|
|
1163
|
+
the substep, so the row couples no two particles, so there is no Gauss-Seidel
|
|
1164
|
+
versus Jacobi distinction to make and nothing to keep out of the colouring. It
|
|
1165
|
+
accumulates in the vertex update exactly like a leash row, in colour order, and
|
|
1166
|
+
the step is deterministic because the contact *set* is built by one pass in a
|
|
1167
|
+
fixed order over a fixed table.
|
|
1168
|
+
|
|
1169
|
+
What is true is that a contact comes and goes, so it cannot be a CSR table sized
|
|
1170
|
+
at build time. M2's answer is a fixed **four slots per particle** inside
|
|
1171
|
+
`ClothState`'s own buffer, rebuilt each step, keyed on the collider's index
|
|
1172
|
+
handle so a multiplier survives the rebuild. §5.4's reasoning applies unchanged
|
|
1173
|
+
to M4's particle-particle rows, which really are pairs.
|
|
1174
|
+
|
|
1175
|
+
Four slots is generous. On the 20-collider budget scene, over 100 steps × 1,024
|
|
1176
|
+
particles: **zero particle-steps reached the slot limit**, and the mean occupancy
|
|
1177
|
+
was 0.10 slots per particle. The cost of the generosity is 36 words per particle
|
|
1178
|
+
— 147 KB at 1,024 particles against `ClothState`'s 370 KiB, a 40% increase in
|
|
1179
|
+
state for a structure that was never more than a quarter full. It is kept at four
|
|
1180
|
+
because the case it is sized for is an armpit rather than a sheet on a floor, and
|
|
1181
|
+
M3's garments are where that will be visible.
|
|
1182
|
+
|
|
1183
|
+
---
|
|
1184
|
+
|
|
1185
|
+
## 19. The interpolated pose is a rigid pose, not a lerp of matrices
|
|
1186
|
+
|
|
1187
|
+
§8.2 says swept behaviour "comes from interpolating the collider's pose between
|
|
1188
|
+
the previous and current **matrices** at the substep's fraction". That is the one
|
|
1189
|
+
part of §8 that does not work, and the reason is arithmetic rather than taste: a
|
|
1190
|
+
component-wise lerp of two rotation matrices is not a rotation matrix. Halfway
|
|
1191
|
+
through a turn of `θ` its columns are shorter by `cos(θ/2)` in the rotation
|
|
1192
|
+
plane, so the shape it poses is *shrunk*.
|
|
1193
|
+
|
|
1194
|
+
```
|
|
1195
|
+
θ (rad) |lerp(I,R)·x| shrink on a 25 cm collider vs a 4 mm cloth
|
|
1196
|
+
0.050 0.999688 0.078 mm 0.02×
|
|
1197
|
+
0.100 0.998750 0.312 mm 0.08×
|
|
1198
|
+
0.250 0.992198 1.951 mm 0.49×
|
|
1199
|
+
0.500 0.968912 7.772 mm 1.94×
|
|
1200
|
+
1.000 0.877583 30.604 mm 7.65×
|
|
1201
|
+
1.571 0.707107 73.223 mm 18.31×
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
`CLOTH_ANCHOR_ROTATION_LIMIT` is half a radian per step, so 0.5 is the fastest
|
|
1205
|
+
rotation a cloth is allowed to see, and the shrink there is already twice a
|
|
1206
|
+
garment's thickness. A collider that shrinks by twice the cloth's thickness
|
|
1207
|
+
halfway through every step is a collider cloth passes through for reasons that
|
|
1208
|
+
have nothing to do with speed.
|
|
1209
|
+
|
|
1210
|
+
A translation and a quaternion interpolate rigidly by construction — the
|
|
1211
|
+
quaternion is renormalised, so its column reads 1.000000 at every angle — and
|
|
1212
|
+
that is what `ClothColliderRecord` stores. The `nlerp` is not constant angular
|
|
1213
|
+
velocity and over the fraction of a fixed step it does not need to be.
|
|
1214
|
+
|
|
1215
|
+
---
|
|
1216
|
+
|
|
1217
|
+
## 20. Sweeping the poses is not enough; the *set* has to be swept too
|
|
1218
|
+
|
|
1219
|
+
M2 built §8.2's pose interpolation, measured it against a capsule driven through
|
|
1220
|
+
a hanging sheet, and found it doing nothing at all above 5 m/s. The reason was
|
|
1221
|
+
not the interpolation.
|
|
1222
|
+
|
|
1223
|
+
`cloth_contact_find` runs once per step and evaluates the field at the
|
|
1224
|
+
**end-of-step** pose. A collider that crossed the cloth *within* the step is
|
|
1225
|
+
already past it by then, so the speculative margin — twice the contact offset,
|
|
1226
|
+
8 mm on a garment — finds nothing, no row is created, and the swept poses have
|
|
1227
|
+
nothing to act through.
|
|
1228
|
+
|
|
1229
|
+
```
|
|
1230
|
+
speed pose worst penetration deep rows/step
|
|
1231
|
+
2 m/s swept (§8.2) 1.85e-2 m 0 16.4
|
|
1232
|
+
2 m/s end-of-step 3.99e-2 m 4 7.2
|
|
1233
|
+
5 m/s swept (§8.2) 3.38e-2 m 1 14.5
|
|
1234
|
+
5 m/s end-of-step 0.00e+0 m 0 1.4
|
|
1235
|
+
10 m/s swept (§8.2) 3.08e-4 m 0 31.3
|
|
1236
|
+
10 m/s end-of-step 0.00e+0 m 0 1.4
|
|
1237
|
+
20 m/s swept (§8.2) 0.00e+0 m 0 94.8
|
|
1238
|
+
20 m/s end-of-step 0.00e+0 m 0 0.0
|
|
1239
|
+
40 m/s swept (§8.2) 0.00e+0 m 0 160.0
|
|
1240
|
+
40 m/s end-of-step 0.00e+0 m 0 0.0
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
Read the last column first. "end-of-step" — the previous pose set equal to the
|
|
1244
|
+
current one, which is what §8.2 would be without the sweep — creates **no rows at
|
|
1245
|
+
all** at 20 and 40 m/s. Its zero penetration is not a contact working; it is a
|
|
1246
|
+
capsule passing through a sheet that never knew it was there. "deep" counts
|
|
1247
|
+
particle-steps more than half a capsule radius inside, and the swept column holds
|
|
1248
|
+
it at zero or one across the whole range.
|
|
1249
|
+
|
|
1250
|
+
The fix is one subtraction per record per step: **the discovery reach includes
|
|
1251
|
+
how far the collider moved.** A particle within `offset·(1 + margin) + travel` of
|
|
1252
|
+
the end-of-step surface gets a row, which stays clamped out until a substep's
|
|
1253
|
+
interpolated pose actually brings the collider onto it.
|
|
1254
|
+
|
|
1255
|
+
That is also the honest boundary of P3. The *set* is swept by this margin and the
|
|
1256
|
+
*poses* by `cloth_collider_pose_at`, and both are translation-first: a collider
|
|
1257
|
+
spinning fast enough that a point on its surface travels more than its own radius
|
|
1258
|
+
within one substep is still missed, and more substeps is the answer to it.
|
|
1259
|
+
|
|
1260
|
+
---
|
|
1261
|
+
|
|
1262
|
+
## 21. Chebyshev acceleration: built, measured, removed
|
|
1263
|
+
|
|
1264
|
+
§5.2 carries Chebyshev acceleration as "available and disabled by default, turned
|
|
1265
|
+
on per-dynamics only where it measurably helps", gated on a particle not being in
|
|
1266
|
+
contact this step — which is why M0 and M1 could not evaluate it and M2 is the
|
|
1267
|
+
first milestone that can.
|
|
1268
|
+
|
|
1269
|
+
Implemented as the paper specifies: `ω₁ = 1`, `ω₂ = 2/(2−ρ²)`, `ωₙ = 4/(4−ρ²ωₙ₋₁)`,
|
|
1270
|
+
applied as `x ← ω(x − x^(k−1)) + x^(k−1)` after each colour sweep, skipping every
|
|
1271
|
+
particle with a contact slot.
|
|
1272
|
+
|
|
1273
|
+
```
|
|
1274
|
+
a 400-particle sheet landing at 3 m/s
|
|
1275
|
+
|
|
1276
|
+
ρ worst pen. resting pen. kinetic@240 ms/step
|
|
1277
|
+
0.00 1.60e-2 7.90e-8 1.11e-2 3.604
|
|
1278
|
+
0.50 1.42e-2 7.90e-8 1.67e-2 3.773
|
|
1279
|
+
0.80 1.70e-2 7.90e-8 1.50e-2 3.682
|
|
1280
|
+
0.90 7.72e-2 4.71e-2 7.60e+1 3.345
|
|
1281
|
+
0.95 4.05e+10 3.66e+10 3.87e+26 3.588
|
|
1282
|
+
0.99 diverged — a Hessian pivot reached Infinity
|
|
1283
|
+
|
|
1284
|
+
a hanging cape with a sphere pushed 6 cm into it, where most particles
|
|
1285
|
+
are free and the acceleration has room:
|
|
1286
|
+
|
|
1287
|
+
ρ=0.00 worst 5.78e-4 resting 3.00e-4 kinetic 4.70e-4
|
|
1288
|
+
ρ=0.80 worst 3.31e-4 resting 3.10e-4 kinetic 4.90e-3
|
|
1289
|
+
ρ=0.95 worst 3.06e-3 resting 0.00e+0 kinetic 1.68e+46
|
|
1290
|
+
```
|
|
1291
|
+
|
|
1292
|
+
The best cell in the table is the cape at `ρ = 0.8`, which takes a third off the
|
|
1293
|
+
penetration and pays ten times the residual kinetic energy for it — a livelier
|
|
1294
|
+
cloth, not a better-converged one. Everything else is inside the run-to-run
|
|
1295
|
+
spread or worse, the cost is 2–5%, and the top of the parameter range detonates.
|
|
1296
|
+
|
|
1297
|
+
Removed. The grid is here so that a future attempt starts from the numbers rather
|
|
1298
|
+
than from the idea, and `cloth_step.js` says where the branch was.
|
|
1299
|
+
|
|
1300
|
+
---
|
|
1301
|
+
|
|
1302
|
+
## 22. A rope with no lateral freedom stands on its own end
|
|
1303
|
+
|
|
1304
|
+
Not a solver defect, and recorded because it looks exactly like one.
|
|
1305
|
+
|
|
1306
|
+
A rope authored exactly along −Y, compressed by a floor whose normal is exactly
|
|
1307
|
+
+Y, has every force, every constraint gradient and every position on one axis.
|
|
1308
|
+
There is no lateral component anywhere in the system, so the accordion fold it
|
|
1309
|
+
lands in is an **exact equilibrium**: every link is at its rest length, the
|
|
1310
|
+
residual is zero, and nothing — including §7 P4(d)'s escape hatch, which watches
|
|
1311
|
+
the residual — has anything to act on.
|
|
1312
|
+
|
|
1313
|
+
An 8-link rope of 10 cm links, hanging from the origin onto a floor at −0.4:
|
|
1314
|
+
|
|
1315
|
+
```
|
|
1316
|
+
lean tip y after 200 steps what it did
|
|
1317
|
+
0 −0.201 folded, and stayed folded
|
|
1318
|
+
0.001 −0.385 lay down, one thickness clear of the floor
|
|
1319
|
+
0.01 −0.385 the same
|
|
1320
|
+
```
|
|
1321
|
+
|
|
1322
|
+
`lean` is a lateral offset per link as a fraction of the link length, so 0.001 is
|
|
1323
|
+
a millimetre across a 10 cm link. **One part in a thousand is enough**, and no
|
|
1324
|
+
authored scene is closer to symmetric than that. The tip of the leaning rope
|
|
1325
|
+
lands at −0.385 against a floor at −0.4 and a `CLOTH_ROPE` thickness of 15 mm,
|
|
1326
|
+
which is the contact row holding it exactly one offset clear.
|
|
1327
|
+
|
|
1328
|
+
Recorded rather than fixed. The fix would be a lateral perturbation injected by
|
|
1329
|
+
the solver, which is noise added to a system whose whole design commitment is
|
|
1330
|
+
that it does not need any.
|
|
1331
|
+
|
|
1332
|
+
---
|
|
1333
|
+
|
|
1334
|
+
## 23. The frame budget with contacts in it
|
|
1335
|
+
|
|
1336
|
+
M1 measured the §17 workload — 1,024 particles at 2 substeps × 4 iterations on a
|
|
1337
|
+
32×32 patch — at 4.61 ms and re-sized the library around it. M2 adds a broadphase
|
|
1338
|
+
pass per particle per step, up to four contact rows per particle, and two field
|
|
1339
|
+
evaluations per contact per iteration.
|
|
1340
|
+
|
|
1341
|
+
```
|
|
1342
|
+
no collider system 4.426 ms 0 contact rows
|
|
1343
|
+
1 collider, out of range 4.473 ms + 1.1% 0 contact rows
|
|
1344
|
+
1 collider, touching 5.485 ms + 23.9% 4 contact rows
|
|
1345
|
+
4 colliders, touching 5.077 ms + 14.7% 41 contact rows
|
|
1346
|
+
8 colliders, touching 4.610 ms + 4.2% 72 contact rows
|
|
1347
|
+
20 colliders, touching 4.829 ms + 9.1% 107 contact rows
|
|
1348
|
+
```
|
|
1349
|
+
|
|
1350
|
+
**Read the range, not the rows.** The column is not monotone in the collider
|
|
1351
|
+
count — one collider costs more than eight — because the variants sit in
|
|
1352
|
+
different physical states, which is the same warning §7 gave about attributing
|
|
1353
|
+
cost by deletion. A cloth draped over a sphere is not the same workload as one
|
|
1354
|
+
hanging free, whatever the row count says.
|
|
1355
|
+
|
|
1356
|
+
What the table does license: **the collision layer costs between nothing and a
|
|
1357
|
+
quarter of a frame, and does not scale with the collider count over the range a
|
|
1358
|
+
character occupies.** The broadphase — a particle against a collider's swept AABB
|
|
1359
|
+
— is the part that does scale, and one collider out of range costs 1.1%, so
|
|
1360
|
+
twenty of them out of range would be about a fifth of a frame and worth a
|
|
1361
|
+
per-cloth spatial structure if a scene ever wants that many.
|
|
1362
|
+
|
|
1363
|
+
**The library is not re-sized.** M1's entries were chosen against 4.61 ms for the
|
|
1364
|
+
§17 workload and M2 measures 4.43 ms for the same thing — agreement to 4%, inside
|
|
1365
|
+
M1's own ±5% spread — and the worst contact case lands at 5.49 ms, which is 19%
|
|
1366
|
+
over M1's figure on a workload the library already spends two levers to avoid.
|
|
1367
|
+
Every entry's own budget is unchanged; §17's table stands. M4's self-collision is
|
|
1368
|
+
the next thing that could move it, and §17 already says so.
|
|
1369
|
+
|
|
1370
|
+
---
|
|
1371
|
+
|
|
1372
|
+
# Cloth — M3 measurements
|
|
1373
|
+
|
|
1374
|
+
> Written 2026-09-10, against the M3 implementation in `build/` and the rig path
|
|
1375
|
+
> in `ecs/`. Everything above this line is M0's, M1's and M2's and is unchanged.
|
|
1376
|
+
>
|
|
1377
|
+
> Two scripts, both runnable directly under node — the M0 note applies unchanged:
|
|
1378
|
+
>
|
|
1379
|
+
> ```
|
|
1380
|
+
> node src/engine/physics/cloth/ecs/__fixtures__/cloth_m3_measure.mjs
|
|
1381
|
+
> node src/engine/physics/cloth/build/__fixtures__/cloth_m3_joint_budget.mjs
|
|
1382
|
+
> ```
|
|
1383
|
+
>
|
|
1384
|
+
> And a fourth playground page, `playground/garment.html`, which is a `Node3D`
|
|
1385
|
+
> skeleton with a `Skin` over it and a garment built out of some of its joints.
|
|
1386
|
+
|
|
1387
|
+
---
|
|
1388
|
+
|
|
1389
|
+
## 24. What M3 proved wrong in PLAN.md
|
|
1390
|
+
|
|
1391
|
+
Four things, and the first is the one the whole rig path turns on.
|
|
1392
|
+
|
|
1393
|
+
| # | The design said | The measurement said |
|
|
1394
|
+
|---|---|---|
|
|
1395
|
+
| 0 | §11.2 — the writable handle is "the joint's `Node3D.transform_local` — **the same handle the animation systems write**" | The animation systems do not write it. `TransformAuthority` is explicit: a node a clip drives is `GPU`, and "the CPU allocates and seeds the row, then never writes to it again, so the node's own `transform_local` stops describing it and should not be read as if it did". Cloth writing it on such a node writes to something nothing reads. The seed **claims `CPU`** on every joint it drives, which takes those joints away from the animation — the right trade for a cape, and an authoring error for a garment whose joints are also keyed. §25 |
|
|
1396
|
+
| 1 | §11.1 — the rig path is "where the animated pose comes from the skeleton and **is live**" | Not for a rigged garment, and for the reason above: cloth owns those joints, so nothing else poses them, so their authored pose is the proxy's baked bind pose — constant in the anchor's frame, exactly as a rope's is. What moves is the anchor. The live case is the *unrigged* path, where the targets are mesh vertices skinned to the character's skeleton. §25 |
|
|
1397
|
+
| 2 | §11.3 step 5 — the fixed set comes from skin weights | That is the right rule for the unrigged path, where the particles are mesh vertices and there is no joint tree. For a rigged garment the **topology** is the answer: a joint whose parent is outside the named set is a joint the garment hangs from, and they all have to hang from the same bone. No weights are read. §25 |
|
|
1398
|
+
| 3 | §11.2's table — "output joints, order of magnitude, skirt: ~60" | For a 64 cm cape driven by a gust, 60 joints leaves a worst-case reconstruction error of about 5% of the garment's own size — five grid cells. RMS error goes as **1/joints** and the worst as **N^−0.83**; getting the worst inside a garment's own thickness needs about a thousand. §28 |
|
|
1399
|
+
|
|
1400
|
+
And one finding that is not a correction but is the thing an author will hit
|
|
1401
|
+
first: **a garment authored inside its own body collider reads as a tether
|
|
1402
|
+
failure.** §29.
|
|
1403
|
+
|
|
1404
|
+
---
|
|
1405
|
+
|
|
1406
|
+
## 25. The two paths are the same solver, and the number is zero
|
|
1407
|
+
|
|
1408
|
+
§11 claims the entity path and the rig path are "the solver, identical either
|
|
1409
|
+
way; only seeding and write-back differ". That is a claim about trajectories and
|
|
1410
|
+
it is checkable: build the same garment twice — five strips of seven links under
|
|
1411
|
+
one anchor, once as an entity subtree and once as the joints of a `Skin` —
|
|
1412
|
+
drive both the same way, and compare the particles in the cloth's own frame.
|
|
1413
|
+
|
|
1414
|
+
```
|
|
1415
|
+
fabric motion worst disagreement as a fraction of the shortest link
|
|
1416
|
+
SILK still 0.00e+0 m 0.00e+0
|
|
1417
|
+
SILK walk 0.00e+0 m 0.00e+0
|
|
1418
|
+
SILK sprint 0.00e+0 m 0.00e+0
|
|
1419
|
+
DENIM still 0.00e+0 m 0.00e+0
|
|
1420
|
+
DENIM walk 0.00e+0 m 0.00e+0
|
|
1421
|
+
DENIM sprint 0.00e+0 m 0.00e+0
|
|
1422
|
+
CHAIN still 0.00e+0 m 0.00e+0
|
|
1423
|
+
CHAIN walk 0.00e+0 m 0.00e+0
|
|
1424
|
+
CHAIN sprint 0.00e+0 m 0.00e+0
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
**Bit-identical**, across three fabrics and three motion profiles, after 600
|
|
1428
|
+
steps. Not "agreeing to rounding" — the same bits.
|
|
1429
|
+
|
|
1430
|
+
That is not luck and it is worth saying why, because it is the shape the code was
|
|
1431
|
+
given to make it true. M3 moved the row builder out of `cloth_seed_subtree.js`
|
|
1432
|
+
into `cloth_build_rows.js`, and the two seeders' *entire* job is to produce a
|
|
1433
|
+
`node_parent` array and an `animated_position` array. Everything after that —
|
|
1434
|
+
geodesics, link rows, strain limits, skip rows, leashes, the colouring, the
|
|
1435
|
+
`ClothState` — is one function called by both. A second copy for the rig path
|
|
1436
|
+
would have made §11's claim true of the solver and false of everything above it,
|
|
1437
|
+
and this table is what that would have cost.
|
|
1438
|
+
|
|
1439
|
+
The write-back is the same story one level up: `cloth_reconstruct_pose.js` turns
|
|
1440
|
+
particles into a pose and stops, and the two writers put that pose onto an
|
|
1441
|
+
entity's `Transform64` + `TransformAttachment` or onto a `Node3D`.
|
|
1442
|
+
|
|
1443
|
+
### Cloth takes the joints, and that is the design rather than a side effect
|
|
1444
|
+
|
|
1445
|
+
§11.2 says the writable handle is `Node3D.transform_local`, "the same handle the
|
|
1446
|
+
animation systems write". They do not. `TransformAuthority`'s own docblock is
|
|
1447
|
+
unambiguous:
|
|
1448
|
+
|
|
1449
|
+
> The GPU owns the TRS — animation clips, effects, anything writing through the
|
|
1450
|
+
> pose accumulator. The CPU allocates and seeds the row, then never writes to it
|
|
1451
|
+
> again, so the node's own `transform_local` stops describing it and should not
|
|
1452
|
+
> be read as if it did.
|
|
1453
|
+
|
|
1454
|
+
And `instantiate_scene_bundle` stamps `TransformAuthority.GPU` on every node a
|
|
1455
|
+
clip channel targets. So a cape joint that an artist keyed — even with a
|
|
1456
|
+
placeholder curve — is a joint whose `transform_local` nothing reads, and cloth
|
|
1457
|
+
writing it would be writing into a field that stopped being the truth.
|
|
1458
|
+
|
|
1459
|
+
`cloth_seed_rig` therefore **claims `TransformAuthority.CPU`** on every joint it
|
|
1460
|
+
drives. The consequence is stated rather than hidden: those joints stop being
|
|
1461
|
+
animatable by a clip, because two writers of one row is the race the enum exists
|
|
1462
|
+
to prevent. For a cape that is the point of simulating it. For a garment whose
|
|
1463
|
+
joints are also keyed it is an authoring error, and the claim is where it
|
|
1464
|
+
surfaces.
|
|
1465
|
+
|
|
1466
|
+
### The anchor's pose is computed, never read back
|
|
1467
|
+
|
|
1468
|
+
A joint of an animated skeleton has no CPU-side `transform_global` — nothing
|
|
1469
|
+
maintains it — so the rig path evaluates the anchor's world pose with
|
|
1470
|
+
`pose_evaluate_world` over the clips the entity is playing. That is the engine's
|
|
1471
|
+
own sanctioned answer to "where is this bone", the one
|
|
1472
|
+
`query_entity_node_world_pose` gives gameplay, and using it means a cape and a
|
|
1473
|
+
scabbard on the same shoulder are placed by the same evaluator off the same
|
|
1474
|
+
clock. M3 lifted `collect_entity_playbacks` out of that query so both callers
|
|
1475
|
+
gather the same playbacks rather than two lists that could disagree.
|
|
1476
|
+
|
|
1477
|
+
---
|
|
1478
|
+
|
|
1479
|
+
## 26. The tether on a fanned garment
|
|
1480
|
+
|
|
1481
|
+
Worst `max(|x − anchor| / d_geo)` over 600 steps, both paths, five strips of
|
|
1482
|
+
seven.
|
|
1483
|
+
|
|
1484
|
+
```
|
|
1485
|
+
fabric motion entity path rig path
|
|
1486
|
+
SILK still 1.0005 1.0005
|
|
1487
|
+
SILK walk 1.0027 1.0027
|
|
1488
|
+
SILK sprint 1.1254 1.1254
|
|
1489
|
+
DENIM still 1.0026 1.0026
|
|
1490
|
+
DENIM walk 1.0019 1.0019
|
|
1491
|
+
DENIM sprint 1.4561 1.4561
|
|
1492
|
+
CHAIN still 1.0002 1.0002
|
|
1493
|
+
CHAIN walk 1.0029 1.0029
|
|
1494
|
+
CHAIN sprint 1.1738 1.1738
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
Resting and walking are inside 0.3%, which is M1's own figure. **Sprinting is
|
|
1498
|
+
not**, and denim reaches 1.46.
|
|
1499
|
+
|
|
1500
|
+
The two columns being identical is the point: this is not the rig path failing,
|
|
1501
|
+
it is §7 P2's conditional bound showing on a shape M1 did not measure. M1's
|
|
1502
|
+
profile drove a **20-link rope of uniform 10 cm links with a 2 m reach**, and a
|
|
1503
|
+
±9 m/s square wave moves the anchor 15 cm a step — 7% of that reach. The garment
|
|
1504
|
+
here has a 0.68 m reach, so the same 15 cm is 22% of it, and it is a *fan*: five
|
|
1505
|
+
strips whose first links are nearly horizontal, so a sideways reversal loads them
|
|
1506
|
+
across rather than along.
|
|
1507
|
+
|
|
1508
|
+
Denim is worst because it is the entry that spends its levers on particles rather
|
|
1509
|
+
than on iterations: 2×2 against silk's 2×4, so half the correction authority for
|
|
1510
|
+
the same displacement. That is the library's own trade, priced.
|
|
1511
|
+
|
|
1512
|
+
The excursion is transient in every case and nothing teleports. What it says is
|
|
1513
|
+
that §7 P2's "no particle is ever further from the anchor than `d_geo`" needs its
|
|
1514
|
+
conditional read as a statement about **the anchor's displacement against the
|
|
1515
|
+
garment's reach**, not only against the shortest row: a short, wide garment on a
|
|
1516
|
+
fast anchor is the case that finds it.
|
|
1517
|
+
|
|
1518
|
+
---
|
|
1519
|
+
|
|
1520
|
+
## 27. What the rig path costs
|
|
1521
|
+
|
|
1522
|
+
The same garment, the same steps, the same fabric, best of three rounds.
|
|
1523
|
+
|
|
1524
|
+
```
|
|
1525
|
+
garment entity path rig path difference
|
|
1526
|
+
5 strips × 7 (35 joints) 0.0988 ms 0.1034 ms +4.6%
|
|
1527
|
+
3 strips × 9 (27 joints) 0.0861 ms 0.0883 ms +2.5%
|
|
1528
|
+
12 strips × 10 (120) 0.3082 ms 0.3183 ms +3.2%
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
Two to five per cent, which is the CPU pose evaluation of the anchor joint plus a
|
|
1532
|
+
`Node3D` write-back in place of a `Transform64` one. The anchor evaluation is a
|
|
1533
|
+
walk up the joint chain per cloth per step and does not scale with the garment,
|
|
1534
|
+
which is why the largest garment shows the smallest relative difference.
|
|
1535
|
+
|
|
1536
|
+
For scale against §17's budget: 120 joints is 0.32 ms, and a garment's joint
|
|
1537
|
+
count is a *proxy* rather than a simulation resolution — the whole point of §11.2's
|
|
1538
|
+
three tiers is that a 5,000-vertex render mesh rides 120 joints. Nothing in the
|
|
1539
|
+
library needs re-sizing.
|
|
1540
|
+
|
|
1541
|
+
---
|
|
1542
|
+
|
|
1543
|
+
## 28. How many joints a drape takes — §18's open question
|
|
1544
|
+
|
|
1545
|
+
§18 carries the unrigged path's joint budget as open, with the mitigation that
|
|
1546
|
+
**M3 measures the fidelity curve before fixing a budget**. The unrigged runtime
|
|
1547
|
+
path is not in M3; this is the experiment that says what it would cost.
|
|
1548
|
+
|
|
1549
|
+
A 33×33 cape at 2 cm — 1,089 particles, 64 cm square, pinned along its top edge
|
|
1550
|
+
and driven by a gust — is simulated at full resolution and is the reference. A
|
|
1551
|
+
`k × k` grid of those particles is nominated as joints; every particle is bound
|
|
1552
|
+
to the four nearest of them in the mesh's own parameter space with
|
|
1553
|
+
inverse-distance weights, which is exactly what a four-weight palette does; and
|
|
1554
|
+
the garment is reconstructed each frame by linear blend skinning from the joints'
|
|
1555
|
+
fitted frames.
|
|
1556
|
+
|
|
1557
|
+
```
|
|
1558
|
+
joints RMS error worst as % of the garment degenerate frames
|
|
1559
|
+
4 6.13e-2 m 1.92e-1 m 29.93% 0
|
|
1560
|
+
9 2.14e-2 m 1.22e-1 m 19.13% 0
|
|
1561
|
+
16 1.19e-2 m 7.51e-2 m 11.73% 0
|
|
1562
|
+
25 8.01e-3 m 6.81e-2 m 10.65% 0
|
|
1563
|
+
36 5.92e-3 m 5.10e-2 m 7.97% 0
|
|
1564
|
+
49 4.44e-3 m 3.97e-2 m 6.21% 0
|
|
1565
|
+
81 2.77e-3 m 2.36e-2 m 3.69% 0
|
|
1566
|
+
121 2.04e-3 m 1.90e-2 m 2.97% 0
|
|
1567
|
+
289 9.35e-4 m 5.60e-3 m 0.88% 0
|
|
1568
|
+
```
|
|
1569
|
+
|
|
1570
|
+
**RMS error is inversely proportional to the joint count** — `RMS × joints` is
|
|
1571
|
+
0.245 at 4 joints and 0.270 at 289, flat across a factor of 72 — and the worst
|
|
1572
|
+
case falls more slowly, as about `N^−0.83`.
|
|
1573
|
+
|
|
1574
|
+
That gives the budget its shape. §11.2's table guesses "~60 output joints" for a
|
|
1575
|
+
skirt; at 60 the worst-case error on this cape is about 5% of its own size, which
|
|
1576
|
+
is five grid cells and reads as faceting. Putting the worst inside **one grid
|
|
1577
|
+
cell** takes about 120 joints; inside the garment's own 4 mm thickness takes
|
|
1578
|
+
about a thousand, which is not a budget, it is the simulation resolution again.
|
|
1579
|
+
|
|
1580
|
+
So the honest statement for a future unrigged path is: **80 to 120 joints for a
|
|
1581
|
+
cape of this size, and the four-weight palette is what sets that** — the error at
|
|
1582
|
+
289 joints is still 0.88%, and it is not the frames that are losing it.
|
|
1583
|
+
|
|
1584
|
+
### The frames did not degenerate, and that is measured rather than argued
|
|
1585
|
+
|
|
1586
|
+
§18's second open risk is that "a fold that collapses a triangle fan has no
|
|
1587
|
+
well-defined frame". The run counts a frame as degenerate when either fitted
|
|
1588
|
+
tangent falls below 1e-4 m. **Across 800 frames × up to 121 joints, in the table
|
|
1589
|
+
above and in a deliberately crumpled variant — bending at 1e-7 and a gust four
|
|
1590
|
+
times as hard — the count is zero:**
|
|
1591
|
+
|
|
1592
|
+
```
|
|
1593
|
+
joints RMS error worst as % of the garment degenerate frames
|
|
1594
|
+
16 3.69e-2 m 1.52e-1 m 23.82% 0
|
|
1595
|
+
36 1.94e-2 m 8.97e-2 m 14.01% 0
|
|
1596
|
+
81 1.05e-2 m 5.12e-2 m 8.00% 0
|
|
1597
|
+
121 8.17e-3 m 4.86e-2 m 7.60% 0
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
The mechanism is worth stating, because it is why it did not happen rather than a
|
|
1601
|
+
promise that it cannot. A tangent is a difference across **two links**, and the
|
|
1602
|
+
stretch rows are hard, so each of those links holds its length; the only way the
|
|
1603
|
+
difference vanishes is a fold of exactly 180° at the joint's own vertex, which is
|
|
1604
|
+
a measure-zero configuration the bend rows are actively pushing away from. It is
|
|
1605
|
+
*possible* — hard rows do not forbid it — and a future unrigged path should keep
|
|
1606
|
+
the epsilon and the fallback rather than delete them on the strength of a zero.
|
|
1607
|
+
|
|
1608
|
+
What the crumpled variant does show is that the error roughly triples: a garment
|
|
1609
|
+
with no bending resistance needs about three times the joints for the same
|
|
1610
|
+
fidelity, which is the other half of the budget question and says that the number
|
|
1611
|
+
is per-fabric rather than per-garment.
|
|
1612
|
+
|
|
1613
|
+
---
|
|
1614
|
+
|
|
1615
|
+
## 29. A garment authored inside its own body reads as a tether failure
|
|
1616
|
+
|
|
1617
|
+
Not a correction, and the first thing an author will hit.
|
|
1618
|
+
|
|
1619
|
+
The M3 playground's first cape was authored 9 cm behind the chest, and the
|
|
1620
|
+
character's torso collider was a capsule of 16 cm radius on the spine — so the
|
|
1621
|
+
garment's first links started **inside the body**. What that looks like is not a
|
|
1622
|
+
garment stuck in a torso. It looks like this:
|
|
1623
|
+
|
|
1624
|
+
```
|
|
1625
|
+
worst |x − anchor| / d_geo, a cape at rest, no motion at all
|
|
1626
|
+
|
|
1627
|
+
with the body colliders 1.3117
|
|
1628
|
+
without them 1.0000
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
The contact row pushes the first links out of the collider, the tether row pulls
|
|
1632
|
+
them back, the contact wins — measured at 363 N of multiplier on a link holding
|
|
1633
|
+
a 0.12 kg strip — and the readout says the tether is failing by 31%. It is not.
|
|
1634
|
+
Both rows are doing exactly what they are for, and the configuration is one
|
|
1635
|
+
neither of them should ever have been given.
|
|
1636
|
+
|
|
1637
|
+
§11.3's step 10 is the answer and it says so: the build validates "that the
|
|
1638
|
+
skinned bind pose is collision-free against the character's `ClothCollider` set",
|
|
1639
|
+
and fails loudly with the offending vertex and collider named. **M3 does not
|
|
1640
|
+
build that check** — `cloth_proxy_from_joints` has a joint tree and no collider
|
|
1641
|
+
set — and this measurement is the argument for it being the next thing the build
|
|
1642
|
+
gains rather than a nicety. Moving the garment 21 cm back and shrinking the torso
|
|
1643
|
+
capsule to 13 cm returns the resting figure to 1.0022.
|
|
1644
|
+
|
|
1645
|
+
---
|
|
1646
|
+
|
|
1647
|
+
# Cloth — M4 measurements
|
|
1648
|
+
|
|
1649
|
+
> Written 2026-09-11, against the M4 implementation in `solver/` and the grid in
|
|
1650
|
+
> `core/geom/3d/hash-grid/`. Everything above this line is M0's, M1's, M2's and
|
|
1651
|
+
> M3's and is unchanged.
|
|
1652
|
+
>
|
|
1653
|
+
> Two scripts, both runnable directly under node — the M0 note applies unchanged:
|
|
1654
|
+
>
|
|
1655
|
+
> ```
|
|
1656
|
+
> node src/engine/physics/cloth/solver/__fixtures__/cloth_m4_measure.mjs
|
|
1657
|
+
> node src/engine/physics/cloth/ecs/__fixtures__/cloth_library_bench.mjs
|
|
1658
|
+
> ```
|
|
1659
|
+
>
|
|
1660
|
+
> The second is M1's, extended here with the section that prices self-collision
|
|
1661
|
+
> against each entry's own size and budget.
|
|
1662
|
+
>
|
|
1663
|
+
> **A folding sheet is chaotic**, and one run of one gust says nothing about a
|
|
1664
|
+
> parameter. Every folding measurement below is the mean over **twelve gust
|
|
1665
|
+
> realisations** — the same sheet, the same everything, twelve phases and rates
|
|
1666
|
+
> of the driving gust. The first version of §32 ran one realisation per row, and
|
|
1667
|
+
> at one the noise was larger than the effect and pointed at a different answer.
|
|
1668
|
+
|
|
1669
|
+
---
|
|
1670
|
+
|
|
1671
|
+
## 30. What M4 proved wrong in PLAN.md
|
|
1672
|
+
|
|
1673
|
+
Four things, and the first is the one the whole tier turns on.
|
|
1674
|
+
|
|
1675
|
+
| # | The design said | The measurement said |
|
|
1676
|
+
|---|---|---|
|
|
1677
|
+
| 0 | §9 — pairs closer than `r_i + r_j` get the unilateral row from §6, whose `r` reads as the same `ClothDynamics#thickness` a collider contact uses | Not at a garment's real proportions. A fabric is 4 to 20 mm thick and a proxy's particles are 2 to 8 cm apart, so the two layers of a fold are almost never within a fabric thickness of each other. At the fabric's own 6 mm the row removes **21%** of a folding sheet's self-intersections; at half the shortest row — a diameter of one particle spacing — it removes **82%**. The radius is a property of *the proxy*, not of the cloth it stands for. §31 |
|
|
1678
|
+
| 1 | §14.2 — a 3D uniform hash grid "modelled on `core/geom/2d/hash-grid/SpatialHashGrid.js`" | The 2D grid is a **persistent, incremental** structure: a bounded array of cells, elements that are AABBs and carry identity, and insert/remove/move as the primitive operations. Cloth's grid is none of those. Its elements are points with no identity across steps, its domain is unbounded, and every particle moves every step — so the operation that matters is *rebuild*, and insert/remove never runs at all. `PointHashGrid3` is a counting sort into a power-of-two hash and shares no structure with the 2D grid. The rebuild is 10% to 12% of the step it sits in front of, and most of everything self-collision costs. §34 |
|
|
1679
|
+
| 2 | §9 — the flag is "set on the library entries that need it (skirts, long coats, hair) and clear on the ones that do not (capes, ponytails, banners)" | That list is drawn along the wrong axis. What decides is not what the garment *is* but how far the fabric bends: the floppier the fabric the more it passes through itself. Silk, hair and cotton tangle 8 to 11 times a sample and the row removes 71% to 81%; leather tangles 0.18 times and the row makes it *worse*. §33 |
|
|
1680
|
+
| 3 | §9 — "Both tiers derive their normals from the proxy's surface orientation, per P4(a)" | M4a's normal is the line between the two particles, because a particle pair has no surface in it. What P4(a) actually asks for — nothing history-dependent, no "which side was this on last frame" to latch onto — the pair normal satisfies completely and more simply: recomputed every iteration from the current positions, with no multiplier, no warm start and no identity across steps. The sentence is right about M4b, where a point-triangle stencil genuinely needs an orientation to choose a side. |
|
|
1681
|
+
|
|
1682
|
+
**And two findings with no line in PLAN.md to correct**, because §9 never wrote a
|
|
1683
|
+
radius down at all. `max(thickness, shortest_row/2)` has an upper end and leather
|
|
1684
|
+
is on it (§36) — and that upper end has to be *measured* rather than reasoned
|
|
1685
|
+
from a sheet's topology, because the geometry M3 ships is not a sheet (§37).
|
|
1686
|
+
|
|
1687
|
+
Two things the implementation **confirmed** rather than corrected, both of them
|
|
1688
|
+
places where an earlier milestone wrote down what M4 would find:
|
|
1689
|
+
|
|
1690
|
+
- **§5.4's Jacobi paragraph.** M2 measured that a *collider* contact is unary
|
|
1691
|
+
and needs none of it, and left the paragraph standing "for M4's rows, which
|
|
1692
|
+
really are pairs". They are, and it does. `cloth_self_row.js` accumulates the
|
|
1693
|
+
pair list into a per-particle `(f, H)` scratch once per iteration and every
|
|
1694
|
+
vertex update adds its own entry, which is what keeps the step independent of
|
|
1695
|
+
the order the colours were swept in.
|
|
1696
|
+
- **§9's "it prevents the great majority of visible interpenetration".** 82% of
|
|
1697
|
+
it, at the radius §31 settles on. The tier's stated limit — cloth passing
|
|
1698
|
+
*between* particles — is real and is what the other 18% is: §35 went looking
|
|
1699
|
+
for a cheaper explanation, a pair search running one step behind the solver,
|
|
1700
|
+
and ruled it out.
|
|
1701
|
+
|
|
1702
|
+
---
|
|
1703
|
+
|
|
1704
|
+
## 31. The radius is the proxy's resolution, not the fabric's thickness
|
|
1705
|
+
|
|
1706
|
+
§6 writes the row as `‖x_i − x_j‖ − (r_i + r_j)` and §9 says the pairs that get
|
|
1707
|
+
one are those "closer than `r_i + r_j`". Both read naturally as the same `r` a
|
|
1708
|
+
collider contact uses, which is `ClothDynamics#thickness` — how thick the fabric
|
|
1709
|
+
is. M4 was built that way and it barely worked: on a folding garment the pair
|
|
1710
|
+
list held **1.6 to 3.7 pairs a step across the whole cloth**, and no stiffness
|
|
1711
|
+
made the sheet stop passing through itself.
|
|
1712
|
+
|
|
1713
|
+
The arithmetic is not subtle once it is written down. A fabric is 4 to 20 mm
|
|
1714
|
+
thick. A proxy's particles are 2 to 8 cm apart. Two layers of a fold are within
|
|
1715
|
+
a *fabric thickness* of each other only when their particles happen to line up,
|
|
1716
|
+
and nothing makes them line up.
|
|
1717
|
+
|
|
1718
|
+
A 12×12 sheet at 2 cm spacing, 6 mm thick, driven into a fold. Only the radius
|
|
1719
|
+
moves; the stiffness, the gust and the mesh are held fixed. "Crossings" counts
|
|
1720
|
+
edges passing through triangles they share no vertex with — §17's own metric —
|
|
1721
|
+
sampled every twentieth step and averaged over twelve gust realisations. The
|
|
1722
|
+
same sheet with no row at all sits at **11.39**.
|
|
1723
|
+
|
|
1724
|
+
```
|
|
1725
|
+
radius diameter pairs/step crossings: mean / worst overlap mean
|
|
1726
|
+
|
|
1727
|
+
3 mm 6 mm 0.5 10.60 / 156 5.2 mm
|
|
1728
|
+
6 mm 12 mm 2.6 9.00 / 190 10.7 mm <- the fabric thickness
|
|
1729
|
+
8 mm 16 mm 3.9 5.33 / 86 14.4 mm
|
|
1730
|
+
10 mm 20 mm 4.8 2.03 / 71 18.4 mm <- half the shortest row
|
|
1731
|
+
12 mm 24 mm 5.5 0.91 / 64 20.1 mm
|
|
1732
|
+
16 mm 32 mm 8.2 0.02 / 5 24.8 mm
|
|
1733
|
+
```
|
|
1734
|
+
|
|
1735
|
+
At the fabric's own thickness the row removes 21% of the crossings. At half the
|
|
1736
|
+
shortest row — a diameter of exactly one particle spacing — it removes 82%. The
|
|
1737
|
+
radius is a property of **the proxy**, and `ClothState#self_radius` is a separate
|
|
1738
|
+
field from `contact_radius` for that reason: a collider contact really is about
|
|
1739
|
+
how thick the cloth is, and this is not.
|
|
1740
|
+
|
|
1741
|
+
`ClothSystem` writes `max(thickness, shortest_row / 2)`, under a ceiling §36 and
|
|
1742
|
+
§37 derive. The `max` is not decoration: a heavy fabric on a coarse proxy — 2 cm
|
|
1743
|
+
of leather on 3 cm particles — is the one case where the fabric is the longer of
|
|
1744
|
+
the two lengths, and there the thickness is right.
|
|
1745
|
+
|
|
1746
|
+
### The column does not turn over, and the reason to stop is not in it
|
|
1747
|
+
|
|
1748
|
+
12 mm is better than 10, and 16 mm — a diameter of 1.6 particle spacings — very
|
|
1749
|
+
nearly eliminates crossings. §36 carries the sweep further and it keeps
|
|
1750
|
+
improving right up to a cliff at two spacings that has nothing to do with
|
|
1751
|
+
crossings at all.
|
|
1752
|
+
|
|
1753
|
+
**So the shipped value is not the minimum of this table, and it would be
|
|
1754
|
+
dishonest to present it as one.** Half the shortest row is a *fidelity* choice:
|
|
1755
|
+
a self-collision radius is the cloth's apparent half-thickness, and at a
|
|
1756
|
+
diameter of 1.6 spacings a silk cape on 8 cm particles would hold the two layers
|
|
1757
|
+
of a fold nearly 13 cm apart. For 4 mm of silk that is absurd, and no crossing
|
|
1758
|
+
count can see it — the metric being optimised cannot measure the thing that
|
|
1759
|
+
stops the optimisation. A diameter of one particle spacing is the largest
|
|
1760
|
+
separation the proxy can be said to *mean*, since it is the mesh's own finest
|
|
1761
|
+
feature, and it delivers §9's "great majority" at 82%.
|
|
1762
|
+
|
|
1763
|
+
What would settle it properly is a number M4 does not have: what the search
|
|
1764
|
+
costs as a function of cell size. §34 shows the search is nearly all of the cost
|
|
1765
|
+
and that it scales with particles, but a wider radius is a wider *cell*, and
|
|
1766
|
+
every walk then visits more candidates. Someone who wants a stricter garment can
|
|
1767
|
+
raise the radius today — the table above is the dial, and the ceiling in §36 is
|
|
1768
|
+
where it stops — but they should measure that first.
|
|
1769
|
+
|
|
1770
|
+
---
|
|
1771
|
+
|
|
1772
|
+
## 32. How stiff the row has to be, and what it is actually for
|
|
1773
|
+
|
|
1774
|
+
Same sheet, same gust, radius fixed at half the shortest row; the penalty moves.
|
|
1775
|
+
`CLOTH_SELF_RATIO` is a multiple of `m_eff/h²` exactly as the bend and leash
|
|
1776
|
+
bands are, and `m_eff` for a pair with two free ends is half a particle.
|
|
1777
|
+
|
|
1778
|
+
```
|
|
1779
|
+
k / (m_eff/h²) overlap: mean / worst crossings: mean / worst / rest pairs kinetic
|
|
1780
|
+
|
|
1781
|
+
0 19.4 / 19.7 mm 11.39 / 146 / 0.0 0.0 6.86e-3
|
|
1782
|
+
1 17.4 / 19.2 mm 3.42 / 51 / 0.0 6.9 6.63e-3
|
|
1783
|
+
2 16.6 / 19.3 mm 3.36 / 76 / 0.0 5.8 5.81e-3
|
|
1784
|
+
4 17.2 / 19.3 mm 2.75 / 83 / 0.0 4.8 6.28e-3
|
|
1785
|
+
8 18.4 / 19.8 mm 2.03 / 71 / 0.0 4.8 7.57e-3
|
|
1786
|
+
16 16.8 / 19.5 mm 2.03 / 96 / 0.0 4.6 7.00e-3
|
|
1787
|
+
32 16.8 / 19.3 mm 2.45 / 123 / 0.0 4.4 5.24e-3
|
|
1788
|
+
64 17.5 / 19.5 mm 3.87 / 125 / 0.0 4.3 6.81e-3
|
|
1789
|
+
```
|
|
1790
|
+
|
|
1791
|
+
Four readings, and the last two are the ones worth keeping.
|
|
1792
|
+
|
|
1793
|
+
**Most of the win is in having a row at all.** 11.39 crossings a sample without
|
|
1794
|
+
one, 3.42 with the softest row in the table. The remaining sweep moves it from
|
|
1795
|
+
3.42 to 2.03 — a third of what the first newton bought.
|
|
1796
|
+
|
|
1797
|
+
**The mean bottoms at 8 to 16 and the worst case gets steadily worse the whole
|
|
1798
|
+
way up.** 51 crossings at the worst realisation with `k = 1`, 125 with `k = 64`.
|
|
1799
|
+
A stiff penalty removes the average tangle and creates a rarer, larger one: it
|
|
1800
|
+
throws a particle hard enough to put the sheet through itself somewhere the row
|
|
1801
|
+
was not looking. `CLOTH_SELF_RATIO` ships at **8**, which is the joint minimum of
|
|
1802
|
+
the mean and is well down the worst-case curve.
|
|
1803
|
+
|
|
1804
|
+
**M0's dissipative band does not bind this row.** M0 measured that a soft row
|
|
1805
|
+
stiffer than about `8·(m/h²)` makes the step add energy rather than lose it, and
|
|
1806
|
+
`cloth_step` originally justified the ratio by that ceiling. The kinetic column
|
|
1807
|
+
says otherwise: across a sixty-four-fold range of stiffness it moves between
|
|
1808
|
+
5.2e-3 and 7.6e-3 with no trend at all. The band was measured on rows that are
|
|
1809
|
+
**on every step** — a bend row, a leash. A self-collision row is one-sided and
|
|
1810
|
+
vanishes the instant it is satisfied, so it does work only while it is
|
|
1811
|
+
compressing and has no standing spring to pump. Eight is the right number here
|
|
1812
|
+
and the band is not the reason; the comment in `cloth_step.js` no longer claims
|
|
1813
|
+
it is.
|
|
1814
|
+
|
|
1815
|
+
**The row never achieves its own separation, and it is not meant to.** The
|
|
1816
|
+
overlap column is `diameter − distance` at the worst governed pair, and it barely
|
|
1817
|
+
moves: 19.4 mm without the row and 16.6 to 18.4 mm with it, out of a 20 mm
|
|
1818
|
+
diameter. Inside a fold the hard stretch rows are holding the sheet's own
|
|
1819
|
+
geometry and a soft penalty cannot outvote them. What it can do is decide *which
|
|
1820
|
+
side* of the fold a particle ends up on, which is what a crossing count measures
|
|
1821
|
+
and what §9 asks the tier for.
|
|
1822
|
+
|
|
1823
|
+
### The settled sheet is clean either way, which is the whole flag question
|
|
1824
|
+
|
|
1825
|
+
The `rest` column is zero in every row of the table, the `k = 0` row included. A
|
|
1826
|
+
sheet with no bending resistance flattens itself once the gust stops and takes
|
|
1827
|
+
its tangles out with it. Every crossing counted above happened while the cloth
|
|
1828
|
+
was *moving*.
|
|
1829
|
+
|
|
1830
|
+
That is not a small caveat, it is the shape of the answer: if tangling were
|
|
1831
|
+
transient for every fabric, the flag would never be worth setting. It is not —
|
|
1832
|
+
what makes a tangle stay is bending. §33.
|
|
1833
|
+
|
|
1834
|
+
---
|
|
1835
|
+
|
|
1836
|
+
## 33. Which entries set the flag, and what it costs them
|
|
1837
|
+
|
|
1838
|
+
§9 says the flag is "set on the library entries that need it (skirts, long
|
|
1839
|
+
coats, hair) and clear on the ones that do not (capes, ponytails, banners)".
|
|
1840
|
+
That list is drawn along what the garment *is*. The measurement is drawn along
|
|
1841
|
+
how far the fabric bends, and it separates the entries far more sharply.
|
|
1842
|
+
|
|
1843
|
+
The same folding sheet, twelve realisations, with each library entry's own
|
|
1844
|
+
`bend` — a ratio of the bend row's inertial scale, mapped the way
|
|
1845
|
+
`cloth_build_rows` maps it — and nothing else changed.
|
|
1846
|
+
|
|
1847
|
+
```
|
|
1848
|
+
entry bend row? crossings: mean / worst pairs removed
|
|
1849
|
+
|
|
1850
|
+
SILK 0.04 none 8.08 / 167 0.0
|
|
1851
|
+
SILK 0.04 with 2.37 / 77 4.5 71%
|
|
1852
|
+
HAIR 0.20 none 10.62 / 139 0.0
|
|
1853
|
+
HAIR 0.20 with 1.98 / 71 4.4 81%
|
|
1854
|
+
COTTON 0.25 none 9.36 / 135 0.0
|
|
1855
|
+
COTTON 0.25 with 1.99 / 49 4.7 79%
|
|
1856
|
+
DENIM 0.62 none 3.59 / 103 0.0
|
|
1857
|
+
DENIM 0.62 with 1.37 / 70 2.2 62%
|
|
1858
|
+
LEATHER 1.00 none 0.18 / 39 0.0
|
|
1859
|
+
LEATHER 1.00 with 0.41 / 44 0.3 -137%
|
|
1860
|
+
```
|
|
1861
|
+
|
|
1862
|
+
**Leather does not tangle, and the row makes it worse.** 0.18 crossings a sample
|
|
1863
|
+
unaided — call it none — and 0.3 pairs a step, which is the row finding almost
|
|
1864
|
+
nothing and pushing on a sheet that had not asked. A fabric at the top of the
|
|
1865
|
+
bend scale will not fold tightly enough to pass through itself; there is nothing
|
|
1866
|
+
for the tier to prevent, and the handful of pairs it does find are noise it is
|
|
1867
|
+
adding rather than removing. The sign of that last column is the whole argument
|
|
1868
|
+
for the flag being off by default.
|
|
1869
|
+
|
|
1870
|
+
**Denim tangles a third as much as cotton** and the row removes 62% of it. It is
|
|
1871
|
+
the one genuinely marginal entry, and it is also the entry that has already spent
|
|
1872
|
+
both of its performance levers (§17): 576 particles at 2×2. It stays clear.
|
|
1873
|
+
|
|
1874
|
+
**Silk, cotton and hair are where the tier earns its keep** — 8 to 11 crossings a
|
|
1875
|
+
sample unaided, 71% to 81% of them gone. Cotton is "the default fabric, and the
|
|
1876
|
+
one every other entry is a deviation from", and a default that shows nine
|
|
1877
|
+
crossings in every sample taken while it moves is a bad default.
|
|
1878
|
+
|
|
1879
|
+
So the flag moves from one entry to three: `CLOTH_SILK` and `CLOTH_COTTON` join
|
|
1880
|
+
`CLOTH_HAIR`. `CLOTH_DENIM`, `CLOTH_LEATHER`, `CLOTH_ROPE` and `CLOTH_CHAIN`
|
|
1881
|
+
stay clear — the first two on the table above, the chains because a chain has no
|
|
1882
|
+
surface to pass through and a coiling rope is a case this measurement does not
|
|
1883
|
+
cover.
|
|
1884
|
+
|
|
1885
|
+
### What that costs
|
|
1886
|
+
|
|
1887
|
+
The solver-level figure first, on the folding sheet, so the shape of the cost is
|
|
1888
|
+
visible before the entries are priced:
|
|
1889
|
+
|
|
1890
|
+
```
|
|
1891
|
+
particles without with delta pairs/step slots full
|
|
1892
|
+
|
|
1893
|
+
144 0.445 ms 0.508 ms 14.3% 2.6 0
|
|
1894
|
+
256 0.813 ms 0.936 ms 15.1% 7.1 0
|
|
1895
|
+
484 1.541 ms 1.806 ms 17.2% 20.6 0
|
|
1896
|
+
1024 3.491 ms 4.100 ms 17.5% 36.0 0
|
|
1897
|
+
```
|
|
1898
|
+
|
|
1899
|
+
Flat at 14% to 18%, and the pair list never once hit its cap — 36 pairs a step
|
|
1900
|
+
across 1,024 particles at the widest, against a ceiling of eight per particle.
|
|
1901
|
+
The cost is not in the pairs; §34 says where it is.
|
|
1902
|
+
|
|
1903
|
+
And then every entry at its own size, its own budget and its own row set, from
|
|
1904
|
+
`cloth_library_bench.mjs` — the same harness M1 sized the library with, driven by
|
|
1905
|
+
a gust so the pair list is doing work:
|
|
1906
|
+
|
|
1907
|
+
```
|
|
1908
|
+
SILK 2x4 1.427 ms -> 1.802 ms 26.3% inside pairs 318.0 full 0
|
|
1909
|
+
COTTON 2x4 1.478 ms -> 1.802 ms 22.0% inside pairs 325.1 full 0
|
|
1910
|
+
DENIM 2x2 1.297 ms -> 1.765 ms 36.1% inside pairs 607.8 full 0
|
|
1911
|
+
LEATHER 2x2 1.315 ms -> 1.828 ms 39.0% inside pairs 740.2 full 0
|
|
1912
|
+
ROPE 2x4 0.116 ms -> 0.129 ms 11.5% inside pairs 0.0 full 0
|
|
1913
|
+
CHAIN 2x6 0.165 ms -> 0.183 ms 11.0% inside pairs 0.0 full 0
|
|
1914
|
+
HAIR 2x4 1.438 ms -> 1.798 ms 25.1% inside pairs 315.7 full 0
|
|
1915
|
+
```
|
|
1916
|
+
|
|
1917
|
+
**Every entry stays inside 2 ms, and the three that set the flag have about a
|
|
1918
|
+
tenth of a frame left.** 1.80 ms against 2.00 for silk, cotton and hair — which
|
|
1919
|
+
is the thinnest headroom in the library and is the thing to watch when M5 or M6
|
|
1920
|
+
adds anything to the step. The bare figures agree with M1's to within 4%
|
|
1921
|
+
(silk 1.427 against a claimed 1.49, denim 1.297 against 1.28), so **no entry is
|
|
1922
|
+
re-sized**: §17's table stands, and self-collision is spent out of headroom
|
|
1923
|
+
rather than out of a lever.
|
|
1924
|
+
|
|
1925
|
+
The delta here — 22% to 26% — is larger than the 14% to 17% above because this
|
|
1926
|
+
harness folds a 400-particle sheet hard enough to find 318 pairs a step against
|
|
1927
|
+
the folding sheet's 5. That is the honest worst case for a garment of this size,
|
|
1928
|
+
and it is the figure the entries were checked against.
|
|
1929
|
+
|
|
1930
|
+
**The chains find nothing**, which is the measurement behind leaving `CLOTH_ROPE`
|
|
1931
|
+
and `CLOTH_CHAIN` clear: 0.0 pairs a step, and the 11% they still pay is the
|
|
1932
|
+
grid being built and walked for a cloth that will never have a pair in it. A
|
|
1933
|
+
hanging chain's nearest ungoverned particles are three links apart and its links
|
|
1934
|
+
are 5 cm long; nothing about a rope brings them within one link of each other
|
|
1935
|
+
except coiling, which this harness does not do.
|
|
1936
|
+
|
|
1937
|
+
**Leather is the entry the §36 clamp is for.** Before it, this same row read
|
|
1938
|
+
1,398 pairs a step — the row had found the mesh rather than a fold. Clamped, its
|
|
1939
|
+
radius comes down from 20 mm to 16 mm and it reads 740, and those are folds. It
|
|
1940
|
+
still does not set the flag.
|
|
1941
|
+
|
|
1942
|
+
(§37 later replaced the ceiling's *derivation* without moving any number here:
|
|
1943
|
+
every entry's radius on this harness is identical under both rules, because on a
|
|
1944
|
+
sheet the closest ungoverned pair is exactly two hops. The bench takes the
|
|
1945
|
+
production path so that stays true rather than being assumed.)
|
|
1946
|
+
|
|
1947
|
+
### The other cost is memory, and four of seven entries pay it for nothing
|
|
1948
|
+
|
|
1949
|
+
`ClothState` is one `ArrayBuffer`, sized at seed, and M4's three regions —
|
|
1950
|
+
`self_pair`, `self_force`, `self_hessian` — are in it whether or not the flag
|
|
1951
|
+
is ever set. On the §17 workload:
|
|
1952
|
+
|
|
1953
|
+
```
|
|
1954
|
+
1,024 particles, 2,945 stretch rows, 2,821 bend rows
|
|
1955
|
+
|
|
1956
|
+
whole state buffer 637,344 bytes
|
|
1957
|
+
self-collision 102,400 bytes 16.1%
|
|
1958
|
+
```
|
|
1959
|
+
|
|
1960
|
+
Four of the seven library entries never read a byte of it. The reason it is
|
|
1961
|
+
unconditional is that the flag can be toggled without a reseed today —
|
|
1962
|
+
`cloth_dynamics_change_needs_reseed` returns false for it, because nothing in
|
|
1963
|
+
the row tables depends on it — so a lazily-sized region would have to become a
|
|
1964
|
+
reseed trigger. That is a change to the reseed contract for 100 KB a garment,
|
|
1965
|
+
and M4 leaves it: **recorded, not fixed**, and the number is here so whoever
|
|
1966
|
+
decides has it.
|
|
1967
|
+
|
|
1968
|
+
---
|
|
1969
|
+
|
|
1970
|
+
## 34. The grid is the cost, and it is not the 2D grid
|
|
1971
|
+
|
|
1972
|
+
§14.2 asks for "a 3D uniform hash grid, modelled on
|
|
1973
|
+
`core/geom/2d/hash-grid/SpatialHashGrid.js`". What landed shares the *idea* and
|
|
1974
|
+
none of the structure, and the reason is worth writing down because the next
|
|
1975
|
+
person to want a broadphase in `core` will read that sentence too.
|
|
1976
|
+
|
|
1977
|
+
The 2D grid is **persistent and incremental**. Its cells are a bounded array
|
|
1978
|
+
sized at construction, its elements are AABBs that carry identity and user data,
|
|
1979
|
+
and its primitives are `element_insert`, `element_remove` and the linked-list
|
|
1980
|
+
surgery that moves one between cells. That is the right shape for a world of
|
|
1981
|
+
things that mostly sit still and occasionally move — which is what it was built
|
|
1982
|
+
for.
|
|
1983
|
+
|
|
1984
|
+
A cloth's particles are the opposite of that in all four respects. They are
|
|
1985
|
+
**points**, not boxes. They carry **no identity across steps** — a pair list is
|
|
1986
|
+
rebuilt from scratch every step precisely because there is nothing on a pair
|
|
1987
|
+
worth keeping (`cloth_self_row.js`). Their domain is **unbounded**: a garment
|
|
1988
|
+
travels with its character and a fixed cell array would have to be re-based every
|
|
1989
|
+
frame. And **every particle moves every step**, so the incremental primitive
|
|
1990
|
+
never gets to be incremental; a full pass of remove-and-reinsert is a rebuild
|
|
1991
|
+
with extra bookkeeping.
|
|
1992
|
+
|
|
1993
|
+
`PointHashGrid3` is therefore a counting sort — count per bucket, prefix-sum,
|
|
1994
|
+
scatter — into a power-of-two hash of the integer cell, and it has no insert, no
|
|
1995
|
+
remove and no element identity at all. Two files, one word in common.
|
|
1996
|
+
|
|
1997
|
+
### The rebuild is most of what self-collision costs
|
|
1998
|
+
|
|
1999
|
+
Which makes it the thing to defend. The same folding sheet, timing the pair
|
|
2000
|
+
search separately from the step it feeds:
|
|
2001
|
+
|
|
2002
|
+
```
|
|
2003
|
+
particles step search rows search as % of the whole
|
|
2004
|
+
|
|
2005
|
+
144 0.442 ms 0.048 ms 0.010 ms 9.6%
|
|
2006
|
+
256 0.806 ms 0.113 ms 0.001 ms 12.3%
|
|
2007
|
+
484 1.615 ms 0.217 ms 0.011 ms 11.8%
|
|
2008
|
+
1024 3.547 ms 0.482 ms 0.164 ms 11.5%
|
|
2009
|
+
```
|
|
2010
|
+
|
|
2011
|
+
`step` is the solver with no pairs at all; `search` is `cloth_self_find`;
|
|
2012
|
+
`rows` is what the pairs then cost inside the solve, taken as the difference
|
|
2013
|
+
between two runs. That last column is a difference of two minima from separate
|
|
2014
|
+
runs and at 484 it comes out *negative*, which is the harness saying the quantity
|
|
2015
|
+
is below its own noise floor rather than saying the rows are free. Read it as
|
|
2016
|
+
"small": between 0.005 and 0.14 ms against a search of 0.05 to 0.50.
|
|
2017
|
+
|
|
2018
|
+
So the **search is most of it and the rows are the remainder** — two thirds to
|
|
2019
|
+
all of it across the four sizes, and the spread is the `rows` column's noise
|
|
2020
|
+
rather than anything about the sizes. And the search scales the way a counting
|
|
2021
|
+
sort does: linear in particles to within the noise, with no term in the pair
|
|
2022
|
+
count at all. §9's "O(n) with a small constant" is right about the shape and
|
|
2023
|
+
optimistic about the constant — half a microsecond a particle, which is 11% of
|
|
2024
|
+
a frame at the §17 workload.
|
|
2025
|
+
|
|
2026
|
+
The consequence for whoever takes M4b — point-triangle and edge-edge — is that
|
|
2027
|
+
the extra stencils are not what will cost; they ride on a grid that has already
|
|
2028
|
+
been built. The estimate in §9 that M4b "roughly triples the self-collision cost"
|
|
2029
|
+
is the thing to re-measure first, and this table is the reason to doubt it.
|
|
2030
|
+
|
|
2031
|
+
---
|
|
2032
|
+
|
|
2033
|
+
## 35. What is left is not the search being one step behind
|
|
2034
|
+
|
|
2035
|
+
`ClothSystem` calls `cloth_self_find` and then `cloth_step`. The pair set is
|
|
2036
|
+
therefore discovered from the positions the *previous* step left, and the row
|
|
2037
|
+
acts on positions `cloth_predict` has already moved. A pair that becomes a
|
|
2038
|
+
contact **during** the step is not in the list, and by the time the next step
|
|
2039
|
+
looks, the two particles have already crossed.
|
|
2040
|
+
|
|
2041
|
+
That is the shape of the gap §20 found in the contact set, where the answer was
|
|
2042
|
+
to widen the discovery reach by the collider's own travel —
|
|
2043
|
+
`cloth_contact_find` carries `CLOTH_CONTACT_MARGIN` and adds `TRAVEL[record]`
|
|
2044
|
+
for it. The self-collision search has no equivalent, and §32 leaves 2.03
|
|
2045
|
+
crossings a sample unaccounted for. The obvious suspicion is that they are the
|
|
2046
|
+
same thing.
|
|
2047
|
+
|
|
2048
|
+
They are not. Here the search runs at a multiple of the row's radius while the
|
|
2049
|
+
row is unchanged, so the extra pairs are found and then found to be out of
|
|
2050
|
+
contact — which is what a travel margin would do:
|
|
2051
|
+
|
|
2052
|
+
```
|
|
2053
|
+
search radius pairs/step crossings: mean / worst slots full
|
|
2054
|
+
|
|
2055
|
+
1.0x 4.8 2.03 / 71 0
|
|
2056
|
+
1.5x 32.3 2.13 / 69 0
|
|
2057
|
+
2.0x 187.8 1.77 / 110 0
|
|
2058
|
+
3.0x 738.9 4.76 / 89 0
|
|
2059
|
+
```
|
|
2060
|
+
|
|
2061
|
+
**The pair list grows a hundred and fifty times over and the crossing count does
|
|
2062
|
+
not move.** 2.03 at the shipped width, 2.13 at one and a half, 1.77 at two —
|
|
2063
|
+
inside the spread of twelve realisations — and then *worse* at three.
|
|
2064
|
+
|
|
2065
|
+
So the residual is not a discovery problem. It is the limit §9 states and does
|
|
2066
|
+
not hide: a particle-particle row can only act when two **particles** are close,
|
|
2067
|
+
and a sheet can pass through itself between them. No width of search reaches
|
|
2068
|
+
that, because the thing that needs a row is a point against a triangle and there
|
|
2069
|
+
is no point-triangle row here. This is M4b's, and M4b is deferred.
|
|
2070
|
+
|
|
2071
|
+
**Why three times over is worse rather than merely wasteful.** The list holds
|
|
2072
|
+
`CLOTH_SELF_PAIRS_PER_PARTICLE` — eight per particle — and a particle at the cap
|
|
2073
|
+
keeps the eight it found *first in grid order*. At the shipped radius every
|
|
2074
|
+
candidate inside it is in contact, so which eight is arbitrary among equals. At
|
|
2075
|
+
three times it, almost none of them are, and the budget goes on pairs that will
|
|
2076
|
+
be discarded a moment later by the distance test while the pairs that mattered
|
|
2077
|
+
never make the list. The cap is what turns a wider search from a cost into a
|
|
2078
|
+
regression, and it is the thing to redesign first if anyone does want a swept
|
|
2079
|
+
search: a second radius with its own budget, or the search moved inside the
|
|
2080
|
+
substep loop after `cloth_predict`.
|
|
2081
|
+
|
|
2082
|
+
---
|
|
2083
|
+
|
|
2084
|
+
## 36. `max(thickness, …)` has an upper end, and leather is over it
|
|
2085
|
+
|
|
2086
|
+
§31 settles the radius at half the shortest row and keeps a `max` against the
|
|
2087
|
+
fabric's thickness, for the case it named: a heavy fabric on a coarse proxy,
|
|
2088
|
+
where the fabric is the longer of the two lengths. Nobody looked at where that
|
|
2089
|
+
branch stops being safe.
|
|
2090
|
+
|
|
2091
|
+
**On this topology the nearest pair no row governs is two hops away.** One hop is
|
|
2092
|
+
a stretch row. The mesh diagonal is a stretch row too. The two vertices *across*
|
|
2093
|
+
a diagonal are the four particles of a bend stencil. Everything closer than two
|
|
2094
|
+
hops is excluded by construction — which is exactly what makes half a hop the
|
|
2095
|
+
right radius, and it also means a **diameter** that reaches two hops puts a flat,
|
|
2096
|
+
undisturbed sheet in contact with itself everywhere.
|
|
2097
|
+
|
|
2098
|
+
The same folding sheet, sweeping the diameter as a multiple of the particle
|
|
2099
|
+
spacing, with pairs counted both while it folds and after it settles:
|
|
2100
|
+
|
|
2101
|
+
```
|
|
2102
|
+
diameter / spacing pairs while folding pairs at rest crossings
|
|
2103
|
+
diameter / spacing pairs while folding pairs at rest crossings
|
|
2104
|
+
|
|
2105
|
+
0.5x 1.8 0.4 10.76
|
|
2106
|
+
0.8x 3.9 0.0 5.33
|
|
2107
|
+
1.0x 4.8 0.0 2.03
|
|
2108
|
+
1.4x 6.1 0.0 0.18
|
|
2109
|
+
1.8x 13.1 0.0 0.04
|
|
2110
|
+
1.9x 22.4 0.0 0.03
|
|
2111
|
+
2.0x 103.7 78.7 0.02
|
|
2112
|
+
2.2x 220.5 218.0 0.00
|
|
2113
|
+
```
|
|
2114
|
+
|
|
2115
|
+
And where the library lands on a 2 cm proxy, under `max(thickness, 10 mm)`:
|
|
2116
|
+
|
|
2117
|
+
```
|
|
2118
|
+
SILK thickness 4 mm -> radius 10 mm = 1.0x spacing
|
|
2119
|
+
HAIR thickness 6 mm -> radius 10 mm = 1.0x spacing
|
|
2120
|
+
COTTON thickness 8 mm -> radius 10 mm = 1.0x spacing
|
|
2121
|
+
DENIM thickness 14 mm -> radius 14 mm = 1.4x spacing
|
|
2122
|
+
LEATHER thickness 20 mm -> radius 20 mm = 2.0x spacing
|
|
2123
|
+
```
|
|
2124
|
+
|
|
2125
|
+
**The cliff is exactly where the topology says, and it is a cliff.** At 1.9
|
|
2126
|
+
spacings a settled sheet has no pairs at all; at 2.0 it has seventy-nine, and at
|
|
2127
|
+
2.2 it has two hundred and eighteen — on a cloth that is hanging still. Nothing
|
|
2128
|
+
about the fold changed. The row simply reached the first pair the mesh had not
|
|
2129
|
+
already claimed, and from there it is in contact with itself everywhere, for
|
|
2130
|
+
ever, pushing a flat sheet apart with a force that has nothing to resolve.
|
|
2131
|
+
|
|
2132
|
+
Note also that the crossing column is *still improving* across the cliff. A
|
|
2133
|
+
measurement that only counted crossings would walk straight over it, which is
|
|
2134
|
+
the argument for the "pairs at rest" column existing.
|
|
2135
|
+
|
|
2136
|
+
**Leather is on the number.** 20 mm of hide on a 20 mm proxy gives the row a
|
|
2137
|
+
diameter of exactly two spacings. Before the clamp, the library bench found it
|
|
2138
|
+
**1,398 pairs a step** on a 576-particle sheet — more than two per particle, on
|
|
2139
|
+
a cloth that was barely folded. Silk found 318 on the same harness.
|
|
2140
|
+
|
|
2141
|
+
The radius is now clamped at both ends, and the ceiling leaves two tenths of a
|
|
2142
|
+
spacing between itself and the cliff — the table says the sheet is clean well
|
|
2143
|
+
before that. **§37 then makes the ceiling a measured length rather than a
|
|
2144
|
+
multiple of the shortest row**, because the two-hop argument above is a fact
|
|
2145
|
+
about *sheets* and a rigged garment is not one. On a sheet the two agree
|
|
2146
|
+
exactly, so nothing in this section moves.
|
|
2147
|
+
|
|
2148
|
+
This is the one M4 finding with no line in PLAN.md to correct: §9 never wrote a
|
|
2149
|
+
radius down at all, which is how the whole question stayed open long enough to
|
|
2150
|
+
be got wrong twice — once too small, once too large.
|
|
2151
|
+
|
|
2152
|
+
---
|
|
2153
|
+
|
|
2154
|
+
## 37. What a rigged garment shows that a sheet cannot
|
|
2155
|
+
|
|
2156
|
+
Everything from §31 to §36 was measured on a triangulated sheet, because a sheet
|
|
2157
|
+
is the only thing in the system with a *surface* to pass through. The
|
|
2158
|
+
playground's cape is not a sheet. It is five strips of seven links, and **nothing
|
|
2159
|
+
joins one strip to the next** — §11.3's proxy is joint indices and a topology,
|
|
2160
|
+
and that topology is a set of chains.
|
|
2161
|
+
|
|
2162
|
+
Two things follow, and the second is a correction.
|
|
2163
|
+
|
|
2164
|
+
### Without the row a cape collapses to half the width it was drawn at
|
|
2165
|
+
|
|
2166
|
+
```
|
|
2167
|
+
the playground's cape — 5 strips of 7, silk, settled from the bind pose
|
|
2168
|
+
|
|
2169
|
+
bind pose 0.340 m wide
|
|
2170
|
+
settled, no self-collision 0.178 m −48%
|
|
2171
|
+
settled, with it 0.351 m +3%
|
|
2172
|
+
```
|
|
2173
|
+
|
|
2174
|
+
Nothing holds the strips apart but this row. Under gravity each one swings
|
|
2175
|
+
inward and they end up occupying the same space, so the cape settles at half the
|
|
2176
|
+
width the artist drew and its strips hang through one another. **This is the
|
|
2177
|
+
first thing in M4 that self-collision visibly does on the geometry M3 actually
|
|
2178
|
+
ships**, and no sheet measurement could have found it: a sheet's neighbouring
|
|
2179
|
+
columns are held apart by the stretch rows between them, and a cape's strips have
|
|
2180
|
+
nothing between them at all.
|
|
2181
|
+
|
|
2182
|
+
It is also the answer to a question §32 left open. There, every tangle was
|
|
2183
|
+
transient — the sheet untied itself whenever the gust stopped, which is why
|
|
2184
|
+
§17's escape hatch still has nothing to escape from. This one is not transient.
|
|
2185
|
+
It is what the garment settles *into*.
|
|
2186
|
+
|
|
2187
|
+
### And the ceiling has to be measured, not derived from the shortest row
|
|
2188
|
+
|
|
2189
|
+
§36 clamps the radius at four fifths of the shortest row, reasoning from a
|
|
2190
|
+
sheet: the nearest pair no row governs is two hops away, so four fifths of one
|
|
2191
|
+
hop leaves a margin. On a sheet that is exactly right —
|
|
2192
|
+
`cloth_self_closest_free_pair` returns 2.0000× the spacing at both 2 cm and
|
|
2193
|
+
5 cm, and the two ceilings agree to the precision Float32 positions carry.
|
|
2194
|
+
|
|
2195
|
+
On the cape they do not agree at all:
|
|
2196
|
+
|
|
2197
|
+
```
|
|
2198
|
+
shortest row — a link, along a strip 0.0801 m
|
|
2199
|
+
two hops, which a sheet would predict 0.1602 m
|
|
2200
|
+
the closest ungoverned pair, measured 0.0850 m
|
|
2201
|
+
```
|
|
2202
|
+
|
|
2203
|
+
The gap *between* strips is half what the link length implies, because it is a
|
|
2204
|
+
different length entirely: the artist put those joints where the garment needed
|
|
2205
|
+
them, and nothing relates that to how finely each strip is subdivided. Derived
|
|
2206
|
+
from the shortest row the ceiling came out at 0.064 m, the 0.040 m floor took
|
|
2207
|
+
precedence, and the settled cape carried **three pairs permanently in contact** —
|
|
2208
|
+
lateral ones, with nothing to do with folding. Measured, the ceiling is 0.034 m
|
|
2209
|
+
and the settled cape carries **none**.
|
|
2210
|
+
|
|
2211
|
+
So `CLOTH_SELF_RADIUS_MAX_RATIO` is two fifths of `ClothInstance#closest_free_pair`
|
|
2212
|
+
rather than four fifths of the shortest row, and `closest_free_pair` is measured
|
|
2213
|
+
once at seed, in the bind pose, by the same grid and the same exclusion set the
|
|
2214
|
+
pair search uses.
|
|
2215
|
+
|
|
2216
|
+
**§31 through §36 are unaffected.** Every one of them was taken on a sheet, where
|
|
2217
|
+
the new rule reproduces the old one to the precision the positions carry, and
|
|
2218
|
+
`cloth_self_radius.spec.js` pins exactly that so it cannot drift.
|
|
2219
|
+
|
|
2220
|
+
### What measuring it costs
|
|
2221
|
+
|
|
2222
|
+
Once per seed, and every cloth pays it whether or not the flag is set, because
|
|
2223
|
+
the flag can be turned on later without a re-seed:
|
|
2224
|
+
|
|
2225
|
+
```
|
|
2226
|
+
1,024 particles, 2,945 stretch rows, 2,821 bend rows
|
|
2227
|
+
|
|
2228
|
+
the exclusion set 1.792 ms
|
|
2229
|
+
the free-pair walk 0.664 ms
|
|
2230
|
+
2.455 ms, once
|
|
2231
|
+
```
|
|
2232
|
+
|
|
2233
|
+
The exclusion set is the larger half and it is not new work — it was built
|
|
2234
|
+
lazily on the first self-collision step before, so a cloth that sets the flag
|
|
2235
|
+
paid it anyway. What is new is that a cloth which never sets the flag now pays
|
|
2236
|
+
it too, at seed, alongside the subtree walk and the graph colouring that seeding
|
|
2237
|
+
already does. Nothing pays it per step.
|
|
2238
|
+
|
|
2239
|
+
---
|