box3d_rust/shape/
geometry_set.rs1use super::lifecycle::{
9 compute_shape_margin, destroy_shape_allocation_for_shape_change, get_shape,
10};
11use super::mutators::reset_proxy;
12use super::ShapeGeometry;
13use crate::geometry::{Capsule, Sphere};
14use crate::hull::{is_valid_hull, HullData};
15use crate::id::ShapeId;
16use crate::world::World;
17use std::rc::Rc;
18
19pub fn shape_get_sphere(world: &World, shape_id: ShapeId) -> Sphere {
21 let index = get_shape(world, shape_id);
22 match &world.shapes[index as usize].geometry {
23 ShapeGeometry::Sphere(sphere) => *sphere,
24 _ => {
25 debug_assert!(false, "shape is not a sphere");
26 Sphere::default()
27 }
28 }
29}
30
31pub fn shape_get_capsule(world: &World, shape_id: ShapeId) -> Capsule {
33 let index = get_shape(world, shape_id);
34 match &world.shapes[index as usize].geometry {
35 ShapeGeometry::Capsule(capsule) => *capsule,
36 _ => {
37 debug_assert!(false, "shape is not a capsule");
38 Capsule::default()
39 }
40 }
41}
42
43pub fn shape_set_sphere(world: &mut World, shape_id: ShapeId, sphere: &Sphere) {
45 crate::recording::with_recording(world, |rec| {
46 rec.write_shape_set_sphere(shape_id, *sphere);
47 });
48 debug_assert!(!world.locked);
49 if world.locked {
50 return;
51 }
52
53 world.locked = true;
54
55 let index = get_shape(world, shape_id);
56 destroy_shape_allocation_for_shape_change(world, index);
57
58 {
59 let shape = &mut world.shapes[index as usize];
60 shape.geometry = ShapeGeometry::Sphere(*sphere);
61 shape.aabb_margin = compute_shape_margin(shape);
62 }
63
64 let wake_bodies = true;
66 let destroy_proxy = true;
67 reset_proxy(world, index, wake_bodies, destroy_proxy);
68
69 world.locked = false;
70}
71
72pub fn shape_set_capsule(world: &mut World, shape_id: ShapeId, capsule: &Capsule) {
74 crate::recording::with_recording(world, |rec| {
75 rec.write_shape_set_capsule(shape_id, *capsule);
76 });
77 debug_assert!(!world.locked);
78 if world.locked {
79 return;
80 }
81
82 world.locked = true;
83
84 let index = get_shape(world, shape_id);
85 destroy_shape_allocation_for_shape_change(world, index);
86
87 {
88 let shape = &mut world.shapes[index as usize];
89 shape.geometry = ShapeGeometry::Capsule(*capsule);
90 shape.aabb_margin = compute_shape_margin(shape);
91 }
92
93 let wake_bodies = true;
94 let destroy_proxy = true;
95 reset_proxy(world, index, wake_bodies, destroy_proxy);
96
97 world.locked = false;
98}
99
100pub fn shape_set_hull(world: &mut World, shape_id: ShapeId, hull: &HullData) {
105 debug_assert!(is_valid_hull(hull));
106 debug_assert!(hull.hash != 0);
107
108 debug_assert!(!world.locked);
109 if world.locked {
110 return;
111 }
112
113 world.locked = true;
114
115 let index = get_shape(world, shape_id);
116
117 let data = world.hull_database.add(hull);
120
121 if let ShapeGeometry::Hull(existing) = &world.shapes[index as usize].geometry {
123 if Rc::ptr_eq(existing, &data) {
124 drop(data);
126 world.locked = false;
127 return;
128 }
129 }
130
131 destroy_shape_allocation_for_shape_change(world, index);
132
133 {
134 let shape = &mut world.shapes[index as usize];
135 shape.geometry = ShapeGeometry::Hull(data);
136 shape.aabb_margin = compute_shape_margin(shape);
137 }
138
139 let wake_bodies = true;
140 let destroy_proxy = true;
141 reset_proxy(world, index, wake_bodies, destroy_proxy);
142
143 world.locked = false;
144}