Skip to main content

dynamis_abi/
constant.rs

1use crate::wgsl::declare_constants;
2
3include!(concat!(env!("OUT_DIR"), "/lengths.rs"));
4
5declare_constants! {
6    pub const EDIT_PATCH: u32 = 0;
7    pub const EDIT_FORCE: u32 = 1;
8    pub const EDIT_TORQUE: u32 = 2;
9    pub const EDIT_IMPULSE: u32 = 3;
10    pub const EDIT_SLEEP: u32 = 4;
11    pub const EDIT_WAKE: u32 = 5;
12    pub const EDIT_FORCE_AT_POINT: u32 = 6;
13    pub const EDIT_IMPULSE_AT_POINT: u32 = 7;
14    pub const EDIT_ANGULAR_IMPULSE: u32 = 8;
15    pub const PATCH_POSITION: u32 = 1;
16    pub const PATCH_VELOCITY: u32 = 2;
17    pub const PATCH_ORIENTATION: u32 = 4;
18    pub const PATCH_ANGULAR_VELOCITY: u32 = 8;
19    pub const BODY_KINEMATIC: u32 = 1;
20    pub const BODY_CCD: u32 = 2;
21    pub const OVERRIDE_SLEEP_LINEAR: u32 = 4;
22    pub const OVERRIDE_SLEEP_ANGULAR: u32 = 8;
23    pub const NO_COLLISION_FILTER: u32 = u32::MAX;
24    pub const SOLVER_BLOCK_CONTACT: u32 = 0;
25    pub const SOLVER_BLOCK_CONSTRAINT: u32 = 1;
26    pub const SOLVER_DELTA_WORDS: u32 = 8;
27    pub const SHAPE_NONE: u32 = 0;
28    pub const SHAPE_SPHERE: u32 = 1;
29    pub const SHAPE_CUBOID: u32 = 2;
30    pub const SHAPE_CAPSULE: u32 = 3;
31    pub const SHAPE_CYLINDER: u32 = 4;
32    pub const SHAPE_HULL: u32 = 5;
33    pub const SHAPE_MESH: u32 = 6;
34    pub const SHAPE_HEIGHTFIELD: u32 = 7;
35    pub const SHAPE_TRIANGLE: u32 = 8;
36    pub const SHAPE_PLANE: u32 = 9;
37    pub const COLLIDER_SENSOR: u32 = 1;
38    pub const COLLIDER_EVENT_BEGIN_END: u32 = 2;
39    pub const COLLIDER_EVENT_PERSIST: u32 = 4;
40    pub const CONTACT_ANNOUNCED: u32 = 0x8000_0000;
41    pub const ISLAND_WAKE: u32 = 1;
42    pub const ELEMENT_ROLE_BITS: u32 = 2;
43    pub const ELEMENT_ROLE_MASK: u32 = (1 << ELEMENT_ROLE_BITS) - 1;
44    pub const ELEMENT_DISTANCE: u32 = 0;
45    pub const ELEMENT_AREA: u32 = 1;
46    pub const ELEMENT_BEND: u32 = 2;
47    pub const ELEMENT_VOLUME: u32 = 3;
48    pub const ELEMENT_KIND_MASK: u32 = 3;
49    pub const ELEMENT_BROKEN: u32 = 1 << 31;
50    pub const FEATURE_POINT: u32 = 0;
51    pub const FEATURE_VERTEX: u32 = 1 << 28;
52    pub const FEATURE_EDGE: u32 = 2 << 28;
53    pub const FEATURE_FACE: u32 = 3 << 28;
54    pub const FEATURE_TRIANGLE: u32 = 4 << 28;
55    pub const FEATURE_KIND_MASK: u32 = 0xF000_0000;
56    pub const FEATURE_FIELD_BITS: u32 = 14;
57    pub const FEATURE_FIELD_MASK: u32 = (1 << FEATURE_FIELD_BITS) - 1;
58    pub const FEATURE_INDEX_LIMIT: u32 = 1 << 12;
59    pub const FEATURE_CLIP: u32 = 1 << 12;
60    pub const FEATURE_FACE_BIT: u32 = 1 << 13;
61    pub const FEATURE_TRIANGLE_SIDE: u32 = 1 << 27;
62    pub const FEATURE_TRIANGLE_MASK: u32 = FEATURE_TRIANGLE_SIDE - 1;
63    pub const MAX_CELLS_PER_AXIS: u32 = 2;
64    pub const MAX_CELLS_PER_COLLIDER: u32 = 8;
65    pub const ENTRY_CELLS_PER_PARTICLE: u32 = 2;
66    pub const ENTRY_INDEX_BITS: u32 = 24;
67    pub const ENTRY_INDEX_MASK: u32 = (1 << ENTRY_INDEX_BITS) - 1;
68    pub const ENTRY_CELL_SHIFT: u32 = ENTRY_INDEX_BITS;
69    pub const ENTRY_CELL_MASK: u32 = 7 << ENTRY_CELL_SHIFT;
70    pub const ENTRY_KIND_SHIFT: u32 = ENTRY_CELL_SHIFT + 3;
71    pub const ENTRY_KIND_MASK: u32 = 3 << ENTRY_KIND_SHIFT;
72    pub const ENTRY_MOBILE: u32 = 1 << 29;
73    pub const ENTRY_AWAKE: u32 = 1 << 30;
74    pub const ENTRY_PRIMARY: u32 = 1 << 31;
75    pub const ENTRY_KIND_COLLIDER: u32 = 0;
76    pub const ENTRY_KIND_PARTICLE: u32 = 1;
77    pub const LEVEL_KEY_SHIFT: u32 = 27;
78    pub const CELL_HASH_MASK: u32 = 0x07FF_FFFF;
79    pub const CONSTRAINT_BALL: u32 = 0;
80    pub const CONSTRAINT_DISTANCE: u32 = 1;
81    pub const CONSTRAINT_REVOLUTE: u32 = 2;
82    pub const CONSTRAINT_PRISMATIC: u32 = 3;
83    pub const CONSTRAINT_FIXED: u32 = 4;
84    pub const CONSTRAINT_GEAR: u32 = 5;
85    pub const CONSTRAINT_PULLEY: u32 = 6;
86    pub const CONSTRAINT_CONE: u32 = 7;
87    pub const CONSTRAINT_SIXDOF: u32 = 8;
88    pub const CONSTRAINT_DISABLE_COLLISIONS: u32 = 1;
89    pub const CONSTRAINT_HAS_LIMIT: u32 = 2;
90    pub const CONSTRAINT_HAS_MOTOR: u32 = 4;
91    pub const CONSTRAINT_IS_SPRING: u32 = 8;
92    pub const CONSTRAINT_HAS_SWING: u32 = 16;
93    pub const CONSTRAINT_HAS_BREAK: u32 = 32;
94    pub const CONSTRAINT_WARM_START: u32 = 64;
95    pub const DOF_LOCKED: u32 = 1 << 8;
96    pub const DOF_LIMITED: u32 = 1 << 14;
97    pub const DOF_DRIVEN: u32 = 1 << 20;
98    pub const DOF_LIMIT_ROW_BASE: u32 = 8;
99    pub const QUERY_RAY: u32 = 0;
100    pub const QUERY_SPHERE: u32 = 1;
101    pub const QUERY_CUBOID: u32 = 2;
102    pub const QUERY_SWEEP: u32 = 3;
103    pub const QUERY_POINT: u32 = 4;
104    pub const QUERY_CONVEX: u32 = 5;
105    pub const FILTER_IGNORE_SENSORS: u32 = 1;
106    pub const FILTER_IGNORE_SLEEPING: u32 = 2;
107    pub const FILTER_IGNORE_STATIC: u32 = 4;
108    pub const FILTER_IGNORE_KINEMATIC: u32 = 8;
109    pub const EVENT_BEGIN: u32 = 0;
110    pub const EVENT_END: u32 = 1;
111    pub const EVENT_PERSIST: u32 = 2;
112    pub const NO_BODY: u32 = 0xFFFF_FFFF;
113    pub const NO_SLOT: u32 = 0xFFFF_FFFF;
114    pub const NO_SURFACE: u32 = 0xFFFF_FFFF;
115    pub const NO_TRIANGLE: u32 = 0xFFFF_FFFF;
116}
117
118const _: () = assert!(
119    MAX_CELLS_PER_COLLIDER == MAX_CELLS_PER_AXIS * MAX_CELLS_PER_AXIS * MAX_CELLS_PER_AXIS,
120    "a collider budget must be the cube of its per axis span"
121);
122const _: () = assert!(
123    FEATURE_FIELD_BITS * 2 + 4 == 32,
124    "a pair feature must pack two fields below its kind"
125);
126const _: () = assert!(
127    FEATURE_INDEX_LIMIT <= FEATURE_CLIP && FEATURE_FACE_BIT <= FEATURE_FIELD_MASK,
128    "a shape point id must not collide with the shape tags"
129);
130const _: () = assert!(
131    FEATURE_KIND_MASK & FEATURE_FIELD_MASK == 0
132        && FEATURE_TRIANGLE & FEATURE_KIND_MASK == FEATURE_TRIANGLE,
133    "a feature kind must sit above its shape fields"
134);
135const _: () = assert!(
136    CELL_HASH_MASK == (1 << LEVEL_KEY_SHIFT) - 1,
137    "a cell hash must fill every bit below the level"
138);
139const _: () = assert!(
140    1 << ELEMENT_ROLE_BITS == ELEMENT_PARTICLES,
141    "an element role must be addressable by a fixed bit width"
142);
143const _: () = assert!(
144    ELEMENT_DISTANCE < ELEMENT_AREA && ELEMENT_AREA < ELEMENT_BEND && ELEMENT_BEND < ELEMENT_VOLUME,
145    "element kinds must fill their code space"
146);
147const _: () = assert!(
148    ELEMENT_VOLUME & ELEMENT_KIND_MASK == ELEMENT_VOLUME && ELEMENT_KIND_MASK & ELEMENT_BROKEN == 0,
149    "an element failure must sit above its kind code space"
150);
151const _: () = assert!(
152    MAX_CELLS_PER_COLLIDER <= 1 << 3,
153    "a grid entry must pack its cell offset into three bits"
154);
155const _: () = assert!(
156    ENTRY_KIND_MASK != 0
157        && ENTRY_KIND_MASK & ENTRY_MOBILE == 0
158        && ENTRY_MOBILE & ENTRY_AWAKE == 0
159        && ENTRY_AWAKE & ENTRY_PRIMARY == 0,
160    "a grid entry kind, mobile bit, awake bit and primary bit must be disjoint"
161);
162const _: () = assert!(
163    ENTRY_INDEX_MASK < 1 << ENTRY_CELL_SHIFT
164        && ENTRY_CELL_MASK & ENTRY_KIND_MASK == 0
165        && ENTRY_KIND_SHIFT + 2 <= 29,
166    "a grid entry must pack its index and cell below the kind"
167);
168
169pub const DOF_COUNT: u32 = 6;
170
171const _: () = assert!(
172    CONSTRAINT_WARM_START < DOF_LOCKED
173        && DOF_LOCKED < DOF_LIMITED
174        && DOF_LIMITED < DOF_DRIVEN
175        && DOF_DRIVEN << (DOF_COUNT - 1) < 1 << 31,
176    "dof flags must occupy disjoint bits above the constraint flags"
177);
178const _: () = assert!(
179    DOF_LIMIT_ROW_BASE + DOF_COUNT <= CONSTRAINT_ACCUMULATOR_SLOTS,
180    "dof limit rows must fit the constraint accumulator budget"
181);
182const _: () = assert!(
183    DOF_COUNT == JOINT_DOF,
184    "the dof budget must be the joint state width"
185);
186
187fn dof_field(flags: u32, base: u32, index: u32) -> bool {
188    assert!(index < DOF_COUNT, "dof index must be below {DOF_COUNT}");
189    flags & (base << index) != 0
190}
191
192fn set_dof_field(flags: u32, base: u32, index: u32, on: bool) -> u32 {
193    assert!(index < DOF_COUNT, "dof index must be below {DOF_COUNT}");
194    let bit = base << index;
195    if on { flags | bit } else { flags & !bit }
196}
197
198pub fn dof_locked(flags: u32, index: u32) -> bool {
199    dof_field(flags, DOF_LOCKED, index)
200}
201
202pub fn dof_limited(flags: u32, index: u32) -> bool {
203    dof_field(flags, DOF_LIMITED, index)
204}
205
206pub fn dof_driven(flags: u32, index: u32) -> bool {
207    dof_field(flags, DOF_DRIVEN, index)
208}
209
210pub fn set_dof_locked(flags: u32, index: u32, on: bool) -> u32 {
211    set_dof_field(flags, DOF_LOCKED, index, on)
212}
213
214pub fn set_dof_limited(flags: u32, index: u32, on: bool) -> u32 {
215    set_dof_field(flags, DOF_LIMITED, index, on)
216}
217
218pub fn set_dof_driven(flags: u32, index: u32, on: bool) -> u32 {
219    set_dof_field(flags, DOF_DRIVEN, index, on)
220}
221
222pub const NO_HIT: f32 = f32::MAX;