diff --git a/sable_rapier/src/main/rust/rapier/src/boxes.rs b/sable_rapier/src/main/rust/rapier/src/boxes.rs index faf5a3ed..c6f86a50 100644 --- a/sable_rapier/src/main/rust/rapier/src/boxes.rs +++ b/sable_rapier/src/main/rust/rapier/src/boxes.rs @@ -81,7 +81,10 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_rem let sim_data = &mut *sim_data; let mut sable_data = scene.sable_data.write().unwrap(); - let handle = sable_data.rigid_bodies[&(id as LevelColliderID)]; + let Some(handle) = sable_data.rigid_bodies.get(&(id as LevelColliderID)) else { + return; + }; + let handle = *handle; sim_data.rigid_body_set.remove( handle, &mut sim_data.island_manager, diff --git a/sable_rapier/src/main/rust/rapier/src/contraptions.rs b/sable_rapier/src/main/rust/rapier/src/contraptions.rs index 480cab37..2cf27232 100644 --- a/sable_rapier/src/main/rust/rapier/src/contraptions.rs +++ b/sable_rapier/src/main/rust/rapier/src/contraptions.rs @@ -36,11 +36,8 @@ macro_rules! extract_jint_array { fn get_kinematic_collider_info( sable: &mut SableSceneData, id: jint, -) -> &mut ActiveLevelColliderInfo { - sable - .level_colliders - .get_mut(&(id as LevelColliderID)) - .expect("No kinematic contraption with given ID!") +) -> Option<&mut ActiveLevelColliderInfo> { + sable.level_colliders.get_mut(&(id as LevelColliderID)) } #[unsafe(no_mangle)] @@ -61,17 +58,16 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_cre let should_be_static = mount_id == -1; let mount_rigid_body = if should_be_static { - let new_body = sim_data - .rigid_body_set - .insert(RigidBodyBuilder::kinematic_position_based()); - Some(new_body) - } else { Some( - *sable_data - .rigid_bodies - .get(&(mount_id as LevelColliderID)) - .unwrap(), + sim_data + .rigid_body_set + .insert(RigidBodyBuilder::kinematic_position_based()), ) + } else { + sable_data + .rigid_bodies + .get(&(mount_id as LevelColliderID)) + .copied() }; let mount_rigid_body: RigidBodyHandle = if let Some(body) = mount_rigid_body { @@ -140,7 +136,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set let mut sim_data = scene.sim_data.write().unwrap(); let mut sable_data = scene.sable_data.write().unwrap(); - let info = get_kinematic_collider_info(&mut sable_data, id); + let Some(info) = get_kinematic_collider_info(&mut sable_data, id) else { + return; + }; let collider_handle = info.collider; let collider = sim_data.collider_set.get_mut(collider_handle); @@ -218,7 +216,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add with_handle(handle, |scene| { let mut sable_data = scene.sable_data.write().unwrap(); - let info = get_kinematic_collider_info(&mut sable_data, id); + let Some(info) = get_kinematic_collider_info(&mut sable_data, id) else { + return; + }; if let Some(chunk_map) = &mut info.chunk_map { chunk_map.insert(crate::scene::pack_section_pos(x, y, z), chunk); } @@ -240,8 +240,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_rem let sim_data = &mut *sim_data; let mut sable_data = scene.sable_data.write().unwrap(); - let info = sable_data.level_colliders.remove(&(id as LevelColliderID)); - let info = info.unwrap(); + let Some(info) = sable_data.level_colliders.remove(&(id as LevelColliderID)) else { + return; + }; sim_data.collider_set.remove( info.collider, diff --git a/sable_rapier/src/main/rust/rapier/src/joints.rs b/sable_rapier/src/main/rust/rapier/src/joints.rs index 4d99b288..9e042c87 100644 --- a/sable_rapier/src/main/rust/rapier/src/joints.rs +++ b/sable_rapier/src/main/rust/rapier/src/joints.rs @@ -329,13 +329,19 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let rb_a = if id_a == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_a as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_a as LevelColliderID)) else { + return -1; + }; + *rb }; let rb_b = if id_b == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_b as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_b as LevelColliderID)) else { + return -1; + }; + *rb }; let revolute = RevoluteJointBuilder::new( @@ -416,13 +422,19 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let rb_a = if id_a == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_a as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_a as LevelColliderID)) else { + return -1; + }; + *rb }; let rb_b = if id_b == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_b as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_b as LevelColliderID)) else { + return -1; + }; + *rb }; let quat = Quat::from_xyzw( @@ -508,13 +520,19 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let rb_a = if id_a == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_a as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_a as LevelColliderID)) else { + return -1; + }; + *rb }; let rb_b = if id_b == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_b as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_b as LevelColliderID)) else { + return -1; + }; + *rb }; let mut joint = GenericJointBuilder::new(JointAxesMask::empty()).softness( @@ -602,13 +620,19 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let rb_a = if id_a == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_a as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_a as LevelColliderID)) else { + return -1; + }; + *rb }; let rb_b = if id_b == -1 { scene.ground_handle.unwrap() } else { - sable_data.rigid_bodies[&(id_b as LevelColliderID)] + let Some(rb) = sable_data.rigid_bodies.get(&(id_b as LevelColliderID)) else { + return -1; + }; + *rb }; let locked_axes = JointAxesMask::from_bits_truncate(locked_axes_mask as u8); diff --git a/sable_rapier/src/main/rust/rapier/src/lib.rs b/sable_rapier/src/main/rust/rapier/src/lib.rs index 2d224733..4853496a 100644 --- a/sable_rapier/src/main/rust/rapier/src/lib.rs +++ b/sable_rapier/src/main/rust/rapier/src/lib.rs @@ -282,12 +282,9 @@ pub fn get_rigid_body_mut<'a>( sim: &'a mut SimulationSceneData, sable_data: &SableSceneData, id: LevelColliderID, -) -> &'a mut RigidBody { - let handle = sable_data - .rigid_bodies - .get(&id) - .expect("No rigid body for id"); - &mut sim.rigid_body_set[*handle] +) -> Option<&'a mut RigidBody> { + let handle = sable_data.rigid_bodies.get(&id)?; + sim.rigid_body_set.get_mut(*handle) } #[inline(always)] @@ -295,12 +292,9 @@ pub fn get_rigid_body<'a>( sim: &'a SimulationSceneData, sable_data: &SableSceneData, id: LevelColliderID, -) -> &'a RigidBody { - let handle = sable_data - .rigid_bodies - .get(&id) - .expect("No rigid body for id"); - &sim.rigid_body_set[*handle] +) -> Option<&'a RigidBody> { + let handle = sable_data.rigid_bodies.get(&id)?; + sim.rigid_body_set.get(*handle) } #[unsafe(no_mangle)] @@ -527,18 +521,22 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_get let sable_data = scene.sable_data.read().unwrap(); let sim_data = scene.sim_data.read().unwrap(); - let rb: &RigidBody = - &sim_data.rigid_body_set[sable_data.rigid_bodies[&(id as LevelColliderID)]]; - - let arr: [jdouble; 7] = [ - rb.translation().x as jdouble, - rb.translation().y as jdouble, - rb.translation().z as jdouble, - rb.rotation().x as jdouble, - rb.rotation().y as jdouble, - rb.rotation().z as jdouble, - rb.rotation().w as jdouble, - ]; + let arr: [jdouble; 7] = match sable_data + .rigid_bodies + .get(&(id as LevelColliderID)) + .and_then(|body| sim_data.rigid_body_set.get(*body)) + { + Some(rb) => [ + rb.translation().x as jdouble, + rb.translation().y as jdouble, + rb.translation().z as jdouble, + rb.rotation().x as jdouble, + rb.rotation().y as jdouble, + rb.rotation().z as jdouble, + rb.rotation().w as jdouble, + ], + None => [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], + }; env.set_double_array_region(&store, 0, &arr).unwrap(); }) @@ -558,10 +556,12 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set ) { with_handle(handle, |scene| { let mut sable_data = scene.sable_data.write().unwrap(); - let info = sable_data + let Some(info) = sable_data .level_colliders .get_mut(&(id as LevelColliderID)) - .unwrap(); + else { + return; + }; info.center_of_mass = Some(DVec3::new(x, y, z)); let mut sim_data = scene.sim_data.write().unwrap(); update_collider_aabb(&mut sim_data, info); @@ -593,7 +593,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set .. } = &mut *sable_data; - let info = level_colliders.get_mut(&(id as LevelColliderID)).unwrap(); + let Some(info) = level_colliders.get_mut(&(id as LevelColliderID)) else { + return; + }; info.set_local_bounds( IVec3::new(min_x, min_y, min_z), IVec3::new(max_x, max_y, max_z), @@ -691,10 +693,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_rem let mut sable_data = scene.sable_data.write().unwrap(); sable_data.level_colliders.remove(&(id as LevelColliderID)); - let handle = sable_data - .rigid_bodies - .remove(&(id as LevelColliderID)) - .expect("No rigid body for id"); + let Some(handle) = sable_data.rigid_bodies.remove(&(id as LevelColliderID)) else { + return; + }; let mut sim_data = scene.sim_data.write().unwrap(); @@ -803,9 +804,11 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let chunk = main_level_chunks.get(&pack_section_pos(x, y, z)).unwrap(); if global == 0 { if object_id != -1 { - let body = level_colliders + let Some(body) = level_colliders .get_mut(&(object_id as LevelColliderID)) - .unwrap(); + else { + return; + }; body.insert_chunk(chunk, x, y, z, collider_map); } @@ -1112,7 +1115,13 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let rb = &mut sim_data.rigid_body_set[sable_data.rigid_bodies[&(id as LevelColliderID)]]; + let Some(rb) = sable_data + .rigid_bodies + .get(&(id as LevelColliderID)) + .and_then(|body| sim_data.rigid_body_set.get_mut(*body)) + else { + return; + }; rb.set_additional_mass_properties( MassProperties::with_inertia_matrix(Vec3::ZERO, mass as Real, inertia_tensor.into()), @@ -1142,7 +1151,13 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_tel let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let rb = &mut sim_data.rigid_body_set[sable_data.rigid_bodies[&(id as LevelColliderID)]]; + let Some(rb) = sable_data + .rigid_bodies + .get(&(id as LevelColliderID)) + .and_then(|body| sim_data.rigid_body_set.get_mut(*body)) + else { + return; + }; let mut pose = *rb.position(); pose.translation = Vec3::new(x as Real, y as Real, z as Real); @@ -1164,7 +1179,13 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_wak with_handle(handle, |scene| { let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let rb = &mut sim_data.rigid_body_set[sable_data.rigid_bodies[&(id as LevelColliderID)]]; + let Some(rb) = sable_data + .rigid_bodies + .get(&(id as LevelColliderID)) + .and_then(|body| sim_data.rigid_body_set.get_mut(*body)) + else { + return; + }; rb.wake_up(true); }) } @@ -1188,7 +1209,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add with_handle(handle, |scene| { let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let rb = get_rigid_body_mut(&mut sim_data, &sable_data, id as LevelColliderID); + let Some(rb) = get_rigid_body_mut(&mut sim_data, &sable_data, id as LevelColliderID) else { + return; + }; if wake_up == 0 && rb.is_sleeping() { return; @@ -1288,10 +1311,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_app let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let body = sable_data - .rigid_bodies - .get(&(id as LevelColliderID)) - .unwrap(); + let Some(body) = sable_data.rigid_bodies.get(&(id as LevelColliderID)) else { + return; + }; let rb = &mut sim_data.rigid_body_set[*body]; if wake_up == 0 && rb.is_sleeping() { @@ -1333,10 +1355,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_app let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let body = sable_data - .rigid_bodies - .get(&(id as LevelColliderID)) - .unwrap(); + let Some(body) = sable_data.rigid_bodies.get(&(id as LevelColliderID)) else { + return; + }; let rb = &mut sim_data.rigid_body_set[*body]; if wake_up == 0 && rb.is_sleeping() { @@ -1370,10 +1391,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_get let sable_data = scene.sable_data.read().unwrap(); let sim_data = scene.sim_data.read().unwrap(); - let body = sable_data - .rigid_bodies - .get(&(id as LevelColliderID)) - .unwrap(); + let Some(body) = sable_data.rigid_bodies.get(&(id as LevelColliderID)) else { + return; + }; let rb = &sim_data.rigid_body_set[*body]; let vel = rb.linvel(); @@ -1402,10 +1422,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_get let sable_data = scene.sable_data.read().unwrap(); let sim_data = scene.sim_data.read().unwrap(); - let body = sable_data - .rigid_bodies - .get(&(id as LevelColliderID)) - .unwrap(); + let Some(body) = sable_data.rigid_bodies.get(&(id as LevelColliderID)) else { + return; + }; let rb = &sim_data.rigid_body_set[*body]; let vel = rb.angvel(); diff --git a/sable_rapier/src/main/rust/rapier/src/rope.rs b/sable_rapier/src/main/rust/rapier/src/rope.rs index 84a31010..7680df75 100644 --- a/sable_rapier/src/main/rust/rapier/src/rope.rs +++ b/sable_rapier/src/main/rust/rapier/src/rope.rs @@ -51,8 +51,11 @@ pub fn tick(scene: &PhysicsScene) { for (id, rope) in sable_data.rope_map.ropes.iter() { if let Some(attachment) = &rope.start_attachment { - if !sim.impulse_joint_set.contains(attachment.joint) { - dead_start_attachments.push(id.clone()); + let endpoint_gone = attachment + .sub_level_id + .is_some_and(|id_b| !sable_data.level_colliders.contains_key(&id_b)); + if !sim.impulse_joint_set.contains(attachment.joint) || endpoint_gone { + dead_start_attachments.push(*id); } else { let local_anchor = attachment.location - if let Some(id_b) = attachment.sub_level_id { @@ -71,8 +74,11 @@ pub fn tick(scene: &PhysicsScene) { } if let Some(attachment) = &rope.end_attachment { - if !sim.impulse_joint_set.contains(attachment.joint) { - dead_end_attachments.push(id.clone()); + let endpoint_gone = attachment + .sub_level_id + .is_some_and(|id_b| !sable_data.level_colliders.contains_key(&id_b)); + if !sim.impulse_joint_set.contains(attachment.joint) || endpoint_gone { + dead_end_attachments.push(*id); } else { let local_anchor = attachment.location - if let Some(id_b) = attachment.sub_level_id { @@ -265,7 +271,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_que let sable_data = scene.sable_data.read().unwrap(); let sim_data = scene.sim_data.read().unwrap(); - let strand = sable_data.rope_map.ropes.get(&(id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.get(&(id as usize)) else { + return env.new_double_array(0).unwrap(); + }; let flattened: Vec = strand .points @@ -303,7 +311,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_rem let mut sim_data = scene.sim_data.write().unwrap(); let sim_data = &mut *sim_data; - let strand = sable_data.rope_map.ropes.remove(&(id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.remove(&(id as usize)) else { + return; + }; for handle in strand.points { sim_data.rigid_body_set.remove( handle, @@ -332,7 +342,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set let mut sable_data = scene.sable_data.write().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let strand = sable_data.rope_map.ropes.get_mut(&(id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.get_mut(&(id as usize)) else { + return; + }; strand.first_joint_length = length as Real; let first_joint = &mut sim_data @@ -364,7 +376,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_rem let mut sim_data = scene.sim_data.write().unwrap(); let sim_data = &mut *sim_data; - let strand = sable_data.rope_map.ropes.get_mut(&(id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.get_mut(&(id as usize)) else { + return; + }; let point = strand.points.remove(0); strand.joints.remove(0); sim_data.rigid_body_set.remove( @@ -415,7 +429,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add let mut sable_data = scene.sable_data.write().unwrap(); let universal_drag = scene.universal_drag; - let strand = sable_data.rope_map.ropes.get_mut(&(id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.get_mut(&(id as usize)) else { + return; + }; let point_radius = strand.point_radius; // set joint that will no longer be the first @@ -464,7 +480,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_wak let sable_data = scene.sable_data.read().unwrap(); let mut sim_data = scene.sim_data.write().unwrap(); - let strand = sable_data.rope_map.ropes.get(&(rope_id as usize)).unwrap(); + let Some(strand) = sable_data.rope_map.ropes.get(&(rope_id as usize)) else { + return; + }; for point in &strand.points { sim_data @@ -501,7 +519,9 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set .. } = &mut *sable_data; - let strand = rope_map.ropes.get_mut(&(rope_id as usize)).unwrap(); + let Some(strand) = rope_map.ropes.get_mut(&(rope_id as usize)) else { + return; + }; let rope_body = if end > 0 { strand.points.last() @@ -512,9 +532,10 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_set let sub_level_body = if sub_level_id == -1 { ground_handle } else { - *rigid_bodies - .get(&(sub_level_id as LevelColliderID)) - .unwrap() + let Some(rb) = rigid_bodies.get(&(sub_level_id as LevelColliderID)) else { + return; + }; + *rb }; let joint = RopeJointBuilder::new(0.0)