1use super::streams::{StateDemand, StateStreams};
2use dynamis_domain::{MIN_SLOTS, STREAM_FLOOR, grown, product, settled};
3
4const COMMANDS_PER_BODY: u32 = 4;
5const CONSTRAINT_COMMANDS_PER_CONSTRAINT: u32 = 4;
6const QUERIES_PER_BODY: u32 = 2;
7
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
9pub struct ShapeCapacity {
10 pub sources: u32,
11 pub vertices: u32,
12 pub triangles: u32,
13 pub nodes: u32,
14}
15
16#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
17pub struct StateCapacity {
18 pub shapes: ShapeCapacity,
19 pub observed: u32,
20}
21
22#[derive(Clone, Copy, Debug)]
23pub struct StateInputs {
24 pub bodies: u32,
25 pub body_ids: u32,
26 pub collider_pool: u32,
27 pub constraints: u32,
28 pub body_commands: u32,
29 pub constraint_commands: u32,
30 pub queries: u32,
31 pub shapes: ShapeCapacity,
32 pub observed: u32,
33}
34
35pub fn capacity(streams: &StateStreams) -> StateCapacity {
36 StateCapacity {
37 shapes: ShapeCapacity {
38 sources: streams.shape_sources.slots(),
39 vertices: streams.shape_vertices.slots(),
40 triangles: streams.shape_triangles.slots(),
41 nodes: streams.shape_nodes.slots(),
42 },
43 observed: streams.observed_ids.slots(),
44 }
45}
46
47pub fn floor() -> StateDemand {
48 StateDemand {
49 bodies: MIN_SLOTS,
50 body_ids: MIN_SLOTS,
51 colliders: MIN_SLOTS,
52 constraints: MIN_SLOTS,
53 body_commands: STREAM_FLOOR,
54 constraint_commands: STREAM_FLOOR,
55 queries: STREAM_FLOOR,
56 shapes: ShapeCapacity {
57 sources: MIN_SLOTS,
58 vertices: MIN_SLOTS,
59 triangles: MIN_SLOTS,
60 nodes: MIN_SLOTS,
61 },
62 observed: MIN_SLOTS,
63 }
64}
65
66pub fn plan(inputs: &StateInputs, idle: bool, current: &StateStreams) -> StateDemand {
67 let bodies = grown(current.body_states.slots(), inputs.bodies, MIN_SLOTS);
68 let body_ids = current
69 .body_row_of_id
70 .slots()
71 .max(inputs.body_ids)
72 .max(MIN_SLOTS);
73 let colliders = current
74 .collider_owners
75 .slots()
76 .max(inputs.collider_pool)
77 .max(MIN_SLOTS);
78 let constraints = settled(
79 idle,
80 current.constraint_runtime.slots(),
81 inputs.constraints,
82 MIN_SLOTS,
83 );
84 let body_commands = settled(
85 idle,
86 current.body_edits.slots(),
87 inputs
88 .body_commands
89 .max(product(bodies, COMMANDS_PER_BODY, "body command")),
90 STREAM_FLOOR,
91 );
92 let constraint_commands = settled(
93 idle,
94 current.constraint_fresh_rows.slots(),
95 inputs.constraint_commands.max(product(
96 constraints,
97 CONSTRAINT_COMMANDS_PER_CONSTRAINT,
98 "constraint command",
99 )),
100 STREAM_FLOOR,
101 );
102 let queries = settled(
103 idle,
104 current.query_records.slots(),
105 inputs
106 .queries
107 .max(product(bodies, QUERIES_PER_BODY, "query")),
108 STREAM_FLOOR,
109 );
110 StateDemand {
111 bodies,
112 body_ids,
113 colliders,
114 constraints,
115 body_commands,
116 constraint_commands,
117 queries,
118 shapes: ShapeCapacity {
119 sources: grown(
120 current.shape_sources.slots(),
121 inputs.shapes.sources,
122 MIN_SLOTS,
123 ),
124 vertices: grown(
125 current.shape_vertices.slots(),
126 inputs.shapes.vertices,
127 MIN_SLOTS,
128 ),
129 triangles: grown(
130 current.shape_triangles.slots(),
131 inputs.shapes.triangles,
132 MIN_SLOTS,
133 ),
134 nodes: grown(current.shape_nodes.slots(), inputs.shapes.nodes, MIN_SLOTS),
135 },
136 observed: grown(current.observed_ids.slots(), inputs.observed, MIN_SLOTS),
137 }
138}