use super::*;
impl World {
pub fn create_parallel_joint(&mut self, def: ParallelJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_distance_joint(&mut self, def: DistanceJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_motor_joint(&mut self, def: MotorJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_filter_joint(&mut self, def: FilterJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_prismatic_joint(&mut self, def: PrismaticJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_revolute_joint(&mut self, def: RevoluteJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_spherical_joint(&mut self, def: SphericalJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_weld_joint(&mut self, def: WeldJointDef) -> Result<JointId> {
self.create_joint(def)
}
pub fn create_wheel_joint(&mut self, def: WheelJointDef) -> Result<JointId> {
self.create_joint(def)
}
fn create_joint(&mut self, def: impl JointDefinition) -> Result<JointId> {
def.validate_definition()?;
let (body_a, body_b) = def.body_ids();
callback_state::check_not_in_callback()?;
let raw_body_a = self.state.ledger.authorize_body(body_a)?;
let raw_body_b = self.state.ledger.authorize_body(body_b)?;
check_joint_body_pair_valid(body_a, body_b)?;
let pending = self.state.ledger.reserve_joint(body_a, body_b)?;
let _guard = box3d_lock::lock();
self.check_world_valid_locked()?;
debug_checks::check_body_valid_raw(raw_body_a)?;
debug_checks::check_body_valid_raw(raw_body_b)?;
let raw = def.create_locked(self.raw());
if unsafe { ffi::b3Joint_IsValid(raw) } {
Ok(self.state.ledger.publish_joint(raw, pending))
} else {
Err(Error::NativeFailure)
}
}
pub fn destroy_joint(&mut self, joint_id: JointId, wake_attached: bool) -> Result<()> {
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3DestroyJoint(joint_id.into_raw(), wake_attached) };
drop(_guard);
self.state.ledger.retire_joint(joint_id);
Ok(())
}
pub fn joint_type(&self, joint_id: JointId) -> Result<JointType> {
let _guard = lock_joint_checked(self, joint_id)?;
JointType::from_raw(unsafe { ffi::b3Joint_GetType(joint_id.into_raw()) })
.ok_or(Error::NativeFailure)
}
pub fn joint_body_a(&self, joint_id: JointId) -> Result<BodyId> {
let _guard = lock_joint_checked(self, joint_id)?;
let raw = unsafe { ffi::b3Joint_GetBodyA(joint_id.into_raw()) };
self.state.ledger.resolve_body(raw)
}
pub fn joint_body_b(&self, joint_id: JointId) -> Result<BodyId> {
let _guard = lock_joint_checked(self, joint_id)?;
let raw = unsafe { ffi::b3Joint_GetBodyB(joint_id.into_raw()) };
self.state.ledger.resolve_body(raw)
}
pub fn set_joint_local_frame_a(&mut self, joint_id: JointId, frame: Transform) -> Result<()> {
validation::transform("joint.local_frame_a", frame)?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_SetLocalFrameA(joint_id.into_raw(), frame.into_raw()) };
Ok(())
}
pub fn joint_local_frame_a(&self, joint_id: JointId) -> Result<Transform> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(Transform::from_raw(unsafe {
ffi::b3Joint_GetLocalFrameA(joint_id.into_raw())
}))
}
pub fn set_joint_local_frame_b(&mut self, joint_id: JointId, frame: Transform) -> Result<()> {
validation::transform("joint.local_frame_b", frame)?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_SetLocalFrameB(joint_id.into_raw(), frame.into_raw()) };
Ok(())
}
pub fn joint_local_frame_b(&self, joint_id: JointId) -> Result<Transform> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(Transform::from_raw(unsafe {
ffi::b3Joint_GetLocalFrameB(joint_id.into_raw())
}))
}
pub fn set_joint_collide_connected(&mut self, joint_id: JointId, collide: bool) -> Result<()> {
let next_contact_epoch = self.state.ledger.prepare_contact_turnover()?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_SetCollideConnected(joint_id.into_raw(), collide) };
self.finish_contact_turnover_locked(next_contact_epoch);
drop(_guard);
Ok(())
}
pub fn joint_collide_connected(&self, joint_id: JointId) -> Result<bool> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetCollideConnected(joint_id.into_raw()) })
}
pub fn wake_joint_bodies(&mut self, joint_id: JointId) -> Result<()> {
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_WakeBodies(joint_id.into_raw()) };
Ok(())
}
pub fn joint_constraint_force(&self, joint_id: JointId) -> Result<Vec3> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(Vec3::from_raw(unsafe {
ffi::b3Joint_GetConstraintForce(joint_id.into_raw())
}))
}
pub fn joint_constraint_torque(&self, joint_id: JointId) -> Result<Vec3> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(Vec3::from_raw(unsafe {
ffi::b3Joint_GetConstraintTorque(joint_id.into_raw())
}))
}
pub fn joint_linear_separation(&self, joint_id: JointId) -> Result<f32> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetLinearSeparation(joint_id.into_raw()) })
}
pub fn joint_angular_separation(&self, joint_id: JointId) -> Result<f32> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetAngularSeparation(joint_id.into_raw()) })
}
pub fn set_joint_constraint_tuning(
&mut self,
joint_id: JointId,
tuning: JointTuning,
) -> Result<()> {
tuning.validate()?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe {
ffi::b3Joint_SetConstraintTuning(
joint_id.into_raw(),
tuning.hertz,
tuning.damping_ratio,
)
};
Ok(())
}
pub fn joint_constraint_tuning(&self, joint_id: JointId) -> Result<JointTuning> {
let _guard = lock_joint_checked(self, joint_id)?;
let mut hertz = 0.0;
let mut damping_ratio = 0.0;
unsafe {
ffi::b3Joint_GetConstraintTuning(joint_id.into_raw(), &mut hertz, &mut damping_ratio)
};
Ok(JointTuning::new(hertz, damping_ratio))
}
pub fn set_joint_force_threshold(&mut self, joint_id: JointId, threshold: f32) -> Result<()> {
validation::nonnegative("joint.force_threshold", threshold)?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_SetForceThreshold(joint_id.into_raw(), threshold) };
Ok(())
}
pub fn joint_force_threshold(&self, joint_id: JointId) -> Result<f32> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetForceThreshold(joint_id.into_raw()) })
}
pub fn set_joint_torque_threshold(&mut self, joint_id: JointId, threshold: f32) -> Result<()> {
validation::nonnegative("joint.torque_threshold", threshold)?;
let _guard = lock_joint_checked(self, joint_id)?;
unsafe { ffi::b3Joint_SetTorqueThreshold(joint_id.into_raw(), threshold) };
Ok(())
}
pub fn joint_torque_threshold(&self, joint_id: JointId) -> Result<f32> {
let _guard = lock_joint_checked(self, joint_id)?;
Ok(unsafe { ffi::b3Joint_GetTorqueThreshold(joint_id.into_raw()) })
}
}