nphysics2d/object/
multibody_link.rs1use std::ops::{Deref, DerefMut};
2
3use na::RealField;
4
5use crate::joint::Joint;
6use crate::math::{Inertia, Isometry, Point, Vector, Velocity};
7use crate::object::BodyPart;
8
9pub struct MultibodyLink<N: RealField + Copy> {
11 pub(crate) name: String,
12 pub(crate) internal_id: usize,
14 pub(crate) assembly_id: usize,
15 pub(crate) impulse_id: usize,
16 pub(crate) is_leaf: bool,
17
18 pub(crate) parent_internal_id: usize,
21 pub(crate) dof: Box<dyn Joint<N>>,
22 pub(crate) parent_shift: Vector<N>,
23 pub(crate) body_shift: Vector<N>,
24
25 pub(crate) parent_to_world: Isometry<N>,
27 pub(crate) local_to_world: Isometry<N>,
28 pub(crate) local_to_parent: Isometry<N>,
29 pub(crate) velocity_dot_wrt_joint: Velocity<N>,
31 pub(crate) velocity_wrt_joint: Velocity<N>,
33 pub(crate) velocity: Velocity<N>,
35 pub(crate) inertia: Inertia<N>,
36 pub(crate) com: Point<N>,
37
38 pub(crate) local_inertia: Inertia<N>,
39 pub(crate) local_com: Point<N>,
40 }
43
44impl<N: RealField + Copy> MultibodyLink<N> {
45 pub fn new(
47 internal_id: usize,
48 assembly_id: usize,
49 impulse_id: usize,
50 parent_internal_id: usize,
51 dof: Box<dyn Joint<N>>,
52 parent_shift: Vector<N>,
53 body_shift: Vector<N>,
54 parent_to_world: Isometry<N>,
55 local_to_world: Isometry<N>,
56 local_to_parent: Isometry<N>,
57 local_inertia: Inertia<N>,
58 local_com: Point<N>,
59 ) -> Self {
60 let is_leaf = true;
61 let velocity = Velocity::zero();
62 let velocity_dot_wrt_joint = Velocity::zero();
63 let velocity_wrt_joint = Velocity::zero();
64 let inertia = local_inertia.transformed(&local_to_world);
65 let com = local_to_world * local_com;
66
67 MultibodyLink {
68 name: String::new(),
69 internal_id,
70 assembly_id,
71 impulse_id,
72 is_leaf,
73 parent_internal_id,
74 dof,
75 parent_shift,
76 body_shift,
77 parent_to_world,
78 local_to_world,
79 local_to_parent,
80 velocity_dot_wrt_joint,
81 velocity_wrt_joint,
82 velocity,
83 local_inertia,
84 local_com,
85 inertia,
86 com,
87 }
88 }
89
90 #[inline]
92 pub fn is_root(&self) -> bool {
93 self.internal_id == 0
94 }
95
96 #[inline]
98 pub fn joint(&self) -> &dyn Joint<N> {
99 &*self.dof
100 }
101
102 #[inline]
104 pub fn joint_mut(&mut self) -> &mut dyn Joint<N> {
105 &mut *self.dof
106 }
107
108 #[inline]
110 pub fn parent_shift(&self) -> &Vector<N> {
111 &self.parent_shift
112 }
113
114 #[inline]
116 pub fn body_shift(&self) -> &Vector<N> {
117 &self.body_shift
118 }
119
120 #[inline]
122 pub fn name(&self) -> &str {
123 &self.name
124 }
125
126 #[inline]
128 pub fn set_name(&mut self, name: String) {
129 self.name = name
130 }
131
132 #[inline]
134 pub fn link_id(&self) -> usize {
135 self.internal_id
136 }
137
138 #[inline]
140 pub fn parent_id(&self) -> Option<usize> {
141 if self.internal_id != 0 {
142 Some(self.parent_internal_id)
143 } else {
144 None
145 }
146 }
147}
148
149impl<N: RealField + Copy> BodyPart<N> for MultibodyLink<N> {
150 #[inline]
151 fn is_ground(&self) -> bool {
152 false
153 }
154
155 #[inline]
156 fn center_of_mass(&self) -> Point<N> {
157 self.com
158 }
159
160 #[inline]
161 fn local_center_of_mass(&self) -> Point<N> {
162 self.local_com
163 }
164
165 #[inline]
166 fn velocity(&self) -> Velocity<N> {
167 self.velocity
168 }
169
170 #[inline]
171 fn position(&self) -> Isometry<N> {
172 self.local_to_world
173 }
174
175 #[inline]
176 fn local_inertia(&self) -> Inertia<N> {
177 self.local_inertia
178 }
179
180 #[inline]
181 fn inertia(&self) -> Inertia<N> {
182 self.inertia
183 }
184}
185
186pub(crate) struct MultibodyLinkVec<N: RealField + Copy>(pub Vec<MultibodyLink<N>>);
188
189impl<N: RealField + Copy> MultibodyLinkVec<N> {
190 #[inline]
202 pub fn get_mut_with_parent(&mut self, i: usize) -> (&mut MultibodyLink<N>, &MultibodyLink<N>) {
203 let parent_id = self[i].parent_internal_id;
204
205 assert!(
206 parent_id != i,
207 "Internal error: circular rigid body dependency."
208 );
209 assert!(parent_id < self.len(), "Invalid parent index.");
210
211 unsafe {
212 let rb = &mut *(self.get_unchecked_mut(i) as *mut _);
213 let parent_rb = &*(self.get_unchecked(parent_id) as *const _);
214 (rb, parent_rb)
215 }
216 }
217}
218
219impl<N: RealField + Copy> Deref for MultibodyLinkVec<N> {
220 type Target = Vec<MultibodyLink<N>>;
221
222 #[inline]
223 fn deref(&self) -> &Vec<MultibodyLink<N>> {
224 let MultibodyLinkVec(ref me) = *self;
225 me
226 }
227}
228
229impl<N: RealField + Copy> DerefMut for MultibodyLinkVec<N> {
230 #[inline]
231 fn deref_mut(&mut self) -> &mut Vec<MultibodyLink<N>> {
232 let MultibodyLinkVec(ref mut me) = *self;
233 me
234 }
235}