@woosh/meep-engine 3.40.0 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts +24 -0
- package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_clamp.js +62 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts +15 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.js +36 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.d.ts +39 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.js +85 -0
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts +11 -6
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +27 -13
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts +25 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +166 -0
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +5 -3
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +5 -3
- package/src/engine/animation/curve/AnimationCurve.d.ts +3 -0
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +6 -1
- package/src/engine/ecs/EntityManager.d.ts +9 -1
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +26 -27
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +20 -0
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -1
- package/src/engine/ecs/gpu/GPUStateAuthority.js +21 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts +13 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.js +12 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +6 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -1
- package/src/engine/ecs/gpu/gpu_authority_grant.js +7 -1
- package/src/engine/ecs/gpu/gpu_authority_held.d.ts +14 -0
- package/src/engine/ecs/gpu/gpu_authority_held.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_held.js +23 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.d.ts +23 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.js +41 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts +14 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.js +32 -0
- package/src/engine/ecs/ik/IKGoal.d.ts +59 -0
- package/src/engine/ecs/ik/IKGoal.d.ts.map +1 -0
- package/src/engine/ecs/ik/IKGoal.js +83 -0
- package/src/engine/ecs/ik/IKGoalSystem.d.ts +75 -0
- package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -0
- package/src/engine/ecs/ik/IKGoalSystem.js +1456 -0
- package/src/engine/ecs/ik/PLAN.md +179 -0
- package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +4 -5
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +7 -3
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +1 -2
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts +33 -0
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts.map +1 -0
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.js +282 -0
- package/src/engine/ecs/transform/T64WorldCache.js +139 -139
- package/src/engine/ecs/transform/t64_evaluate_local.d.ts +25 -0
- package/src/engine/ecs/transform/t64_evaluate_local.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_evaluate_local.js +35 -0
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts +5 -3
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_evaluate_world.js +128 -126
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +2 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +337 -329
- package/src/engine/graphics3/AnimationSystem.d.ts +2 -0
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +360 -352
- package/src/engine/physics/cloth/MEASUREMENTS.md +130 -0
- package/src/engine/physics/cloth/PLAN.md +16 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +5 -6
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +5 -6
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +4 -7
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +4 -7
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +4 -3
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +4 -3
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +10 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +24 -24
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +46 -43
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +1 -1
- package/src/engine/physics/constraint/solve_constraints.d.ts +0 -35
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +1 -83
- package/src/engine/physics/ecs/ContactProbe.d.ts +73 -0
- package/src/engine/physics/ecs/ContactProbe.d.ts.map +1 -0
- package/src/engine/physics/ecs/ContactProbe.js +103 -0
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts +44 -0
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/ContactProbeSystem.js +397 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +1 -1
- package/src/engine/physics/fluid/ecs/FluidComponent.js +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts +205 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.js +245 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts +21 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.js +63 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts +33 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +874 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts +27 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.js +77 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts +36 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.js +97 -0
- package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts +33 -11
- package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts.map +1 -1
- package/src/engine/physics/inverse_kinematics/two_joint_ik.js +158 -67
- package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.js +10 -1
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +10 -4
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +251 -23
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts +12 -4
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts.map +1 -1
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js +12 -4
- package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts.map +1 -1
- package/src/shade/renderer/animation/chunk_pose_accumulator.js +14 -1
- package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts +78 -0
- package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts.map +1 -0
- package/src/shade/renderer/animation/pose/PoseChannelIndex.js +274 -0
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts +40 -3
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.js +77 -3
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +21 -3
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/pose_evaluate_local.js +79 -11
- package/src/shade/renderer/animation/shader_animation_apply.js +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts +3 -2
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.js +187 -176
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.d.ts +3 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.d.ts.map +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.js +5 -2
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts +4 -0
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts.map +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.js +6 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +135 -73
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +7 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +29 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts +19 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.js +167 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts +25 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.js +124 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts +19 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.js +48 -0
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +17 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +29 -3
- package/src/engine/ecs/ik/IKConstraint.d.ts +0 -52
- package/src/engine/ecs/ik/IKConstraint.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKConstraint.js +0 -95
- package/src/engine/ecs/ik/IKProblem.d.ts +0 -45
- package/src/engine/ecs/ik/IKProblem.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKProblem.js +0 -58
- package/src/engine/ecs/ik/IKSolver.d.ts +0 -8
- package/src/engine/ecs/ik/IKSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKSolver.js +0 -9
- package/src/engine/ecs/ik/InverseKinematics.d.ts +0 -48
- package/src/engine/ecs/ik/InverseKinematics.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematics.js +0 -119
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts +0 -19
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.js +0 -72
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +0 -54
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +0 -212
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts +0 -8
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +0 -153
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts +0 -5
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +0 -120
- package/src/engine/ecs/ik/ik_bone_chain.d.ts +0 -64
- package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_bone_chain.js +0 -142
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +0 -42
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_probe_terrain_contact.js +0 -123
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +0 -18
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +0 -32
|
@@ -1,176 +1,187 @@
|
|
|
1
|
-
import { atomic_u32, u32 } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
-
import { WebGPUArray } from "../shader/type/WebGPUArray.js";
|
|
3
|
-
import { chunk_scene_database_access_rw } from "../scene/chunk_scene_database_access.js";
|
|
4
|
-
import { SCENE_DATABASE_SPEC } from "../scene/SCENE_DATABASE_SPEC.js";
|
|
5
|
-
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
6
|
-
import { ComputeShader } from "../shader/ComputeShader.js";
|
|
7
|
-
import { ShaderResourceSetDescriptor } from "../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
|
-
import { chunk_pose_accumulator } from "./chunk_pose_accumulator.js";
|
|
9
|
-
|
|
10
|
-
const TRANSFORMS_TABLE = SCENE_DATABASE_SPEC.get('transforms');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Workgroup size for the resolve pass. Exported so dispatchers can pair
|
|
14
|
-
* it with `transforms.dispatch_group_count(WORKGROUP_SIZE)`.
|
|
15
|
-
*/
|
|
16
|
-
export const WORKGROUP_SIZE = 64;
|
|
17
|
-
|
|
18
|
-
const PG_PREFIX = TRANSFORMS_TABLE.page_iterator_symbol_prefix(WORKGROUP_SIZE, true);
|
|
19
|
-
|
|
20
|
-
const resources = new ShaderResourceSetDescriptor();
|
|
21
|
-
resources.createGroup()
|
|
22
|
-
.addStorageBuffer('scene_database', WebGPUArray.from(u32), true)
|
|
23
|
-
.addStorageBuffer('pose_accumulator', WebGPUArray.from(atomic_u32), true);
|
|
24
|
-
|
|
25
|
-
const body = CodeChunk.from(
|
|
26
|
-
//language=WGSL
|
|
27
|
-
`
|
|
28
|
-
@compute @workgroup_size(${WORKGROUP_SIZE},1,1)
|
|
29
|
-
fn main(
|
|
30
|
-
@builtin(workgroup_id) wg_id: vec3<u32>,
|
|
31
|
-
@builtin(local_invocation_index) local_id: u32,
|
|
32
|
-
) {
|
|
33
|
-
if !${PG_PREFIX}_setup(&scene_database, wg_id.x, local_id) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let slot_in_page = ${PG_PREFIX}_slot_in_page(local_id);
|
|
38
|
-
|
|
39
|
-
if slot_in_page >= ${PG_PREFIX}_ELEMENTS_PER_PAGE {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
if !${PG_PREFIX}_is_occupied(slot_in_page) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Absolute transforms-table row index. The accumulator is laid out
|
|
47
|
-
// one slot per row at the same index, so this is also the
|
|
48
|
-
// accumulator slot.
|
|
49
|
-
let row = ${PG_PREFIX}_slot_to_index(slot_in_page);
|
|
50
|
-
|
|
51
|
-
let slot_base = pose_accumulator_slot_base(row);
|
|
52
|
-
let dirty_word = slot_base + POSE_OFFSET_DIRTY;
|
|
53
|
-
|
|
54
|
-
// Single load of the dirty mask gates the whole resolve. If
|
|
55
|
-
// nothing was contributed to this row this frame, leave local_*
|
|
56
|
-
// alone (and the accumulator slot is already zero because the
|
|
57
|
-
// previous resolve drained it).
|
|
58
|
-
let dirty = atomicLoad(&pose_accumulator[dirty_word]);
|
|
59
|
-
if dirty == 0u {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ── Translation ───────────────────────────────────────────────
|
|
64
|
-
if (dirty & POSE_DIRTY_T_MASK) != 0u {
|
|
65
|
-
let t_base = slot_base + POSE_OFFSET_TRANSLATION;
|
|
66
|
-
// Per-axis: only overwrite the channels that actually had a
|
|
67
|
-
// contribution. Read the current local_translation through
|
|
68
|
-
// the rw helper and patch the dirty channels in-place — the
|
|
69
|
-
// sibling-axis race that the old direct writer already
|
|
70
|
-
// tolerated still applies (two threads writing different
|
|
71
|
-
// axes of the same node), but we now have at most one resolve
|
|
72
|
-
// thread per row, so it never triggers here.
|
|
73
|
-
var t = scene_read_node_rw(&scene_database, row).local_translation;
|
|
74
|
-
if (dirty & POSE_DIRTY_TX) != 0u {
|
|
75
|
-
t.x = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 0u]));
|
|
76
|
-
atomicStore(&pose_accumulator[t_base + 0u], 0u);
|
|
77
|
-
}
|
|
78
|
-
if (dirty & POSE_DIRTY_TY) != 0u {
|
|
79
|
-
t.y = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 1u]));
|
|
80
|
-
atomicStore(&pose_accumulator[t_base + 1u], 0u);
|
|
81
|
-
}
|
|
82
|
-
if (dirty & POSE_DIRTY_TZ) != 0u {
|
|
83
|
-
t.z = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 2u]));
|
|
84
|
-
atomicStore(&pose_accumulator[t_base + 2u], 0u);
|
|
85
|
-
}
|
|
86
|
-
scene_write_node_local_translation(&scene_database, row, t);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ── Rotation ──────────────────────────────────────────────────
|
|
90
|
-
if (dirty & POSE_DIRTY_R) != 0u {
|
|
91
|
-
let r_base = slot_base + POSE_OFFSET_ROTATION;
|
|
92
|
-
let r = vec4<f32>(
|
|
93
|
-
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 0u])),
|
|
94
|
-
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 1u])),
|
|
95
|
-
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 2u])),
|
|
96
|
-
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 3u])),
|
|
97
|
-
);
|
|
98
|
-
atomicStore(&pose_accumulator[r_base + 0u], 0u);
|
|
99
|
-
atomicStore(&pose_accumulator[r_base + 1u], 0u);
|
|
100
|
-
atomicStore(&pose_accumulator[r_base + 2u], 0u);
|
|
101
|
-
atomicStore(&pose_accumulator[r_base + 3u], 0u);
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
*
|
|
165
|
-
* `
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
1
|
+
import { atomic_u32, u32 } from "../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
2
|
+
import { WebGPUArray } from "../shader/type/WebGPUArray.js";
|
|
3
|
+
import { chunk_scene_database_access_rw } from "../scene/chunk_scene_database_access.js";
|
|
4
|
+
import { SCENE_DATABASE_SPEC } from "../scene/SCENE_DATABASE_SPEC.js";
|
|
5
|
+
import { CodeChunk } from "../shader/compiler/CodeChunk.js";
|
|
6
|
+
import { ComputeShader } from "../shader/ComputeShader.js";
|
|
7
|
+
import { ShaderResourceSetDescriptor } from "../shader/resource/ShaderResourceSetDescriptor.js";
|
|
8
|
+
import { chunk_pose_accumulator } from "./chunk_pose_accumulator.js";
|
|
9
|
+
|
|
10
|
+
const TRANSFORMS_TABLE = SCENE_DATABASE_SPEC.get('transforms');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Workgroup size for the resolve pass. Exported so dispatchers can pair
|
|
14
|
+
* it with `transforms.dispatch_group_count(WORKGROUP_SIZE)`.
|
|
15
|
+
*/
|
|
16
|
+
export const WORKGROUP_SIZE = 64;
|
|
17
|
+
|
|
18
|
+
const PG_PREFIX = TRANSFORMS_TABLE.page_iterator_symbol_prefix(WORKGROUP_SIZE, true);
|
|
19
|
+
|
|
20
|
+
const resources = new ShaderResourceSetDescriptor();
|
|
21
|
+
resources.createGroup()
|
|
22
|
+
.addStorageBuffer('scene_database', WebGPUArray.from(u32), true)
|
|
23
|
+
.addStorageBuffer('pose_accumulator', WebGPUArray.from(atomic_u32), true);
|
|
24
|
+
|
|
25
|
+
const body = CodeChunk.from(
|
|
26
|
+
//language=WGSL
|
|
27
|
+
`
|
|
28
|
+
@compute @workgroup_size(${WORKGROUP_SIZE},1,1)
|
|
29
|
+
fn main(
|
|
30
|
+
@builtin(workgroup_id) wg_id: vec3<u32>,
|
|
31
|
+
@builtin(local_invocation_index) local_id: u32,
|
|
32
|
+
) {
|
|
33
|
+
if !${PG_PREFIX}_setup(&scene_database, wg_id.x, local_id) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let slot_in_page = ${PG_PREFIX}_slot_in_page(local_id);
|
|
38
|
+
|
|
39
|
+
if slot_in_page >= ${PG_PREFIX}_ELEMENTS_PER_PAGE {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if !${PG_PREFIX}_is_occupied(slot_in_page) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Absolute transforms-table row index. The accumulator is laid out
|
|
47
|
+
// one slot per row at the same index, so this is also the
|
|
48
|
+
// accumulator slot.
|
|
49
|
+
let row = ${PG_PREFIX}_slot_to_index(slot_in_page);
|
|
50
|
+
|
|
51
|
+
let slot_base = pose_accumulator_slot_base(row);
|
|
52
|
+
let dirty_word = slot_base + POSE_OFFSET_DIRTY;
|
|
53
|
+
|
|
54
|
+
// Single load of the dirty mask gates the whole resolve. If
|
|
55
|
+
// nothing was contributed to this row this frame, leave local_*
|
|
56
|
+
// alone (and the accumulator slot is already zero because the
|
|
57
|
+
// previous resolve drained it).
|
|
58
|
+
let dirty = atomicLoad(&pose_accumulator[dirty_word]);
|
|
59
|
+
if dirty == 0u {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── Translation ───────────────────────────────────────────────
|
|
64
|
+
if (dirty & POSE_DIRTY_T_MASK) != 0u {
|
|
65
|
+
let t_base = slot_base + POSE_OFFSET_TRANSLATION;
|
|
66
|
+
// Per-axis: only overwrite the channels that actually had a
|
|
67
|
+
// contribution. Read the current local_translation through
|
|
68
|
+
// the rw helper and patch the dirty channels in-place — the
|
|
69
|
+
// sibling-axis race that the old direct writer already
|
|
70
|
+
// tolerated still applies (two threads writing different
|
|
71
|
+
// axes of the same node), but we now have at most one resolve
|
|
72
|
+
// thread per row, so it never triggers here.
|
|
73
|
+
var t = scene_read_node_rw(&scene_database, row).local_translation;
|
|
74
|
+
if (dirty & POSE_DIRTY_TX) != 0u {
|
|
75
|
+
t.x = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 0u]));
|
|
76
|
+
atomicStore(&pose_accumulator[t_base + 0u], 0u);
|
|
77
|
+
}
|
|
78
|
+
if (dirty & POSE_DIRTY_TY) != 0u {
|
|
79
|
+
t.y = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 1u]));
|
|
80
|
+
atomicStore(&pose_accumulator[t_base + 1u], 0u);
|
|
81
|
+
}
|
|
82
|
+
if (dirty & POSE_DIRTY_TZ) != 0u {
|
|
83
|
+
t.z = bitcast<f32>(atomicLoad(&pose_accumulator[t_base + 2u]));
|
|
84
|
+
atomicStore(&pose_accumulator[t_base + 2u], 0u);
|
|
85
|
+
}
|
|
86
|
+
scene_write_node_local_translation(&scene_database, row, t);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Rotation ──────────────────────────────────────────────────
|
|
90
|
+
if (dirty & POSE_DIRTY_R) != 0u {
|
|
91
|
+
let r_base = slot_base + POSE_OFFSET_ROTATION;
|
|
92
|
+
let r = vec4<f32>(
|
|
93
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 0u])),
|
|
94
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 1u])),
|
|
95
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 2u])),
|
|
96
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[r_base + 3u])),
|
|
97
|
+
);
|
|
98
|
+
atomicStore(&pose_accumulator[r_base + 0u], 0u);
|
|
99
|
+
atomicStore(&pose_accumulator[r_base + 1u], 0u);
|
|
100
|
+
atomicStore(&pose_accumulator[r_base + 2u], 0u);
|
|
101
|
+
atomicStore(&pose_accumulator[r_base + 3u], 0u);
|
|
102
|
+
// The weighted-quaternion sum (\`w_i * q_i\`) is the standard
|
|
103
|
+
// nlerp blend numerator; normalise here, once, after every
|
|
104
|
+
// contributor has been folded in. The apply pass canonicalised
|
|
105
|
+
// signs at GLTF load so we don't hit the antipode case for
|
|
106
|
+
// imported clips.
|
|
107
|
+
//
|
|
108
|
+
// A sum of length zero carries no orientation to recover: every
|
|
109
|
+
// clip that writes this rotation is playing at weight zero — a
|
|
110
|
+
// faded-out clip keeps its binding, and the apply pass
|
|
111
|
+
// contributes to a bound clip whatever its weight — or the
|
|
112
|
+
// contributions cancelled exactly. \`normalize\` answers NaN there,
|
|
113
|
+
// and one NaN local rotation reaches every skin matrix naming the
|
|
114
|
+
// joint, so the meshes it drives stop rasterising altogether. Nor
|
|
115
|
+
// can the row be left alone: once a clip has written it, it holds
|
|
116
|
+
// that clip's last pose, not the rest. The answer is the rest
|
|
117
|
+
// rotation, which every contribution carried into the slot from
|
|
118
|
+
// its binding — what the CPU twin (\`pose_evaluate_local\`) gives.
|
|
119
|
+
if length(r) > 0.0 {
|
|
120
|
+
scene_write_node_local_rotation(&scene_database, row, normalize(r));
|
|
121
|
+
} else {
|
|
122
|
+
let rest_base = slot_base + POSE_OFFSET_REST_ROTATION;
|
|
123
|
+
let rest = vec4<f32>(
|
|
124
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[rest_base + 0u])),
|
|
125
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[rest_base + 1u])),
|
|
126
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[rest_base + 2u])),
|
|
127
|
+
bitcast<f32>(atomicLoad(&pose_accumulator[rest_base + 3u])),
|
|
128
|
+
);
|
|
129
|
+
scene_write_node_local_rotation(&scene_database, row, rest);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ── Scale ─────────────────────────────────────────────────────
|
|
134
|
+
if (dirty & POSE_DIRTY_S_MASK) != 0u {
|
|
135
|
+
let s_base = slot_base + POSE_OFFSET_SCALE;
|
|
136
|
+
var s = scene_read_node_rw(&scene_database, row).local_scale;
|
|
137
|
+
if (dirty & POSE_DIRTY_SX) != 0u {
|
|
138
|
+
s.x = bitcast<f32>(atomicLoad(&pose_accumulator[s_base + 0u]));
|
|
139
|
+
atomicStore(&pose_accumulator[s_base + 0u], 0u);
|
|
140
|
+
}
|
|
141
|
+
if (dirty & POSE_DIRTY_SY) != 0u {
|
|
142
|
+
s.y = bitcast<f32>(atomicLoad(&pose_accumulator[s_base + 1u]));
|
|
143
|
+
atomicStore(&pose_accumulator[s_base + 1u], 0u);
|
|
144
|
+
}
|
|
145
|
+
if (dirty & POSE_DIRTY_SZ) != 0u {
|
|
146
|
+
s.z = bitcast<f32>(atomicLoad(&pose_accumulator[s_base + 2u]));
|
|
147
|
+
atomicStore(&pose_accumulator[s_base + 2u], 0u);
|
|
148
|
+
}
|
|
149
|
+
scene_write_node_local_scale(&scene_database, row, s);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Clear the dirty mask itself last, so an interrupted resolve
|
|
153
|
+
// (theoretical — these passes don't yield) would still leave the
|
|
154
|
+
// dirty bits intact to be redone.
|
|
155
|
+
atomicStore(&pose_accumulator[dirty_word], 0u);
|
|
156
|
+
}
|
|
157
|
+
`, [
|
|
158
|
+
TRANSFORMS_TABLE.chunk_iterate(WORKGROUP_SIZE, true),
|
|
159
|
+
chunk_scene_database_access_rw,
|
|
160
|
+
chunk_pose_accumulator,
|
|
161
|
+
]);
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Compute shader that drains the pose accumulator into
|
|
165
|
+
* `transforms_table.local_{translation,rotation,scale}`.
|
|
166
|
+
*
|
|
167
|
+
* Walks the transforms table via the read+write page iterator — one
|
|
168
|
+
* thread per slot. For each occupied row whose accumulator slot has
|
|
169
|
+
* any dirty bits set, reads the contributed components (atomic
|
|
170
|
+
* loads, bitcast back to f32), writes them through the per-field
|
|
171
|
+
* scene helpers, normalises rotation — or, for a rotation summing to
|
|
172
|
+
* nothing, writes the rest rotation the contributions carried — and
|
|
173
|
+
* zeros the sums and the dirty mask for next frame.
|
|
174
|
+
*
|
|
175
|
+
* The accumulator buffer must be sized to at least
|
|
176
|
+
* `transforms.dispatch_page_count * elements_per_page` rows —
|
|
177
|
+
* {@link GPUAnimationManager#ensure_pose_accumulator_capacity}
|
|
178
|
+
* handles that.
|
|
179
|
+
*
|
|
180
|
+
* Dispatch via
|
|
181
|
+
* `shader_animation_pose_resolve.dispatch({ group_count_x: transforms.dispatch_group_count(WORKGROUP_SIZE), ... })`.
|
|
182
|
+
*/
|
|
183
|
+
export const shader_animation_pose_resolve = ComputeShader.from({
|
|
184
|
+
label: "Animation/PoseResolve",
|
|
185
|
+
body,
|
|
186
|
+
resources,
|
|
187
|
+
});
|
|
@@ -13,7 +13,7 @@ export class TinyGltf {
|
|
|
13
13
|
* @readonly
|
|
14
14
|
* @type {TextureFormat}
|
|
15
15
|
*/
|
|
16
|
-
static readonly "__#
|
|
16
|
+
static readonly "__#261@#UNCOMPRESSED_TARGET": TextureFormat;
|
|
17
17
|
/**
|
|
18
18
|
* @param {AssetManager} assetManager
|
|
19
19
|
* @param {AssetRequestScope} [scope]
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
* `weight` is the weight `value` has already been multiplied by. Only the
|
|
13
13
|
* Node3D writer wants it, and only for rotation: a rotation channel missing
|
|
14
14
|
* its `w` curve defaults to the identity's 1, which has to be weighted the
|
|
15
|
-
* same way the authored channels were.
|
|
15
|
+
* same way the authored channels were. `rest_rotation` is the target's
|
|
16
|
+
* rest rotation from its binding, and the same goes for it: only a Node3D
|
|
17
|
+
* rotation reads it.
|
|
16
18
|
*
|
|
17
19
|
* Each writer lives in its own CodeChunk and operates on whatever storage
|
|
18
20
|
* buffers the importing shader has bound under the documented names —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_write_object_property.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/object_property/chunk_write_object_property.js"],"names":[],"mappings":"AASA
|
|
1
|
+
{"version":3,"file":"chunk_write_object_property.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/object_property/chunk_write_object_property.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,0CAFU,SAAS,CA4Bb;0BA7DoB,iCAAiC"}
|
|
@@ -21,7 +21,9 @@ import { ObjectType } from "./ObjectType.js";
|
|
|
21
21
|
* `weight` is the weight `value` has already been multiplied by. Only the
|
|
22
22
|
* Node3D writer wants it, and only for rotation: a rotation channel missing
|
|
23
23
|
* its `w` curve defaults to the identity's 1, which has to be weighted the
|
|
24
|
-
* same way the authored channels were.
|
|
24
|
+
* same way the authored channels were. `rest_rotation` is the target's
|
|
25
|
+
* rest rotation from its binding, and the same goes for it: only a Node3D
|
|
26
|
+
* rotation reads it.
|
|
25
27
|
*
|
|
26
28
|
* Each writer lives in its own CodeChunk and operates on whatever storage
|
|
27
29
|
* buffers the importing shader has bound under the documented names —
|
|
@@ -40,12 +42,13 @@ fn write_object_property(
|
|
|
40
42
|
mask: u32,
|
|
41
43
|
value: vec4f,
|
|
42
44
|
weight: f32,
|
|
45
|
+
rest_rotation: vec4f,
|
|
43
46
|
) {
|
|
44
47
|
let object_type = instance >> 24u;
|
|
45
48
|
|
|
46
49
|
switch(object_type){
|
|
47
50
|
case ${ObjectType.Node3D}u: {
|
|
48
|
-
write_object_property_node3d(instance, property, mask, value, weight);
|
|
51
|
+
write_object_property_node3d(instance, property, mask, value, weight, rest_rotation);
|
|
49
52
|
}
|
|
50
53
|
case ${ObjectType.Material}u: {
|
|
51
54
|
write_object_property_material(instance, property, mask, value);
|
|
@@ -35,6 +35,10 @@
|
|
|
35
35
|
* channel has to carry the same weight as the channels that were
|
|
36
36
|
* authored; nothing else here does.
|
|
37
37
|
*
|
|
38
|
+
* `rest_rotation` is the target's rest rotation, from its binding. Only
|
|
39
|
+
* Rotation reads it: it rides into the slot with the contribution, for
|
|
40
|
+
* the resolve to write when the rotations summed to nothing.
|
|
41
|
+
*
|
|
38
42
|
* @type {CodeChunk}
|
|
39
43
|
*/
|
|
40
44
|
export const chunk_write_object_property_node3d: CodeChunk;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk_write_object_property_node3d.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/object_property/chunk_write_object_property_node3d.js"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"chunk_write_object_property_node3d.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/object_property/chunk_write_object_property_node3d.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,iDAFU,SAAS,CA8Bb;0BA1EoB,iCAAiC"}
|
|
@@ -39,6 +39,10 @@ import { Node3DProperty } from "./Node3DProperty.js";
|
|
|
39
39
|
* channel has to carry the same weight as the channels that were
|
|
40
40
|
* authored; nothing else here does.
|
|
41
41
|
*
|
|
42
|
+
* `rest_rotation` is the target's rest rotation, from its binding. Only
|
|
43
|
+
* Rotation reads it: it rides into the slot with the contribution, for
|
|
44
|
+
* the resolve to write when the rotations summed to nothing.
|
|
45
|
+
*
|
|
42
46
|
* @type {CodeChunk}
|
|
43
47
|
*/
|
|
44
48
|
export const chunk_write_object_property_node3d = CodeChunk.from(
|
|
@@ -50,6 +54,7 @@ fn write_object_property_node3d(
|
|
|
50
54
|
mask: u32,
|
|
51
55
|
value: vec4f,
|
|
52
56
|
weight: f32,
|
|
57
|
+
rest_rotation: vec4f,
|
|
53
58
|
) {
|
|
54
59
|
let node_index = instance & 0x00FFFFFFu;
|
|
55
60
|
|
|
@@ -58,7 +63,7 @@ fn write_object_property_node3d(
|
|
|
58
63
|
pose_accumulator_add_translation(node_index, value.xyz, mask);
|
|
59
64
|
}
|
|
60
65
|
case ${Node3DProperty.Rotation}u: {
|
|
61
|
-
pose_accumulator_add_rotation(node_index, value, mask, weight);
|
|
66
|
+
pose_accumulator_add_rotation(node_index, value, mask, weight, rest_rotation);
|
|
62
67
|
}
|
|
63
68
|
case ${Node3DProperty.Scale}u: {
|
|
64
69
|
pose_accumulator_add_scale(node_index, value.xyz, mask);
|
|
@@ -53,7 +53,7 @@ export class NSS {
|
|
|
53
53
|
* @returns {number}
|
|
54
54
|
*/
|
|
55
55
|
static recommended_jitter_sequence_size(upscale_ratio: number): number;
|
|
56
|
-
static "__#
|
|
56
|
+
static "__#192@#preprocess_tensor_descriptor"(render_w: any, render_h: any): TextureResourceDescriptor;
|
|
57
57
|
/**
|
|
58
58
|
* @param {GraphicsContext} graphics
|
|
59
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry_deduplicate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"geometry_deduplicate.d.ts","sourceRoot":"","sources":["../../../../../../../src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js"],"names":[],"mappings":"AAyDA;;;;;;;;;;GAUG;AACH,qGAHW,0BAA0B,GACxB,cAAc,CAAC,WAAW,WAAW,EAAE,CAAC,CA4LpD;;;;;gBAoJa,MAAM;gBACN,MAAM;gBACN,MAAM;;;;YACN,MAAM;;;gBAlYN,UAAU;;;;qBACV,MAAM;;;;;;;;uBACN,MAAM;;;;kBAKN,MAAM;;4BAtBQ,oDAAoD"}
|