1use crate::scene::node::constructor::NodeConstructor;
26use crate::{
27 core::{
28 algebra::{Matrix4, UnitQuaternion, Vector3},
29 math::{aabb::AxisAlignedBoundingBox, Matrix4Ext},
30 pool::Handle,
31 reflect::prelude::*,
32 type_traits::prelude::*,
33 uuid::{uuid, Uuid},
34 uuid_provider,
35 variable::InheritableVariable,
36 visitor::prelude::*,
37 },
38 graph::BaseSceneGraph,
39 scene::{
40 base::{Base, BaseBuilder},
41 collider::Collider,
42 graph::Graph,
43 node::{Node, NodeTrait, UpdateContext},
44 rigidbody::{RigidBody, RigidBodyType},
45 },
46};
47use fyrox_graph::constructor::ConstructorProvider;
48use fyrox_graph::SceneGraphNode;
49use std::{
50 any::{type_name, Any, TypeId},
51 ops::{Deref, DerefMut},
52};
53
54#[derive(Clone, Debug, PartialEq, Default)]
57pub struct Limb {
58 pub bone: Handle<Node>,
60 pub physical_bone: Handle<Node>,
62 pub children: Vec<Limb>,
64}
65
66uuid_provider!(Limb = "6d5bc2f7-8acc-4b64-8e4b-65d4551150bf");
67
68impl Reflect for Limb {
70 fn source_path() -> &'static str {
71 file!()
72 }
73
74 fn type_name(&self) -> &'static str {
75 type_name::<Self>()
76 }
77
78 fn doc(&self) -> &'static str {
79 ""
80 }
81
82 fn assembly_name(&self) -> &'static str {
83 env!("CARGO_PKG_NAME")
84 }
85
86 fn type_assembly_name() -> &'static str {
87 env!("CARGO_PKG_NAME")
88 }
89
90 fn fields_info(&self, func: &mut dyn FnMut(&[FieldInfo])) {
91 func(&[
92 FieldInfo {
93 owner_type_id: TypeId::of::<Self>(),
94 name: "Bone",
95 display_name: "Bone",
96 description: "",
97 tag: "",
98 type_name: type_name::<Handle<Node>>(),
99 value: &self.bone,
100 reflect_value: &self.bone,
101 read_only: false,
102 immutable_collection: false,
103 min_value: None,
104 max_value: None,
105 step: None,
106 precision: None,
107 doc: "",
108 },
109 FieldInfo {
110 owner_type_id: TypeId::of::<Self>(),
111 name: "PhysicalBone",
112 display_name: "Physical Bone",
113 description: "",
114 tag: "",
115 type_name: type_name::<Handle<Node>>(),
116 value: &self.physical_bone,
117 reflect_value: &self.physical_bone,
118 read_only: false,
119 immutable_collection: false,
120 min_value: None,
121 max_value: None,
122 step: None,
123 precision: None,
124 doc: "",
125 },
126 FieldInfo {
127 owner_type_id: TypeId::of::<Self>(),
128 name: "Children",
129 display_name: "Children",
130 description: "",
131 tag: "",
132 type_name: type_name::<Vec<Limb>>(),
133 value: &self.children,
134 reflect_value: &self.children,
135 read_only: false,
136 immutable_collection: false,
137 min_value: None,
138 max_value: None,
139 step: None,
140 precision: None,
141 doc: "",
142 },
143 ])
144 }
145
146 fn into_any(self: Box<Self>) -> Box<dyn Any> {
147 self
148 }
149
150 fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
151 func(self)
152 }
153
154 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
155 func(self)
156 }
157
158 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
159 func(self)
160 }
161
162 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
163 func(self)
164 }
165
166 fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
167 let this = std::mem::replace(self, value.take()?);
168 Ok(Box::new(this))
169 }
170
171 fn fields(&self, func: &mut dyn FnMut(&[&dyn Reflect])) {
172 func(&[&self.bone, &self.physical_bone, &self.children])
173 }
174
175 fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [&mut dyn Reflect])) {
176 func(&mut [&mut self.bone, &mut self.physical_bone, &mut self.children])
177 }
178
179 fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
180 func(match name {
181 "Bone" => Some(&self.bone),
182 "PhysicalBone" => Some(&self.physical_bone),
183 "Children" => Some(&self.children),
184 _ => None,
185 })
186 }
187
188 fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
189 func(match name {
190 "Bone" => Some(&mut self.bone),
191 "PhysicalBone" => Some(&mut self.physical_bone),
192 "Children" => Some(&mut self.children),
193 _ => None,
194 })
195 }
196}
197
198impl Visit for Limb {
199 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
200 let mut guard = visitor.enter_region(name)?;
201
202 self.bone.visit("Bone", &mut guard)?;
203 self.physical_bone.visit("PhysicalBone", &mut guard)?;
204 self.children.visit("Children", &mut guard)?;
205
206 Ok(())
207 }
208}
209
210impl Limb {
211 pub fn iterate_recursive<F>(&self, func: &mut F)
214 where
215 F: FnMut(&Self),
216 {
217 func(self);
218
219 for child in self.children.iter() {
220 child.iterate_recursive(func)
221 }
222 }
223}
224
225#[derive(Clone, Reflect, Visit, Debug, Default, ComponentProvider)]
236#[visit(optional)]
237pub struct Ragdoll {
238 base: Base,
239 pub character_rigid_body: InheritableVariable<Handle<Node>>,
242 pub is_active: InheritableVariable<bool>,
245 pub root_limb: InheritableVariable<Limb>,
248 pub deactivate_colliders: InheritableVariable<bool>,
251 #[reflect(hidden)]
252 prev_enabled: bool,
253}
254
255impl Deref for Ragdoll {
256 type Target = Base;
257
258 fn deref(&self) -> &Self::Target {
259 &self.base
260 }
261}
262
263impl DerefMut for Ragdoll {
264 fn deref_mut(&mut self) -> &mut Self::Target {
265 &mut self.base
266 }
267}
268
269impl TypeUuidProvider for Ragdoll {
270 fn type_uuid() -> Uuid {
271 uuid!("f4441683-dcef-472d-9d7d-4adca4579107")
272 }
273}
274
275impl ConstructorProvider<Node, Graph> for Ragdoll {
276 fn constructor() -> NodeConstructor {
277 NodeConstructor::new::<Self>()
278 .with_variant("Ragdoll", |_| {
279 RagdollBuilder::new(BaseBuilder::new().with_name("Ragdoll"))
280 .build_node()
281 .into()
282 })
283 .with_group("Physics")
284 }
285}
286
287impl NodeTrait for Ragdoll {
288 fn local_bounding_box(&self) -> AxisAlignedBoundingBox {
289 self.base.local_bounding_box()
290 }
291
292 fn world_bounding_box(&self) -> AxisAlignedBoundingBox {
293 self.base.world_bounding_box()
294 }
295
296 fn id(&self) -> Uuid {
297 Self::type_uuid()
298 }
299
300 fn update(&mut self, ctx: &mut UpdateContext) {
301 let mut new_lin_vel = None;
303 let mut new_ang_vel = None;
304 if *self.is_active && !self.prev_enabled {
305 if let Some(character_rigid_body) = ctx
306 .nodes
307 .try_borrow_mut(*self.character_rigid_body)
308 .and_then(|n| n.component_mut::<RigidBody>())
309 {
310 new_lin_vel = Some(character_rigid_body.lin_vel());
311 new_ang_vel = Some(character_rigid_body.ang_vel());
312 }
313 }
314 self.prev_enabled = *self.is_active;
315
316 self.root_limb.iterate_recursive(&mut |limb| {
317 let mbc = ctx.nodes.begin_multi_borrow();
318
319 let mut need_update_transform = false;
320
321 if let Ok(mut limb_body) =
322 mbc.try_get_component_of_type_mut::<RigidBody>(limb.physical_bone)
323 {
324 if *self.is_active {
325 if let Some(lin_vel) = new_lin_vel {
327 limb_body.set_lin_vel(lin_vel);
328 }
329 if let Some(ang_vel) = new_ang_vel {
330 limb_body.set_ang_vel(ang_vel);
331 }
332
333 if limb_body.body_type() != RigidBodyType::Dynamic {
334 limb_body.set_body_type(RigidBodyType::Dynamic);
335 }
336
337 if *self.deactivate_colliders {
338 for child in limb_body.children() {
339 if let Ok(mut collider) =
340 mbc.try_get_component_of_type_mut::<Collider>(*child)
341 {
342 collider.set_is_sensor(false);
343 }
344 }
345 }
346
347 let body_transform = limb_body.global_transform();
348
349 let bone_parent = mbc.try_get(limb.bone).unwrap().parent();
351 let transform: Matrix4<f32> = mbc
352 .try_get(bone_parent)
353 .unwrap()
354 .global_transform()
355 .try_inverse()
356 .unwrap_or_else(Matrix4::identity)
357 * body_transform;
358
359 mbc.try_get_mut(limb.bone)
360 .unwrap()
361 .local_transform_mut()
362 .set_position(Vector3::new(transform[12], transform[13], transform[14]))
363 .set_pre_rotation(UnitQuaternion::identity())
364 .set_post_rotation(UnitQuaternion::identity())
365 .set_rotation(UnitQuaternion::from_matrix_eps(
366 &transform.basis(),
367 f32::EPSILON,
368 16,
369 Default::default(),
370 ));
371
372 need_update_transform = true;
373 } else {
374 limb_body.set_body_type(RigidBodyType::KinematicPositionBased);
375 limb_body.set_lin_vel(Default::default());
376 limb_body.set_ang_vel(Default::default());
377
378 if *self.deactivate_colliders {
379 for child in limb_body.children() {
380 if let Ok(mut collider) =
381 mbc.try_get_component_of_type_mut::<Collider>(*child)
382 {
383 collider.set_is_sensor(true);
384 }
385 }
386 }
387
388 let self_transform_inverse =
389 self.global_transform().try_inverse().unwrap_or_default();
390
391 if let Ok(bone) = mbc.try_get(limb.bone) {
393 let relative_transform = self_transform_inverse * bone.global_transform();
394
395 let position = Vector3::new(
396 relative_transform[12],
397 relative_transform[13],
398 relative_transform[14],
399 );
400 let rotation = UnitQuaternion::from_matrix_eps(
401 &relative_transform.basis(),
402 f32::EPSILON,
403 16,
404 Default::default(),
405 );
406 limb_body
407 .local_transform_mut()
408 .set_position(position)
409 .set_rotation(rotation);
410 }
411 }
412 };
413
414 drop(mbc);
415
416 if need_update_transform {
417 Graph::update_hierarchical_data_recursively(
420 ctx.nodes,
421 ctx.sound_context,
422 ctx.physics,
423 ctx.physics2d,
424 limb.bone,
425 );
426 }
427 });
428
429 if let Some(root_limb_body) = ctx.nodes.try_borrow(self.root_limb.bone) {
430 let position = root_limb_body.global_position();
431 if let Some(character_rigid_body) = ctx
432 .nodes
433 .try_borrow_mut(*self.character_rigid_body)
434 .and_then(|n| n.component_mut::<RigidBody>())
435 {
436 if *self.is_active {
437 character_rigid_body.set_lin_vel(Default::default());
438 character_rigid_body.set_ang_vel(Default::default());
439 character_rigid_body
440 .local_transform_mut()
441 .set_position(position);
442 character_rigid_body.set_body_type(RigidBodyType::KinematicPositionBased);
443 } else {
444 character_rigid_body.set_body_type(RigidBodyType::Dynamic);
445 }
446 }
447 }
448 }
449}
450
451pub struct RagdollBuilder {
453 base_builder: BaseBuilder,
454 character_rigid_body: Handle<Node>,
455 is_active: bool,
456 deactivate_colliders: bool,
457 root_limb: Limb,
458}
459
460impl RagdollBuilder {
461 pub fn new(base_builder: BaseBuilder) -> Self {
463 Self {
464 base_builder,
465 character_rigid_body: Default::default(),
466 is_active: true,
467 deactivate_colliders: false,
468 root_limb: Default::default(),
469 }
470 }
471
472 pub fn with_character_rigid_body(mut self, handle: Handle<Node>) -> Self {
474 self.character_rigid_body = handle;
475 self
476 }
477
478 pub fn with_active(mut self, active: bool) -> Self {
480 self.is_active = active;
481 self
482 }
483
484 pub fn with_root_limb(mut self, root_limb: Limb) -> Self {
486 self.root_limb = root_limb;
487 self
488 }
489
490 pub fn with_deactivate_colliders(mut self, value: bool) -> Self {
492 self.deactivate_colliders = value;
493 self
494 }
495
496 pub fn build_ragdoll(self) -> Ragdoll {
498 Ragdoll {
499 base: self.base_builder.build_base(),
500 character_rigid_body: self.character_rigid_body.into(),
501 is_active: self.is_active.into(),
502 root_limb: self.root_limb.into(),
503 deactivate_colliders: self.deactivate_colliders.into(),
504 prev_enabled: self.is_active,
505 }
506 }
507
508 pub fn build_node(self) -> Node {
510 Node::new(self.build_ragdoll())
511 }
512
513 pub fn build(self, graph: &mut Graph) -> Handle<Node> {
515 graph.add_node(self.build_node())
516 }
517}