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;