Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/data/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,9 @@ fn index_twice<T>(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
} else if a == b {
Pair::One(&mut arr[max(a, b)])
} else {
// safe because a, b are in bounds and distinct
unsafe {
let ar = &mut *(arr.get_unchecked_mut(a) as *mut _);
let br = &mut *(arr.get_unchecked_mut(b) as *mut _);
Pair::Both(ar, br)
}
// can't panic because a, b are in bounds and distinct
let [ar, br] = arr.get_disjoint_mut([a, b]).unwrap();
Pair::Both(ar, br)
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/dynamics/joint/multibody_joint/multibody.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ impl Force {
}

fn as_vector(&self) -> &SVector<Real, SPATIAL_DIM> {
// SAFETY : this is safe because :
// - Force is repr(C)
// - Vector is repr(C)
// - AngVector is repr(C) or Real
// - total size in Reals is SPATIAL_DIM
unsafe { core::mem::transmute(self) }
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/dynamics/rigid_body_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ impl RigidBodyMassProps {

#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Copy, PartialEq)]
#[repr(C)]
/// The velocities of this rigid-body.
pub struct RigidBodyVelocity<T: ScalarType> {
/// The linear velocity of the rigid-body.
Expand Down Expand Up @@ -593,6 +594,11 @@ impl RigidBodyVelocity<Real> {
#[inline]
#[cfg(feature = "dim2")]
pub fn as_vector(&self) -> &na::Vector3<Real> {
// SAFETY : this is safe because :
// - RigidBodyVelocity is repr(C)
// - the vector types used are repr(C)
// - the only non vector type is Real
// - total size in Reals is 3
unsafe { core::mem::transmute(self) }
}

Expand All @@ -602,6 +608,11 @@ impl RigidBodyVelocity<Real> {
#[inline]
#[cfg(feature = "dim2")]
pub fn as_vector_mut(&mut self) -> &mut na::Vector3<Real> {
// SAFETY : this is safe because :
// - RigidBodyVelocity is repr(C)
// - the vector types used are repr(C)
// - the only non vector type is Real
// - total size in Reals is 3
unsafe { core::mem::transmute(self) }
}

Expand All @@ -611,6 +622,11 @@ impl RigidBodyVelocity<Real> {
#[inline]
#[cfg(feature = "dim3")]
pub fn as_vector(&self) -> &na::Vector6<Real> {
// SAFETY : this is safe because :
// - RigidBodyVelocity is repr(C)
// - the vector types used are repr(C)
// - the only non vector type is Real
// - total size in Reals is 6
unsafe { core::mem::transmute(self) }
}

Expand All @@ -620,6 +636,11 @@ impl RigidBodyVelocity<Real> {
#[inline]
#[cfg(feature = "dim3")]
pub fn as_vector_mut(&mut self) -> &mut na::Vector6<Real> {
// SAFETY : this is safe because :
// - RigidBodyVelocity is repr(C)
// - the vector types used are repr(C)
// - the only non vector type is Real
// - total size in Reals is 6
unsafe { core::mem::transmute(self) }
}

Expand Down
7 changes: 1 addition & 6 deletions src/dynamics/solver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ mod velocity_solver;
// TODO: SAFETY: restrict with bytemuck::Zeroable to make this safe.
pub unsafe fn reset_buffer<T>(buffer: &mut Vec<T>, len: usize) {
buffer.clear();
buffer.reserve(len);

unsafe {
// NOTE: writing zeros is faster than u8::MAX.
buffer.as_mut_ptr().write_bytes(0, len);
buffer.set_len(len);
}
buffer.resize_with(len, || unsafe { core::mem::zeroed() })
}
17 changes: 4 additions & 13 deletions src/utils/index_mut2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,7 @@ pub trait IndexMut2<I>: IndexMut<I> {
impl<T> IndexMut2<usize> for Vec<T> {
#[inline]
fn index_mut2(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
assert!(i != j, "Unable to index the same element twice.");
assert!(i < self.len() && j < self.len(), "Index out of bounds.");

unsafe {
let a = &mut *(self.get_unchecked_mut(i) as *mut _);
let b = &mut *(self.get_unchecked_mut(j) as *mut _);
(a, b)
}
<[T]>::index_mut2(self, i, j)
}
}

Expand All @@ -42,10 +35,8 @@ impl<T> IndexMut2<usize> for [T] {
assert!(i != j, "Unable to index the same element twice.");
assert!(i < self.len() && j < self.len(), "Index out of bounds.");

unsafe {
let a = &mut *(self.get_unchecked_mut(i) as *mut _);
let b = &mut *(self.get_unchecked_mut(j) as *mut _);
(a, b)
}
// cannot panic, per the above checks
let [a, b] = self.get_disjoint_mut([i, j]).unwrap();
(a, b)
}
}