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 derived_types() -> &'static [TypeId] {
75 &[]
76 }
77
78 fn query_derived_types(&self) -> &'static [TypeId] {
79 Self::derived_types()
80 }
81
82 fn type_name(&self) -> &'static str {
83 type_name::<Self>()
84 }
85
86 fn doc(&self) -> &'static str {
87 ""
88 }
89
90 fn assembly_name(&self) -> &'static str {
91 env!("CARGO_PKG_NAME")
92 }
93
94 fn type_assembly_name() -> &'static str {
95 env!("CARGO_PKG_NAME")
96 }
97
98 fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
99 func(&[
100 {
101 static METADATA: FieldMetadata = FieldMetadata {
102 name: "Bone",
103 display_name: "Bone",
104 tag: "",
105 read_only: false,
106 immutable_collection: false,
107 min_value: None,
108 max_value: None,
109 step: None,
110 precision: None,
111 doc: "",
112 };
113 FieldRef {
114 metadata: &METADATA,
115 value: &self.bone,
116 }
117 },
118 {
119 static METADATA: FieldMetadata = FieldMetadata {
120 name: "PhysicalBone",
121 display_name: "Physical Bone",
122 tag: "",
123 read_only: false,
124 immutable_collection: false,
125 min_value: None,
126 max_value: None,
127 step: None,
128 precision: None,
129 doc: "",
130 };
131 FieldRef {
132 metadata: &METADATA,
133 value: &self.physical_bone,
134 }
135 },
136 {
137 static METADATA: FieldMetadata = FieldMetadata {
138 name: "Children",
139 display_name: "Children",
140 tag: "",
141 read_only: false,
142 immutable_collection: false,
143 min_value: None,
144 max_value: None,
145 step: None,
146 precision: None,
147 doc: "",
148 };
149 FieldRef {
150 metadata: &METADATA,
151 value: &self.children,
152 }
153 },
154 ])
155 }
156
157 fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
158 func(&mut [
159 {
160 static METADATA: FieldMetadata = FieldMetadata {
161 name: "Bone",
162 display_name: "Bone",
163 tag: "",
164 read_only: false,
165 immutable_collection: false,
166 min_value: None,
167 max_value: None,
168 step: None,
169 precision: None,
170 doc: "",
171 };
172 FieldMut {
173 metadata: &METADATA,
174 value: &mut self.bone,
175 }
176 },
177 {
178 static METADATA: FieldMetadata = FieldMetadata {
179 name: "PhysicalBone",
180 display_name: "Physical Bone",
181 tag: "",
182 read_only: false,
183 immutable_collection: false,
184 min_value: None,
185 max_value: None,
186 step: None,
187 precision: None,
188 doc: "",
189 };
190 FieldMut {
191 metadata: &METADATA,
192 value: &mut self.physical_bone,
193 }
194 },
195 {
196 static METADATA: FieldMetadata = FieldMetadata {
197 name: "Children",
198 display_name: "Children",
199 tag: "",
200 read_only: false,
201 immutable_collection: false,
202 min_value: None,
203 max_value: None,
204 step: None,
205 precision: None,
206 doc: "",
207 };
208 FieldMut {
209 metadata: &METADATA,
210 value: &mut self.children,
211 }
212 },
213 ])
214 }
215
216 fn into_any(self: Box<Self>) -> Box<dyn Any> {
217 self
218 }
219
220 fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
221 func(self)
222 }
223
224 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
225 func(self)
226 }
227
228 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
229 func(self)
230 }
231
232 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
233 func(self)
234 }
235
236 fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
237 let this = std::mem::replace(self, value.take()?);
238 Ok(Box::new(this))
239 }
240
241 fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
242 Some(Box::new(self.clone()))
243 }
244}
245
246impl Visit for Limb {
247 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
248 let mut guard = visitor.enter_region(name)?;
249
250 self.bone.visit("Bone", &mut guard)?;
251 self.physical_bone.visit("PhysicalBone", &mut guard)?;
252 self.children.visit("Children", &mut guard)?;
253
254 Ok(())
255 }
256}
257
258impl Limb {
259 pub fn iterate_recursive<F>(&self, func: &mut F)
262 where
263 F: FnMut(&Self),
264 {
265 func(self);
266
267 for child in self.children.iter() {
268 child.iterate_recursive(func)
269 }
270 }
271}
272
273#[derive(Clone, Reflect, Visit, Debug, Default, ComponentProvider)]
284#[reflect(derived_type = "Node")]
285#[visit(optional)]
286pub struct Ragdoll {
287 base: Base,
288 pub character_rigid_body: InheritableVariable<Handle<Node>>,
291 pub is_active: InheritableVariable<bool>,
294 pub root_limb: InheritableVariable<Limb>,
297 pub deactivate_colliders: InheritableVariable<bool>,
300 #[reflect(hidden)]
301 prev_enabled: bool,
302}
303
304impl Deref for Ragdoll {
305 type Target = Base;
306
307 fn deref(&self) -> &Self::Target {
308 &self.base
309 }
310}
311
312impl DerefMut for Ragdoll {
313 fn deref_mut(&mut self) -> &mut Self::Target {
314 &mut self.base
315 }
316}
317
318impl TypeUuidProvider for Ragdoll {
319 fn type_uuid() -> Uuid {
320 uuid!("f4441683-dcef-472d-9d7d-4adca4579107")
321 }
322}
323
324impl ConstructorProvider<Node, Graph> for Ragdoll {
325 fn constructor() -> NodeConstructor {
326 NodeConstructor::new::<Self>()
327 .with_variant("Ragdoll", |_| {
328 RagdollBuilder::new(BaseBuilder::new().with_name("Ragdoll"))
329 .build_node()
330 .into()
331 })
332 .with_group("Physics")
333 }
334}
335
336impl NodeTrait for Ragdoll {
337 fn local_bounding_box(&self) -> AxisAlignedBoundingBox {
338 self.base.local_bounding_box()
339 }
340
341 fn world_bounding_box(&self) -> AxisAlignedBoundingBox {
342 self.base.world_bounding_box()
343 }
344
345 fn id(&self) -> Uuid {
346 Self::type_uuid()
347 }
348
349 fn update(&mut self, ctx: &mut UpdateContext) {
350 let mut new_lin_vel = None;
352 let mut new_ang_vel = None;
353 if *self.is_active && !self.prev_enabled {
354 if let Some(character_rigid_body) = ctx
355 .nodes
356 .try_borrow_mut(*self.character_rigid_body)
357 .and_then(|n| n.component_mut::<RigidBody>())
358 {
359 new_lin_vel = Some(character_rigid_body.lin_vel());
360 new_ang_vel = Some(character_rigid_body.ang_vel());
361 }
362 }
363 self.prev_enabled = *self.is_active;
364
365 self.root_limb.iterate_recursive(&mut |limb| {
366 let mbc = ctx.nodes.begin_multi_borrow();
367
368 let mut need_update_transform = false;
369
370 if let Ok(mut limb_body) =
371 mbc.try_get_component_of_type_mut::<RigidBody>(limb.physical_bone)
372 {
373 if *self.is_active {
374 if let Some(lin_vel) = new_lin_vel {
376 limb_body.set_lin_vel(lin_vel);
377 }
378 if let Some(ang_vel) = new_ang_vel {
379 limb_body.set_ang_vel(ang_vel);
380 }
381
382 if limb_body.body_type() != RigidBodyType::Dynamic {
383 limb_body.set_body_type(RigidBodyType::Dynamic);
384 }
385
386 if *self.deactivate_colliders {
387 for child in limb_body.children() {
388 if let Ok(mut collider) =
389 mbc.try_get_component_of_type_mut::<Collider>(*child)
390 {
391 collider.set_is_sensor(false);
392 }
393 }
394 }
395
396 let body_transform = limb_body.global_transform();
397
398 let bone_parent = mbc.try_get(limb.bone).unwrap().parent();
400 let transform: Matrix4<f32> = mbc
401 .try_get(bone_parent)
402 .unwrap()
403 .global_transform()
404 .try_inverse()
405 .unwrap_or_else(Matrix4::identity)
406 * body_transform;
407
408 mbc.try_get_mut(limb.bone)
409 .unwrap()
410 .local_transform_mut()
411 .set_position(Vector3::new(transform[12], transform[13], transform[14]))
412 .set_pre_rotation(UnitQuaternion::identity())
413 .set_post_rotation(UnitQuaternion::identity())
414 .set_rotation(UnitQuaternion::from_matrix_eps(
415 &transform.basis(),
416 f32::EPSILON,
417 16,
418 Default::default(),
419 ));
420
421 need_update_transform = true;
422 } else {
423 limb_body.set_body_type(RigidBodyType::KinematicPositionBased);
424 limb_body.set_lin_vel(Default::default());
425 limb_body.set_ang_vel(Default::default());
426
427 if *self.deactivate_colliders {
428 for child in limb_body.children() {
429 if let Ok(mut collider) =
430 mbc.try_get_component_of_type_mut::<Collider>(*child)
431 {
432 collider.set_is_sensor(true);
433 }
434 }
435 }
436
437 let self_transform_inverse =
438 self.global_transform().try_inverse().unwrap_or_default();
439
440 if let Ok(bone) = mbc.try_get(limb.bone) {
442 let relative_transform = self_transform_inverse * bone.global_transform();
443
444 let position = Vector3::new(
445 relative_transform[12],
446 relative_transform[13],
447 relative_transform[14],
448 );
449 let rotation = UnitQuaternion::from_matrix_eps(
450 &relative_transform.basis(),
451 f32::EPSILON,
452 16,
453 Default::default(),
454 );
455 limb_body
456 .local_transform_mut()
457 .set_position(position)
458 .set_rotation(rotation);
459 }
460 }
461 };
462
463 drop(mbc);
464
465 if need_update_transform {
466 Graph::update_hierarchical_data_recursively(
469 ctx.nodes,
470 ctx.sound_context,
471 ctx.physics,
472 ctx.physics2d,
473 limb.bone,
474 );
475 }
476 });
477
478 if let Some(root_limb_body) = ctx.nodes.try_borrow(self.root_limb.bone) {
479 let position = root_limb_body.global_position();
480 if let Some(character_rigid_body) = ctx
481 .nodes
482 .try_borrow_mut(*self.character_rigid_body)
483 .and_then(|n| n.component_mut::<RigidBody>())
484 {
485 if *self.is_active {
486 character_rigid_body.set_lin_vel(Default::default());
487 character_rigid_body.set_ang_vel(Default::default());
488 character_rigid_body
489 .local_transform_mut()
490 .set_position(position);
491 character_rigid_body.set_body_type(RigidBodyType::KinematicPositionBased);
492 } else {
493 character_rigid_body.set_body_type(RigidBodyType::Dynamic);
494 }
495 }
496 }
497 }
498}
499
500pub struct RagdollBuilder {
502 base_builder: BaseBuilder,
503 character_rigid_body: Handle<Node>,
504 is_active: bool,
505 deactivate_colliders: bool,
506 root_limb: Limb,
507}
508
509impl RagdollBuilder {
510 pub fn new(base_builder: BaseBuilder) -> Self {
512 Self {
513 base_builder,
514 character_rigid_body: Default::default(),
515 is_active: true,
516 deactivate_colliders: false,
517 root_limb: Default::default(),
518 }
519 }
520
521 pub fn with_character_rigid_body(mut self, handle: Handle<Node>) -> Self {
523 self.character_rigid_body = handle;
524 self
525 }
526
527 pub fn with_active(mut self, active: bool) -> Self {
529 self.is_active = active;
530 self
531 }
532
533 pub fn with_root_limb(mut self, root_limb: Limb) -> Self {
535 self.root_limb = root_limb;
536 self
537 }
538
539 pub fn with_deactivate_colliders(mut self, value: bool) -> Self {
541 self.deactivate_colliders = value;
542 self
543 }
544
545 pub fn build_ragdoll(self) -> Ragdoll {
547 Ragdoll {
548 base: self.base_builder.build_base(),
549 character_rigid_body: self.character_rigid_body.into(),
550 is_active: self.is_active.into(),
551 root_limb: self.root_limb.into(),
552 deactivate_colliders: self.deactivate_colliders.into(),
553 prev_enabled: self.is_active,
554 }
555 }
556
557 pub fn build_node(self) -> Node {
559 Node::new(self.build_ragdoll())
560 }
561
562 pub fn build(self, graph: &mut Graph) -> Handle<Node> {
564 graph.add_node(self.build_node())
565 }
566}