use super::lifecycle::{
compute_shape_margin, destroy_shape_allocation_for_shape_change, get_shape,
};
use super::mutators::reset_proxy;
use super::ShapeGeometry;
use crate::geometry::{Capsule, Sphere};
use crate::hull::{is_valid_hull, HullData};
use crate::id::ShapeId;
use crate::world::World;
use std::rc::Rc;
pub fn shape_get_sphere(world: &World, shape_id: ShapeId) -> Sphere {
let index = get_shape(world, shape_id);
match &world.shapes[index as usize].geometry {
ShapeGeometry::Sphere(sphere) => *sphere,
_ => {
debug_assert!(false, "shape is not a sphere");
Sphere::default()
}
}
}
pub fn shape_get_capsule(world: &World, shape_id: ShapeId) -> Capsule {
let index = get_shape(world, shape_id);
match &world.shapes[index as usize].geometry {
ShapeGeometry::Capsule(capsule) => *capsule,
_ => {
debug_assert!(false, "shape is not a capsule");
Capsule::default()
}
}
}
pub fn shape_set_sphere(world: &mut World, shape_id: ShapeId, sphere: &Sphere) {
crate::recording::with_recording(world, |rec| {
rec.write_shape_set_sphere(shape_id, *sphere);
});
debug_assert!(!world.locked);
if world.locked {
return;
}
world.locked = true;
let index = get_shape(world, shape_id);
destroy_shape_allocation_for_shape_change(world, index);
{
let shape = &mut world.shapes[index as usize];
shape.geometry = ShapeGeometry::Sphere(*sphere);
shape.aabb_margin = compute_shape_margin(shape);
}
let wake_bodies = true;
let destroy_proxy = true;
reset_proxy(world, index, wake_bodies, destroy_proxy);
world.locked = false;
}
pub fn shape_set_capsule(world: &mut World, shape_id: ShapeId, capsule: &Capsule) {
crate::recording::with_recording(world, |rec| {
rec.write_shape_set_capsule(shape_id, *capsule);
});
debug_assert!(!world.locked);
if world.locked {
return;
}
world.locked = true;
let index = get_shape(world, shape_id);
destroy_shape_allocation_for_shape_change(world, index);
{
let shape = &mut world.shapes[index as usize];
shape.geometry = ShapeGeometry::Capsule(*capsule);
shape.aabb_margin = compute_shape_margin(shape);
}
let wake_bodies = true;
let destroy_proxy = true;
reset_proxy(world, index, wake_bodies, destroy_proxy);
world.locked = false;
}
pub fn shape_set_hull(world: &mut World, shape_id: ShapeId, hull: &HullData) {
debug_assert!(is_valid_hull(hull));
debug_assert!(hull.hash != 0);
debug_assert!(!world.locked);
if world.locked {
return;
}
world.locked = true;
let index = get_shape(world, shape_id);
let data = world.hull_database.add(hull);
if let ShapeGeometry::Hull(existing) = &world.shapes[index as usize].geometry {
if Rc::ptr_eq(existing, &data) {
drop(data);
world.locked = false;
return;
}
}
destroy_shape_allocation_for_shape_change(world, index);
{
let shape = &mut world.shapes[index as usize];
shape.geometry = ShapeGeometry::Hull(data);
shape.aabb_margin = compute_shape_margin(shape);
}
let wake_bodies = true;
let destroy_proxy = true;
reset_proxy(world, index, wake_bodies, destroy_proxy);
world.locked = false;
}