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}