1use crate::RigidDomain;
2use dynamis_abi::{
3 AabbRecord, BodyStateRecord, CONTACT_MAX_POINTS, ConstraintRowsRecord, ConstraintRuntimeRecord,
4 ContactEventRecord, ContactRecord, JointStateRecord, NO_SLOT, SOLVER_BLOCK_CONSTRAINT,
5};
6use dynamis_domain::Domain;
7use dynamis_domain::streams;
8use dynamis_gpu::Contents;
9use dynamis_gpu::EVENT_SLOTS;
10
11pub const COMPACT_BLOCK: u32 = 256;
12
13const SOLVER_BLOCK_KINDS: u32 = SOLVER_BLOCK_CONSTRAINT + 1;
14
15pub const DELTA_WORDS: u32 = dynamis_abi::SOLVER_DELTA_WORDS;
16pub const BLOCK_LANES: u32 = 2;
17
18streams! {
19 RigidStreams, RigidStream, RigidDemand, RigidDomain::ID, demand,
20 demand {
21 bodies: u32,
22 colliders: u32,
23 constraints: u32,
24 pairs: u32,
25 events: u32,
26 sort: u32,
27 }
28 streams {
29 collider_aabbs, ColliderAabbs: "broadphase aabbs", AabbRecord, 1, Contents::Scratch, demand.colliders;
30 live_bodies, LiveBodies: "live body rows", u32, 1, Contents::Scratch, demand.bodies;
31 body_activity, BodyActivity: "body activity", u32, 1, Contents::Scratch, demand.bodies;
32 body_motion, BodyMotion: "body motion", u32, 1, Contents::Scratch, demand.bodies;
33 body_state_scratch, BodyStateScratch: "body state scratch", BodyStateRecord, 1, Contents::Scratch, demand.bodies;
34 constraint_rows, ConstraintRows: "constraint rows", ConstraintRowsRecord, 1, Contents::Scratch, demand.constraints;
35 joint_states, JointStates: "joint states", JointStateRecord, 1, Contents::Scratch, demand.constraints;
36 constraint_scratch, ConstraintScratch: "constraint state scratch", ConstraintRuntimeRecord, 1, Contents::Scratch, demand.constraints;
37 joint_filter_major, JointFilterMajor: "joint filter major", u32, 1, Contents::Scratch, demand.constraints;
38 joint_filter_minor, JointFilterMinor: "joint filter minor", u32, 1, Contents::Scratch, demand.constraints;
39 ccd_factor, CcdFactor: "ccd retreat factors", u32, 1, Contents::Scratch, demand.bodies;
40 ccd_impact, CcdImpact: "ccd impacts", [f32; 4], 1, Contents::Scratch, demand.bodies;
41 contacts_raw, ContactsRaw: "contacts raw", ContactRecord, 1, Contents::Scratch, demand.pairs;
42 contact_valid, ContactValid: "contact valid", u32, 1, Contents::Scratch, demand.pairs;
43 compact_ranks, CompactRanks: "compact ranks", u32, 1, Contents::Scratch, demand.pairs;
44 compact_block_sums, CompactBlockSums: "compact block sums", u32, 1, Contents::Scratch, demand.compact_blocks();
45 compact_block_offsets, CompactBlockOffsets: "compact block offsets", u32, 1, Contents::Scratch, demand.compact_blocks();
46 contacts, Contacts: "contacts", ContactRecord, 1, Contents::Scratch, demand.pairs;
47 contact_target_speeds, ContactTargetSpeeds: "contact target speeds", f32, CONTACT_MAX_POINTS, Contents::Scratch, demand.pairs;
48 contact_matched, ContactMatched: "contact matched", u32, 1, Contents::Scratch, demand.pairs;
49 contact_archive, ContactArchive: "contact archive", ContactRecord, 1, Contents::Durable, demand.pairs;
50 resting_contacts, RestingContacts: "resting contacts", ContactRecord, 1, Contents::Durable, demand.pairs;
51 resting_live, RestingLive: "resting contact live", u32, 1, Contents::Durable, demand.pairs;
52 resting_next, RestingNext: "resting contact next", u32, 1, Contents::Durable, demand.pairs;
53 resting_free, RestingFree: "resting contact free", u32, 1, Contents::Seeded(NO_SLOT), 1;
54 resting_index_major, RestingIndexMajor: "resting index major", u32, 1, Contents::Durable, demand.pairs;
55 resting_index_minor, RestingIndexMinor: "resting index minor", u32, 1, Contents::Durable, demand.pairs;
56 resting_index_slots, RestingIndexSlots: "resting index slots", u32, 1, Contents::Durable, demand.pairs;
57 solver_segments, SolverSegments: "solver segments", u32, 1, Contents::Scratch, SOLVER_BLOCK_KINDS;
58 solver_block_counts, SolverBlockCounts: "solver block counts", u32, 1, Contents::Scratch, demand.bodies;
59 solver_blocks, SolverBlocks: "solver block lanes", u32, 1, Contents::Scratch, demand.solver_words();
60 solver_velocity_deltas, SolverVelocityDeltas: "solver velocity deltas", u32, 1, Contents::Scratch, demand.body_words();
61 solver_position_deltas, SolverPositionDeltas: "solver position deltas", u32, 1, Contents::Scratch, demand.body_words();
62 solver_resolution, SolverResolution: "solver resolution", [f32; 4], 1, Contents::Scratch, demand.bodies;
63 solver_contributions, SolverContributions: "solver contributions", u32, 1, Contents::Scratch, demand.bodies;
64 island_parents, IslandParents: "island parents", u32, 1, Contents::Scratch, demand.bodies;
65 island_state, IslandState: "island state", u32, 1, Contents::Scratch, demand.bodies;
66 events, Events: "contact events", ContactEventRecord, 1, Contents::Scratch, demand.events.saturating_mul(EVENT_SLOTS);
67 sort_scratch_major, SortScratchMajor: "sort scratch major", u32, 1, Contents::Scratch, demand.sort;
68 sort_scratch_minor, SortScratchMinor: "sort scratch minor", u32, 1, Contents::Scratch, demand.sort;
69 sort_scratch_payload, SortScratchPayload: "sort scratch payload", u32, 1, Contents::Scratch, demand.sort;
70 sort_dummy_payload, SortDummyPayload: "sort dummy payload", u32, 1, Contents::Scratch, demand.sort;
71 }
72}
73
74impl RigidDemand {
75 pub fn blocks(&self) -> u32 {
76 self.pairs.saturating_add(self.constraints)
77 }
78
79 pub fn solver_words(&self) -> u32 {
80 self.blocks().saturating_mul(BLOCK_LANES)
81 }
82
83 pub fn body_words(&self) -> u32 {
84 self.bodies.saturating_mul(DELTA_WORDS)
85 }
86
87 pub fn compact_blocks(&self) -> u32 {
88 self.pairs.div_ceil(COMPACT_BLOCK)
89 }
90
91 pub fn sort_slots(pairs: u32, constraints: u32) -> u32 {
92 pairs.saturating_add(constraints)
93 }
94}
95
96pub fn event_capacity<R: dynamis_gpu::Resources>(resources: &R) -> u32 {
97 resources.slots(RigidStream::Events.into()) / EVENT_SLOTS
98}
99
100pub fn sort_capacity<R: dynamis_gpu::Resources>(resources: &R) -> u32 {
101 resources.slots(RigidStream::SortScratchMajor.into())
102}