1// Shared declarations, prepended to every kernel.
3struct Params {
4 nx: u32,
5 ny: u32,
6 n: u32,
7 histLen: u32,
8 hx: f32,
9 hy: f32,
10 dt: f32,
11 nu: f32,
12 D: f32, // bending stiffness [N m]
13 C: f32, // E h / (1 - nu^2) [N/m]
14 G: f32, // E h / (2 (1 + nu)) [N/m]
15 rhoh: f32, // mass per unit area [kg/m^2]
16 pushX: f32, // center of the pushed patch [m]
17 pushY: f32,
18 pushR2: f32, // squared patch radius [m^2]
19 mass: f32, // total mass [kg]
20 Ix: f32, // sum m y^2
21 Iy: f32, // sum m x^2
22 Iz: f32, // sum m (x^2 + y^2)
23 fs: f32, // audio sample rate [Hz]
24 strikeX: f32, // drumstick contact point [m]
25 strikeY: f32,
26 strikeR2: f32, // squared contact radius [m^2]
27 patchMass: f32, // mass of the contact patch [kg]
28 strikeNode: u32, // sheet node nearest the contact point
29 K: f32, // Hertz contact stiffness [N/m^alpha]
30 alpha: f32, // Hertz exponent
31 stickMass: f32, // [kg]
32 patchI0: u32, // index box enclosing the contact patch (inclusive)
33 patchI1: u32,
34 patchJ0: u32,
35 patchJ1: u32,
36 patchCX: f32, // mass-weighted center of the contact patch [m]
37 patchCY: f32,
38 inPlaneMass: f32, // factor by which the in-plane inertia is scaled (1: physical)
39 invInPlaneMass: f32, // its reciprocal
40};
42// Per-step parameters, addressed with a dynamic uniform offset.
43struct StepParams {
44 step: u32,
45 flags: u32, // bit 0: push constraint active; bit 1: record its reaction; bit 2: apply the recorded reaction; bit 3: drumstick active; bit 4: re-arm the stick
46 audioSlot: i32, // ring-buffer slot to record the velocity into (-1: none)
47 audioOut: i32, // index of this sample within the batch's output
48 pushW: f32, // prescribed patch displacement [m]
49 pushV: f32, // prescribed patch velocity [m/s]
50 sigma0: f32,
51 sigma1: f32,
52 releaseGain: f32, // fraction of the recorded reaction still applied while the finger lets go
53 sigmaIn: f32, // additional frequency-independent loss of the in-plane motion
54 parity: u32, // which of the two stick-state slots holds the current state
55 strikeV: f32, // stick speed of a re-armed hit [m/s] (bit 4)
56};
58fn nodeX(i: i32) -> f32 { return (f32(i) - 0.5 * f32(P.nx - 1u)) * P.hx; }
59fn nodeY(j: i32) -> f32 { return (f32(j) - 0.5 * f32(P.ny - 1u)) * P.hy; }
61// Quadrature and lumped-mass weight of every node: the fraction of its four
62// cells that belong to the sheet (trapezoidal weights on a full rectangle),
63// zero for nodes outside the sheet. Written once by the host.
64@group(0) @binding(9) var<storage, read> nw: array<f32>;
65fn nodeWeight(i: i32, j: i32) -> f32 {
66 if (i < 0 || i >= i32(P.nx) || j < 0 || j >= i32(P.ny)) { return 0.0; }
67 return nw[u32(j) * P.nx + u32(i)];
68}