dynamis-soft 0.7.0

Soft body and fluid particle simulation
Documentation
@group(0) @binding(0) var<uniform> params: StepParams;
@group(0) @binding(1) var<storage, read_write> body_states: array<BodyState>;
@group(0) @binding(2) var<storage, read_write> reactions: array<atomic<u32>>;
@group(0) @binding(3) var<storage, read_write> wake_flags: array<atomic<u32>>;
@group(0) @binding(4) var<storage, read_write> woke_count: array<atomic<u32>>;
@group(0) @binding(5) var<storage, read_write> deferred_woke_count: array<atomic<u32>>;

const REACTION_SCALE: f32 = 65536.0;
const REACTION_WORDS: u32 = 8u;

fn word_value(word: u32) -> f32 {
    return f32(i32(word)) / REACTION_SCALE;
}

fn work(index: u32) {
    let base = index * REACTION_WORDS;
    let shift_x = atomicExchange(&reactions[base], 0u);
    let shift_y = atomicExchange(&reactions[base + 1u], 0u);
    let shift_z = atomicExchange(&reactions[base + 2u], 0u);
    let spin_x = atomicExchange(&reactions[base + 4u], 0u);
    let spin_y = atomicExchange(&reactions[base + 5u], 0u);
    let spin_z = atomicExchange(&reactions[base + 6u], 0u);
    if (shift_x == 0u && shift_y == 0u && shift_z == 0u && spin_x == 0u && spin_y == 0u && spin_z == 0u) {
        return;
    }
    let shift = vec3f(word_value(shift_x), word_value(shift_y), word_value(shift_z));
    let spin = vec3f(word_value(spin_x), word_value(spin_y), word_value(spin_z));
    var state = body_states[index];
    if (state.sleeping != 0u) {
        atomicAdd(&woke_count[0], 1u);
        atomicAdd(&deferred_woke_count[0], 1u);
    }
    state.position = state.position + shift;
    state.prev_position = state.prev_position + shift;
    state.velocity = state.velocity + shift / params.dt;
    state.angular_velocity = state.angular_velocity + spin / params.dt;
    state.orientation = normalize(quat_mul(vec4f(spin * 0.5, 1.0), state.orientation));
    state.sleeping = 0u;
    state.sleep_timer = 0.0;
    body_states[index] = state;
    atomicOr(&wake_flags[index], 1u);
}