1use na::{Isometry3, Matrix3, RealField, Vector3};
21use nalgebra as na;
22
23#[derive(Debug, Clone)]
24pub enum Geometry<T: RealField> {
25 Box { depth: T, width: T, height: T },
26 Cylinder { radius: T, length: T },
27 Capsule { radius: T, length: T },
28 Sphere { radius: T },
29 Mesh { filename: String, scale: Vector3<T> },
30}
31
32#[derive(Debug, Default, Clone)]
33pub struct Color<T: RealField> {
34 pub r: T,
35 pub g: T,
36 pub b: T,
37 pub a: T,
38}
39
40#[derive(Debug, Clone)]
41pub struct Texture {
42 pub filename: String,
43}
44
45impl Default for Texture {
46 fn default() -> Texture {
47 Texture {
48 filename: "".to_string(),
49 }
50 }
51}
52
53#[derive(Debug, Default, Clone)]
54pub struct Material<T: RealField> {
55 pub name: String,
56 pub color: Color<T>,
57 pub texture: Texture,
58}
59
60#[derive(Debug, Clone)]
61pub struct Inertial<T: RealField> {
62 origin: Isometry3<T>,
63 pub mass: T,
64 pub inertia: Matrix3<T>,
65 world_transform_cache: Option<Isometry3<T>>,
66}
67
68impl<T> Inertial<T>
70where
71 T: RealField,
72{
73 pub fn from_mass(mass: T) -> Self {
74 Self {
75 origin: Isometry3::identity(),
76 mass,
77 inertia: Matrix3::identity(),
78 world_transform_cache: None,
79 }
80 }
81 pub fn new(origin: Isometry3<T>, mass: T, inertia: Matrix3<T>) -> Self {
82 Self {
83 origin,
84 mass,
85 inertia,
86 world_transform_cache: None,
87 }
88 }
89 pub fn set_origin(&mut self, origin: Isometry3<T>) {
90 self.origin = origin;
91 self.world_transform_cache = None;
92 }
93 pub fn origin(&self) -> &Isometry3<T> {
94 &self.origin
95 }
96 pub fn clear_world_transform(&mut self) {
97 self.world_transform_cache = None
98 }
99 pub fn set_world_transform(&mut self, trans: Isometry3<T>) {
100 self.world_transform_cache = Some(trans);
101 }
102 pub fn world_transform(&self) -> &Option<Isometry3<T>> {
103 &self.world_transform_cache
104 }
105}
106
107#[derive(Debug, Clone)]
108pub struct Visual<T: RealField> {
109 pub name: String,
110 origin: Isometry3<T>,
111 pub geometry: Geometry<T>,
112 pub material: Material<T>,
113 world_transform_cache: Option<Isometry3<T>>,
114}
115
116impl<T> Visual<T>
117where
118 T: RealField,
119{
120 pub fn new(
121 name: String,
122 origin: Isometry3<T>,
123 geometry: Geometry<T>,
124 material: Material<T>,
125 ) -> Self {
126 Self {
127 name,
128 origin,
129 geometry,
130 material,
131 world_transform_cache: None,
132 }
133 }
134 pub fn set_origin(&mut self, origin: Isometry3<T>) {
135 self.origin = origin;
136 self.world_transform_cache = None;
137 }
138 pub fn origin(&self) -> &Isometry3<T> {
139 &self.origin
140 }
141 pub fn clear_world_transform(&mut self) {
142 self.world_transform_cache = None
143 }
144 pub fn set_world_transform(&mut self, trans: Isometry3<T>) {
145 self.world_transform_cache = Some(trans);
146 }
147 pub fn world_transform(&self) -> &Option<Isometry3<T>> {
148 &self.world_transform_cache
149 }
150}
151
152#[derive(Debug, Clone)]
153pub struct Collision<T: RealField> {
154 pub name: String,
155 origin: Isometry3<T>,
156 pub geometry: Geometry<T>,
157 world_transform_cache: Option<Isometry3<T>>,
158}
159
160impl<T> Collision<T>
161where
162 T: RealField,
163{
164 pub fn new(name: String, origin: Isometry3<T>, geometry: Geometry<T>) -> Self {
165 Self {
166 name,
167 origin,
168 geometry,
169 world_transform_cache: None,
170 }
171 }
172 pub fn set_origin(&mut self, origin: Isometry3<T>) {
173 self.origin = origin;
174 self.world_transform_cache = None;
175 }
176 pub fn origin(&self) -> &Isometry3<T> {
177 &self.origin
178 }
179 pub fn clear_world_transform(&mut self) {
180 self.world_transform_cache = None
181 }
182 pub fn set_world_transform(&mut self, trans: Isometry3<T>) {
183 self.world_transform_cache = Some(trans);
184 }
185 pub fn world_transform(&self) -> &Option<Isometry3<T>> {
186 &self.world_transform_cache
187 }
188}
189
190#[derive(Debug, Clone)]
191pub struct Link<T: RealField> {
192 pub name: String,
193 pub inertial: Inertial<T>,
194 pub visuals: Vec<Visual<T>>,
195 pub collisions: Vec<Collision<T>>,
196}
197
198impl<T> Default for Link<T>
199where
200 T: RealField,
201{
202 fn default() -> Self {
203 Self {
204 name: "".to_owned(),
205 inertial: Inertial::new(Isometry3::identity(), T::zero(), Matrix3::identity()),
206 visuals: Vec::new(),
207 collisions: Vec::new(),
208 }
209 }
210}
211
212#[derive(Debug)]
213pub struct LinkBuilder<T>
214where
215 T: RealField,
216{
217 name: String,
218 inertial: Inertial<T>,
219 visuals: Vec<Visual<T>>,
220 collisions: Vec<Collision<T>>,
221}
222
223impl<T> LinkBuilder<T>
224where
225 T: RealField,
226{
227 pub fn new() -> Self {
228 Self {
229 name: "".to_owned(),
230 inertial: Inertial::new(Isometry3::identity(), T::zero(), Matrix3::identity()),
231 visuals: Vec::new(),
232 collisions: Vec::new(),
233 }
234 }
235 pub fn name(mut self, name: &str) -> Self {
236 name.clone_into(&mut self.name);
237 self
238 }
239 pub fn inertial(mut self, inertial: Inertial<T>) -> Self {
240 self.inertial = inertial;
241 self
242 }
243 pub fn add_visual(mut self, visual: Visual<T>) -> Self {
244 self.visuals.push(visual);
245 self
246 }
247 pub fn add_collision(mut self, collision: Collision<T>) -> Self {
248 self.collisions.push(collision);
249 self
250 }
251 pub fn finalize(self) -> Link<T> {
252 Link {
253 name: self.name,
254 inertial: self.inertial,
255 visuals: self.visuals,
256 collisions: self.collisions,
257 }
258 }
259}
260
261impl<T> Default for LinkBuilder<T>
262where
263 T: RealField,
264{
265 fn default() -> Self {
266 Self::new()
267 }
268}