dynamis_rigid/
capacity.rs1use super::streams::{RigidDemand, RigidStreams};
2use dynamis_abi::{COUNTER_EVENTS, COUNTER_SPILLOVER_EVENTS, Counters};
3use dynamis_domain::{MIN_SLOTS, StreamWatch, settled};
4
5const STREAM_DENSITY_EVENTS: u32 = 8;
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
8pub struct RigidCapacity {
9 pub events: u32,
10}
11
12#[derive(Clone, Copy, Debug)]
13pub struct RigidInputs {
14 pub bodies: u32,
15 pub colliders: u32,
16 pub collider_pool: u32,
17 pub constraints: u32,
18 pub queries: u32,
19 pub observed: u32,
20 pub ccd: bool,
21}
22
23pub fn capacity(streams: &RigidStreams) -> RigidCapacity {
24 RigidCapacity {
25 events: streams.events.slots() / dynamis_gpu::EVENT_SLOTS,
26 }
27}
28
29pub struct Capacity {
30 events: StreamWatch,
31}
32
33impl Default for Capacity {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl Capacity {
40 pub const fn new() -> Self {
41 Self {
42 events: StreamWatch::IDLE,
43 }
44 }
45
46 pub fn plan(
47 &mut self,
48 measured: &Counters,
49 inputs: &RigidInputs,
50 idle: bool,
51 pairs: u32,
52 current: &RigidStreams,
53 ) -> RigidDemand {
54 self.events.observe(
55 measured[COUNTER_EVENTS],
56 measured[COUNTER_SPILLOVER_EVENTS] > 0,
57 current.events.slots() / dynamis_gpu::EVENT_SLOTS,
58 );
59 if self.events.pressured() {
60 self.events.settle(false);
61 } else if idle {
62 self.events.settle(true);
63 }
64 let event_budget =
65 dynamis_domain::product(inputs.colliders, STREAM_DENSITY_EVENTS, "event");
66 let events = if idle {
67 self.events.released(
68 current.events.slots() / dynamis_gpu::EVENT_SLOTS,
69 event_budget,
70 )
71 } else {
72 self.events.widened(
73 current.events.slots() / dynamis_gpu::EVENT_SLOTS,
74 event_budget,
75 )
76 };
77 let bodies = dynamis_domain::grown(current.body_activity.slots(), inputs.bodies, MIN_SLOTS);
78 let colliders = current
79 .collider_aabbs
80 .slots()
81 .max(inputs.collider_pool)
82 .max(MIN_SLOTS);
83 let constraints = settled(
84 idle,
85 current.constraint_rows.slots(),
86 inputs.constraints,
87 MIN_SLOTS,
88 );
89 let sort = RigidDemand::sort_slots(pairs, constraints).max(MIN_SLOTS);
90 RigidDemand {
91 bodies,
92 colliders,
93 constraints,
94 pairs,
95 events,
96 sort,
97 }
98 }
99
100 pub fn floor(pairs: u32) -> RigidDemand {
101 RigidDemand {
102 bodies: MIN_SLOTS,
103 colliders: MIN_SLOTS,
104 constraints: MIN_SLOTS,
105 pairs,
106 events: dynamis_domain::STREAM_FLOOR,
107 sort: RigidDemand::sort_slots(pairs, MIN_SLOTS).max(MIN_SLOTS),
108 }
109 }
110}