Skip to main content

dynamis_rigid/
domain.rs

1use crate::capacity::Capacity;
2use crate::{
3    Ccd, CcdPasses, Rigid, RigidCapacity, RigidDemand, RigidFrame, RigidInputs, RigidPasses,
4    RigidResolutionPasses, RigidShape, RigidStreams,
5};
6use dynamis_abi::COUNTER_ACTIVE;
7use dynamis_abi::Counters;
8use dynamis_domain::{Domain, Run, StepFacts};
9use dynamis_gpu::GpuContext;
10use dynamis_gpu::Resources;
11use dynamis_pass::{PassGroup, Pipeline, Schedule};
12use wgpu::CommandEncoder;
13
14pub struct RigidDomain;
15
16pub struct RigidDomainPasses {
17    pub simulation: RigidPasses,
18    pub continuous: CcdPasses,
19    pub resolution: RigidResolutionPasses,
20}
21
22pub struct RigidDomainRuntime {
23    pub simulation: Rigid,
24    pub continuous: Ccd,
25}
26
27#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
28pub struct RigidWork {
29    pub body_commands: u32,
30    pub constraint_commands: u32,
31}
32
33impl Domain for RigidDomain {
34    const ID: u32 = 2;
35
36    const SIMULATES: bool = true;
37
38    const PASS_EDGES: dynamis_pass::PassEdges = &[
39        RigidPasses::EDGES,
40        CcdPasses::EDGES,
41        RigidResolutionPasses::EDGES,
42    ];
43
44    type Demand = RigidDemand;
45    type Inputs = RigidInputs;
46    type Work = RigidWork;
47    type Streams = RigidStreams;
48    type Planner = Capacity;
49    type Passes = RigidDomainPasses;
50    type Runtime = RigidDomainRuntime;
51    type Frame = RigidFrame;
52    type Capacity = RigidCapacity;
53
54    fn minimum() -> RigidDemand {
55        Capacity::floor(dynamis_domain::STREAM_FLOOR)
56    }
57
58    fn occupied(inputs: &RigidInputs) -> bool {
59        inputs.bodies > 0
60    }
61
62    fn pending(work: &RigidWork) -> bool {
63        work.body_commands > 0 || work.constraint_commands > 0
64    }
65
66    fn active(measured: &Counters) -> bool {
67        measured[COUNTER_ACTIVE] != 0
68    }
69
70    fn pass_groups() -> &'static [PassGroup] {
71        &[
72            RigidPasses::GROUP,
73            CcdPasses::GROUP,
74            RigidResolutionPasses::GROUP,
75        ]
76    }
77
78    fn resolve(pipeline: &Pipeline) -> RigidDomainPasses {
79        RigidDomainPasses {
80            simulation: RigidPasses::resolve(pipeline),
81            continuous: CcdPasses::resolve(pipeline),
82            resolution: RigidResolutionPasses::resolve(pipeline),
83        }
84    }
85
86    fn build(
87        context: &GpuContext,
88        streams: &impl Resources,
89        passes: RigidDomainPasses,
90    ) -> RigidDomainRuntime {
91        RigidDomainRuntime {
92            simulation: Rigid::new(context, streams, passes.simulation, passes.resolution),
93            continuous: Ccd::new(context, streams, passes.continuous),
94        }
95    }
96
97    fn frame(facts: &StepFacts, inputs: &RigidInputs, run: Run) -> RigidFrame {
98        RigidFrame {
99            params: facts.params,
100            shape: RigidShape::of(&facts.counts),
101            query_count: inputs.queries,
102            observed_count: inputs.observed,
103            simulating: run.awake,
104            indexing: run.indexing,
105            ccd: inputs.ccd,
106        }
107    }
108
109    fn capacity(streams: &RigidStreams) -> RigidCapacity {
110        crate::capacity(streams)
111    }
112
113    fn record(
114        runtime: &RigidDomainRuntime,
115        pass: u32,
116        schedule: &mut Schedule,
117        encoder: &mut CommandEncoder,
118        streams: &impl Resources,
119        frame: &RigidFrame,
120    ) {
121        runtime
122            .simulation
123            .record(pass, schedule, encoder, streams, frame);
124        runtime
125            .continuous
126            .record(pass, schedule, encoder, streams, frame);
127    }
128}