dynamis-rigid 0.7.0

Rigid body integration, islands, CCD, and constraint solving
Documentation
use super::streams::RigidStream;
use crate::RigidFrame;
use crate::sort;
use dynamis_abi::COUNTER_JOINTS;
use dynamis_abi::COUNTER_LIVE;
use dynamis_abi::Count;
use dynamis_gpu::Resources;
use dynamis_gpu::{ComputeRecorder, GpuContext};
use dynamis_pass::Stage;
use dynamis_shader::{CORE, rows, stream};
use dynamis_sort::RadixSort;
use dynamis_state::StateStream;

pub struct Integrate {
    begin_step: Stage,
    substep_integrate: Stage,
    substep_advance: Stage,
    broadphase_aabb: Stage,
}

impl Integrate {
    pub fn build(context: &GpuContext, streams: &impl Resources) -> Self {
        Self {
            begin_step: Stage::build(
                context,
                "begin_step",
                rows(
                    context,
                    include_str!("../shaders/begin_step.wgsl"),
                    CORE,
                    Count::Dynamic.field(),
                ),
                streams,
                &[
                    ("params", StateStream::Params.whole()),
                    ("body_states", StateStream::BodyStates.whole()),
                    ("ccd_factor", RigidStream::CcdFactor.whole()),
                ],
                &[],
            ),
            substep_integrate: Stage::build(
                context,
                "substep_integrate",
                stream(
                    context,
                    include_str!("../shaders/substep_integrate.wgsl"),
                    CORE,
                    "work",
                    RigidStream::LiveBodies,
                ),
                streams,
                &[
                    ("params", StateStream::Params.whole()),
                    ("body_states", StateStream::BodyStates.whole()),
                    ("body_descs", StateStream::BodyDescriptors.whole()),
                    ("live_bodies", RigidStream::LiveBodies.whole()),
                    ("live_count", dynamis_state::counter(COUNTER_LIVE)),
                ],
                &[],
            ),
            substep_advance: Stage::build(
                context,
                "substep_advance",
                stream(
                    context,
                    include_str!("../shaders/substep_advance.wgsl"),
                    CORE,
                    "work",
                    RigidStream::LiveBodies,
                ),
                streams,
                &[
                    ("params", StateStream::Params.whole()),
                    ("body_states", StateStream::BodyStates.whole()),
                    ("live_bodies", RigidStream::LiveBodies.whole()),
                    ("live_count", dynamis_state::counter(COUNTER_LIVE)),
                ],
                &[],
            ),
            broadphase_aabb: Stage::build(
                context,
                "broadphase_aabb",
                rows(
                    context,
                    include_str!("../shaders/broadphase_aabb.wgsl"),
                    CORE,
                    Count::Colliders.field(),
                ),
                streams,
                &[
                    ("params", StateStream::Params.whole()),
                    ("body_states", StateStream::BodyStates.whole()),
                    ("body_descs", StateStream::BodyDescriptors.whole()),
                    ("colliders", StateStream::Colliders.whole()),
                    ("collider_owners", StateStream::ColliderOwners.whole()),
                    ("aabbs", RigidStream::ColliderAabbs.whole()),
                    ("counters", StateStream::Counters.whole()),
                ],
                &dynamis_state::shape_resources(),
            ),
        }
    }

    pub fn record_begin(
        &self,
        recorder: &mut ComputeRecorder,
        streams: &impl Resources,
        frame: &RigidFrame,
    ) {
        self.begin_step
            .record_rows(recorder, streams, Count::Dynamic.rows(&frame.params));
    }

    pub fn record_substep(&self, recorder: &mut ComputeRecorder, streams: &impl Resources) {
        self.substep_integrate.record_stream(recorder, streams);
    }

    pub fn record_substep_advance(&self, recorder: &mut ComputeRecorder, streams: &impl Resources) {
        self.substep_advance.record_stream(recorder, streams);
    }

    pub fn record_broadphase(
        &self,
        recorder: &mut ComputeRecorder,
        streams: &impl Resources,
        frame: &RigidFrame,
    ) {
        self.broadphase_aabb
            .record_rows(recorder, streams, Count::Colliders.rows(&frame.params));
    }

    pub fn record(
        &self,
        recorder: &mut ComputeRecorder,
        streams: &impl Resources,
        frame: &RigidFrame,
        sort: &RadixSort,
    ) {
        if frame.params.constraint_count > 0 {
            let words = frame.shape.body_row_words;
            let channels = sort::lanes_dual(
                streams,
                dynamis_state::counter(COUNTER_JOINTS),
                RigidStream::JointFilterMajor.whole(),
                RigidStream::JointFilterMinor.whole(),
            );
            sort.sort(recorder, &channels, words, words);
        }
        self.record_begin(recorder, streams, frame);
        self.broadphase_aabb
            .record_rows(recorder, streams, Count::Colliders.rows(&frame.params));
    }
}