wgrapier2d/dynamics/
body.rs1use encase::ShaderType;
4use wgcore::tensor::GpuVector;
5use wgcore::Shader;
6use wgebra::{WgQuat, WgSim2, WgSim3};
7use wgparry::cuboid::GpuCuboid;
8use wgparry::math::{AngVector, AngularInertia, GpuSim, Vector};
9use wgparry::{dim_shader_defs, substitute_aliases};
10use wgpu::{BufferUsages, Device};
11
12#[derive(ShaderType, Copy, Clone, PartialEq)]
13#[repr(C)]
14pub struct GpuForce {
16 pub linear: Vector<f32>,
18 pub angular: AngVector<f32>,
20}
21
22#[derive(ShaderType, Copy, Clone, PartialEq, Default)]
23#[repr(C)]
24pub struct GpuVelocity {
26 pub linear: Vector<f32>,
28 pub angular: AngVector<f32>,
30}
31
32#[derive(ShaderType, Copy, Clone, PartialEq)]
33#[repr(C)]
34pub struct GpuMassProperties {
36 pub inv_inertia: AngularInertia<f32>,
38 pub inv_mass: Vector<f32>,
40 pub com: Vector<f32>, }
43
44impl Default for GpuMassProperties {
45 fn default() -> Self {
46 GpuMassProperties {
47 #[rustfmt::skip]
48 #[cfg(feature = "dim2")]
49 inv_inertia: 1.0,
50 #[cfg(feature = "dim3")]
51 inv_inertia: AngularInertia::identity(),
52 inv_mass: Vector::repeat(1.0),
53 com: Vector::zeros(),
54 }
55 }
56}
57
58pub struct GpuBodySet {
60 len: u32,
61 pub(crate) mprops: GpuVector<GpuMassProperties>,
62 pub(crate) local_mprops: GpuVector<GpuMassProperties>,
63 pub(crate) vels: GpuVector<GpuVelocity>,
64 pub(crate) poses: GpuVector<GpuSim>,
65 pub(crate) shapes: GpuVector<GpuCuboid>,
68}
69
70#[derive(Copy, Clone)]
71pub struct BodyDesc {
73 pub mprops: GpuMassProperties,
75 pub vel: GpuVelocity,
77 pub pose: GpuSim,
79 pub shape: GpuCuboid,
81}
82
83impl Default for BodyDesc {
84 fn default() -> Self {
85 Self {
86 mprops: Default::default(),
87 vel: Default::default(),
88 pose: Default::default(),
89 shape: GpuCuboid::new(Vector::repeat(0.5)),
90 }
91 }
92}
93
94impl GpuBodySet {
95 pub fn is_empty(&self) -> bool {
97 self.len == 0
98 }
99
100 pub fn len(&self) -> u32 {
102 self.len
103 }
104
105 pub fn new(device: &Device, bodies: &[BodyDesc]) -> Self {
107 let (mprops, (vels, (poses, shapes))): (Vec<_>, (Vec<_>, (Vec<_>, Vec<_>))) = bodies
108 .iter()
109 .copied()
110 .map(|b| (b.mprops, (b.vel, (b.pose, b.shape))))
112 .collect();
113 Self {
114 len: bodies.len() as u32,
115 mprops: GpuVector::encase(device, &mprops, BufferUsages::STORAGE),
116 local_mprops: GpuVector::encase(device, &mprops, BufferUsages::STORAGE),
117 vels: GpuVector::encase(device, &vels, BufferUsages::STORAGE),
118 poses: GpuVector::init(device, &poses, BufferUsages::STORAGE),
119 shapes: GpuVector::encase(device, &shapes, BufferUsages::STORAGE),
120 }
121 }
122
123 pub fn poses(&self) -> &GpuVector<GpuSim> {
125 &self.poses
126 }
127
128 pub fn vels(&self) -> &GpuVector<GpuVelocity> {
130 &self.vels
131 }
132
133 pub fn mprops(&self) -> &GpuVector<GpuMassProperties> {
135 &self.mprops
136 }
137
138 pub fn local_mprops(&self) -> &GpuVector<GpuMassProperties> {
140 &self.local_mprops
141 }
142
143 pub fn shapes(&self) -> &GpuVector<GpuCuboid> {
145 &self.shapes
146 }
147}
148
149#[derive(Shader)]
150#[shader(
151 derive(WgQuat, WgSim3, WgSim2),
152 src = "body.wgsl",
153 src_fn = "substitute_aliases",
154 shader_defs = "dim_shader_defs"
155)]
156pub struct WgBody;
159
160