aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynamics')
-rw-r--r--src/dynamics/island_set.rs383
-rw-r--r--src/dynamics/island_set2.rs332
-rw-r--r--src/dynamics/mod.rs4
3 files changed, 233 insertions, 486 deletions
diff --git a/src/dynamics/island_set.rs b/src/dynamics/island_set.rs
index a0da207..71dc9eb 100644
--- a/src/dynamics/island_set.rs
+++ b/src/dynamics/island_set.rs
@@ -1,114 +1,69 @@
+use crate::data::Coarena;
use crate::dynamics::{RigidBody, RigidBodyHandle, RigidBodySet};
-use crate::geometry::NarrowPhase;
+use crate::geometry::{ColliderSet, NarrowPhase};
use crate::utils;
-use downcast_rs::__std::collections::VecDeque;
+use std::collections::VecDeque;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub struct Island {
bodies: Vec<RigidBodyHandle>,
-
- // Number of bodies that are awake on this island.
- // If this is equal to zero, ten the whole island is asleep.
- wake_up_count: usize,
- // Index in the island_set.active_islands vector.
- active_island_id: usize,
- dirty: bool,
}
impl Island {
pub fn new() -> Self {
- Self {
- bodies: vec![],
- wake_up_count: 0,
- active_island_id: crate::INVALID_USIZE,
- dirty: false,
- }
+ Self { bodies: vec![] }
}
pub fn len(&self) -> usize {
self.bodies.len()
}
- pub fn is_sleeping(&self) -> bool {
- self.wake_up_count == 0
- }
-
- pub fn active_island_id(&self) -> usize {
- self.active_island_id
- }
-
pub fn bodies(&self) -> &[RigidBodyHandle] {
- &self.bodies[..]
+ &self.bodies
}
}
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub struct IslandSet {
- active_islands: Vec<usize>,
+ // We can't store this in the rigid-bodies because that would
+ // cause borrowing issues during the traversal.
+ traversal_body_timestamps: Coarena<u64>,
islands: Vec<Island>,
- to_update: VecDeque<usize>,
+ active_island: usize,
+ islands_to_extract: VecDeque<RigidBodyHandle>,
+ islands_extraction_queue: Vec<RigidBodyHandle>,
+ // NOTE: this value must never be 0, otherwise some
+ // invariants used during the traversal can break.
+ traversal_timestamp: u64,
}
impl IslandSet {
pub fn new() -> Self {
IslandSet {
- active_islands: vec![],
- islands: vec![],
- to_update: VecDeque::new(),
+ traversal_body_timestamps: Coarena::new(),
+ islands: vec![Island::new()],
+ active_island: 0,
+ islands_to_extract: VecDeque::new(),
+ islands_extraction_queue: vec![],
+ traversal_timestamp: 1,
}
}
- pub fn islands(&self) -> &[Island] {
- &self.islands[..]
- }
-
pub fn num_active_islands(&self) -> usize {
- self.active_islands.len()
- }
-
- pub fn active_island(&self, i: usize) -> &Island {
- &self.islands[self.active_islands[i]]
- }
-
- pub fn active_bodies<'a>(&'a self) -> impl Iterator<Item = RigidBodyHandle> + 'a {
- let islands = &self.islands;
- self.active_islands
- .iter()
- .copied()
- .flat_map(move |i| islands[i].bodies.iter())
- .copied()
+ 1
}
- pub fn contact_stopped(
- &mut self,
- bodies: &RigidBodySet,
- h1: RigidBodyHandle,
- _h2: RigidBodyHandle,
- ) {
- // // NOTE: we don't actually need h2 because they are both on the same island anyway.
- // // Yet we keep the `h2` argument to show that this function properly take into account
- // // both bodies.
- // if let Some(island_id) = bodies.get(h1).map(|b| b.island_id) {
- // if let Some(island) = self.islands.get_mut(island_id) {
- // if !island.dirty {
- // island.dirty = true;
- // self.to_update.push_back(island_id);
- // }
- // }
- // }
+ pub fn is_island_sleeping(&self, island_id: usize) -> bool {
+ island_id != self.active_island
}
- pub fn incremental_update(&mut self, narrow_phase: &NarrowPhase) {
- // if let Some(island) = self.to_update.pop_front() {
- // // Next island to update.
- // }
+ pub fn active_bodies(&self) -> &[RigidBodyHandle] {
+ &self.islands[self.active_island].bodies
}
- pub fn is_island_sleeping(&self, island_id: usize) -> bool {
- self.islands[island_id].is_sleeping()
- }
+ pub fn incremental_update(&mut self, narrow_phase: &NarrowPhase) {}
pub fn add_rigid_body(&mut self, handle: RigidBodyHandle, body: &mut RigidBody) {
assert_eq!(body.island_id, crate::INVALID_USIZE);
@@ -117,85 +72,239 @@ impl IslandSet {
return;
}
- let new_island_id = handle.into_raw_parts().0;
+ self.traversal_body_timestamps
+ .ensure_element_exists(handle.0, 0);
- if self.islands.len() <= new_island_id {
- self.islands.resize(new_island_id + 1, Island::new());
+ if body.can_sleep() {
+ body.island_id = self.islands.len();
+ body.island_offset = 0;
+ self.islands.push(Island {
+ bodies: vec![handle],
+ })
+ } else {
+ let mut active_island = &mut self.islands[self.active_island];
+ body.island_id = self.active_island;
+ body.island_offset = active_island.bodies.len();
+ active_island.bodies.push(handle);
}
+ }
- body.island_id = new_island_id;
- body.island_offset = self.islands[new_island_id].bodies.len();
- self.islands[new_island_id].bodies.push(handle);
+ pub fn contact_started(
+ &mut self,
+ bodies: &mut RigidBodySet,
+ mut h1: RigidBodyHandle,
+ mut h2: RigidBodyHandle,
+ ) {
+ let island1 = bodies[h1].island_id;
+ let island2 = bodies[h2].island_id;
- // NOTE: `body_sleep_state_changed` must be called afterwards.
+ self.wake_up_island(bodies, island1);
+ self.wake_up_island(bodies, island2);
}
- pub fn body_sleep_state_changed(&mut self, body: &RigidBody) {
- // Non-dynamic bodies never take part in the island computation
- // since they don't transmit any forces.
- if !body.is_dynamic() {
- return;
+ pub fn body_sleep_state_changed(&mut self, bodies: &mut RigidBodySet, handle: RigidBodyHandle) {
+ let body = &mut bodies[handle];
+ let island_id = body.island_id;
+
+ if island_id == crate::INVALID_USIZE {
+ self.add_rigid_body(handle, body);
+ } else if island_id == self.active_island && body.can_sleep() {
+ // The body is sleeping now.
+ self.islands_to_extract.push_back(handle);
+ } else if island_id != self.active_island && !body.can_sleep() {
+ // The body is awake now.
+ self.wake_up_island(bodies, island_id);
}
+ }
- let island = &mut self.islands[body.island_id];
-
- if body.can_sleep() {
- island.wake_up_count -= 1;
+ #[inline(always)]
+ fn push_contacting_bodies(
+ handle: RigidBodyHandle,
+ bodies: &mut RigidBodySet,
+ colliders: &ColliderSet,
+ narrow_phase: &NarrowPhase,
+ queue: &mut Vec<RigidBodyHandle>,
+ traversal_body_timestamps: &mut Coarena<u64>,
+ first_traversal_timestamp: u64,
+ traversal_timestamp: u64,
+ ) -> bool {
+ for collider_handle in &bodies[handle].colliders {
+ if let Some(contacts) = narrow_phase.contacts_with(*collider_handle) {
+ for inter in contacts {
+ let other = crate::utils::select_other((inter.0, inter.1), *collider_handle);
+ let other_body_handle = colliders[other].parent;
+ let other_body = &bodies[other_body_handle];
+
+ if other_body.is_dynamic() {
+ if !other_body.can_sleep() {
+ return false;
+ }
+
+ let other_body_timestamp =
+ &mut traversal_body_timestamps[other_body_handle.0];
+
+ if *other_body_timestamp >= first_traversal_timestamp
+ && *other_body_timestamp < traversal_timestamp
+ {
+ // We already saw this body during another traversal this frame.
+ // So we don't need to continue any further.
+ return false;
+ }
+
+ if *other_body_timestamp != traversal_timestamp {
+ *other_body_timestamp = traversal_timestamp;
+ queue.push(other_body_handle);
+ }
+ }
+ }
+ }
+ }
- if island.wake_up_count == 0 {
- // The island is sleeping now.
- // Remove it from the active set.
- let active_island_id_to_remove = island.active_island_id;
- island.active_island_id = crate::INVALID_USIZE;
- self.active_islands.swap_remove(active_island_id_to_remove);
+ true
+ }
- if let Some(moved_island) = self.active_islands.get(active_island_id_to_remove) {
- self.islands[*moved_island].active_island_id = active_island_id_to_remove;
+ pub fn update_sleeping_islands(
+ &mut self,
+ bodies: &mut RigidBodySet,
+ colliders: &mut ColliderSet,
+ narrow_phase: &NarrowPhase,
+ ) {
+ let first_traversal_timestamp = self.traversal_timestamp + 1;
+ let mut island_found = false;
+
+ while let Some(handle) = self.islands_to_extract.pop_front() {
+ self.traversal_timestamp += 1;
+ island_found = self.extract_sleeping_island(
+ bodies,
+ colliders,
+ narrow_phase,
+ handle,
+ first_traversal_timestamp,
+ ) || island_found;
+
+ // Make sure our `traversal_timestamp` remains correct
+ // even if it overflows (can happen in very long-running
+ // simulations).
+ if self.traversal_timestamp == u64::MAX - 1 {
+ // Stop the work now because the overflowing timestamp
+ // will cause issues with the traversal. Forcibly reset all
+ // the timestamps and continue next frame.
+ for body in bodies.iter_mut_internal() {
+ body.1.traversal_timestamp = 0;
}
+ self.traversal_timestamp = 1;
+ break;
}
- } else {
- if island.wake_up_count == 0 {
- // The islands is waking up.
- // Add it to the active set.
- assert_eq!(island.active_island_id, crate::INVALID_USIZE);
- island.active_island_id = self.active_islands.len();
- self.active_islands.push(body.island_id);
- }
-
- island.wake_up_count += 1;
}
- if self.active_islands.len() == 0 {
- dbg!("Hurray!");
+ if island_found {
+ // Now we need to remove from the active set all the bodies
+ // we moved to a sleeping island.
+ let mut i = 0;
+ let mut new_len = 0;
+ let active_island = &mut self.islands[self.active_island];
+
+ while i < active_island.bodies.len() {
+ let handle = active_island.bodies[i];
+ let body = &mut bodies[handle];
+
+ if body.island_id == self.active_island {
+ // This body still belongs to this island.
+ // Update its offset.
+ body.island_offset = new_len;
+ active_island.bodies[new_len] = handle;
+ new_len += 1;
+ }
+
+ i += 1;
+ }
+
+ active_island.bodies.truncate(new_len);
}
}
- pub fn contact_started(
+ fn extract_sleeping_island(
&mut self,
bodies: &mut RigidBodySet,
- mut h1: RigidBodyHandle,
- mut h2: RigidBodyHandle,
- ) {
- let body1 = &bodies[h1];
- let body2 = &bodies[h2];
+ colliders: &mut ColliderSet,
+ narrow_phase: &NarrowPhase,
+ handle: RigidBodyHandle,
+ first_traversal_timestamp: u64,
+ ) -> bool {
+ // Attempt to extract a sleeping island by traversing the
+ // contact graph starting with the given rigid-body.
+ if let Some(body) = bodies.get(handle) {
+ if body.is_dynamic() && body.can_sleep() {
+ // Perform a breadth-first search of the contact graph starting
+ // with this body. We stop the search when an active body is
+ // found (meaning that the island cannot sleep), or if we
+ // extracted the whole island.
+ // We do a breadth-first search in order to increase our chances
+ // to find a non-sleeping body quickly: if this body just started
+ // sleeping, chances are that a non-sleeping body is close.
+ self.islands_extraction_queue.clear();
+ self.islands_extraction_queue.push(handle);
+ self.traversal_body_timestamps[handle.0] = self.traversal_timestamp;
+ let mut i = 0;
+
+ while i < self.islands_extraction_queue.len() {
+ let handle = self.islands_extraction_queue[i];
+
+ let continue_traversal = Self::push_contacting_bodies(
+ handle,
+ bodies,
+ colliders,
+ narrow_phase,
+ &mut self.islands_extraction_queue,
+ &mut self.traversal_body_timestamps,
+ first_traversal_timestamp,
+ self.traversal_timestamp,
+ );
+
+ if !continue_traversal {
+ // This island cannot sleep yet.
+ return false;
+ }
+
+ i += 1;
+ }
- if !body1.is_dynamic() || !body2.is_dynamic() {
- // Non-dynamic bodies don't transmit forces.
- // So we can ignore their contact for island computation.
- return;
+ // If we reached this point, then we successfully found a sleeping island.
+ for (k, handle) in self.islands_extraction_queue.iter().enumerate() {
+ let body = &mut bodies[*handle];
+ body.island_id = self.islands.len();
+ body.island_offset = k;
+ }
+
+ // FIXME: recycle old islands.
+ self.islands.push(Island {
+ bodies: std::mem::replace(&mut self.islands_extraction_queue, Vec::new()),
+ });
+
+ return true;
+ }
}
- assert_ne!(body1.island_id, crate::INVALID_USIZE);
- assert_ne!(body2.island_id, crate::INVALID_USIZE);
+ false
+ }
+
+ pub fn wake_up_island(&mut self, bodies: &mut RigidBodySet, island_id: usize) {
+ if island_id == crate::INVALID_USIZE {
+ return;
+ }
- let mut island_id1 = body1.island_id;
- let mut island_id2 = body2.island_id;
+ let mut island_id1 = self.active_island;
+ let mut island_id2 = island_id;
if island_id1 != island_id2 {
let (mut island1, mut island2) =
utils::get2_mut(&mut self.islands, island_id1, island_id2);
// Make sure island1 points to the biggest island.
+ // The typical scenario is that only a few object are awaking
+ // one big island. So in this typical scenario, we actually want
+ // to merge the active island into the sleeping island, and then
+ // mark the sleeping island as active.
if island2.len() > island1.len() {
std::mem::swap(&mut island1, &mut island2);
std::mem::swap(&mut island_id1, &mut island_id2);
@@ -213,37 +322,7 @@ impl IslandSet {
// Islands can get big so let's save some memory.
island2.bodies = vec![];
-
- // Update the wake-up count and determine if the island is awake.
- // Note that if both `wake_up_count` are zero, then the island
- // won't end up in the active island set (which is what we want).
- let island2_was_sleeping = island2.is_sleeping();
-
- if island1.is_sleeping() && !island2_was_sleeping {
- // Add the first island to the active island set.
- assert_eq!(island1.active_island_id, crate::INVALID_USIZE);
- island1.active_island_id = self.active_islands.len();
- self.active_islands.push(island_id1);
- }
-
- island1.wake_up_count += island2.wake_up_count;
- island2.wake_up_count = 0;
-
- assert!(island1.wake_up_count != 0 || island1.active_island_id == crate::INVALID_USIZE);
-
- if !island2_was_sleeping {
- // The second island will be emptied, so we
- // can remove it from the set of active islands.
- let active_island_id_to_remove = island2.active_island_id;
- island2.active_island_id = crate::INVALID_USIZE;
- self.active_islands.swap_remove(active_island_id_to_remove);
-
- if let Some(moved_island) = self.active_islands.get(active_island_id_to_remove) {
- self.islands[*moved_island].active_island_id = active_island_id_to_remove;
- }
- } else {
- assert_eq!(island2.active_island_id, crate::INVALID_USIZE);
- }
+ self.active_island = island_id1;
}
}
}
diff --git a/src/dynamics/island_set2.rs b/src/dynamics/island_set2.rs
deleted file mode 100644
index 098171a..0000000
--- a/src/dynamics/island_set2.rs
+++ /dev/null
@@ -1,332 +0,0 @@
-use crate::data::Coarena;
-use crate::dynamics::{RigidBody, RigidBodyHandle, RigidBodySet};
-use crate::geometry::{ColliderSet, NarrowPhase};
-use crate::utils;
-use std::collections::VecDeque;
-
-#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
-#[derive(Clone)]
-pub struct Island {
- bodies: Vec<RigidBodyHandle>,
-}
-
-impl Island {
- pub fn new() -> Self {
- Self { bodies: vec![] }
- }
-
- pub fn len(&self) -> usize {
- self.bodies.len()
- }
-
- pub fn is_sleeping(&self) -> bool {
- false // FIXME: should be true
- }
-
- pub fn bodies(&self) -> &[RigidBodyHandle] {
- &self.bodies
- }
-}
-
-#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
-#[derive(Clone)]
-pub struct IslandSet {
- // We can't store this in the rigid-bodies because that would
- // cause borrowing issues during the traversal.
- traversal_body_timestamps: Coarena<u64>,
- islands: Vec<Island>,
- active_island: usize,
- islands_to_extract: VecDeque<RigidBodyHandle>,
- islands_extraction_queue: Vec<RigidBodyHandle>,
- // NOTE: this value must never be 0, otherwise some
- // invariants used during the traversal can break.
- traversal_timestamp: u64,
-}
-
-impl IslandSet {
- pub fn new() -> Self {
- IslandSet {
- traversal_body_timestamps: Coarena::new(),
- islands: vec![Island::new()],
- active_island: 0,
- islands_to_extract: VecDeque::new(),
- islands_extraction_queue: vec![],
- traversal_timestamp: 1,
- }
- }
-
- pub fn num_active_islands(&self) -> usize {
- 1
- }
-
- pub fn is_island_sleeping(&self, island_id: usize) -> bool {
- island_id != self.active_island
- }
-
- pub fn active_bodies(&self) -> &[RigidBodyHandle] {
- &self.islands[self.active_island].bodies
- }
-
- pub fn incremental_update(&mut self, narrow_phase: &NarrowPhase) {}
-
- pub fn add_rigid_body(&mut self, handle: RigidBodyHandle, body: &mut RigidBody) {
- assert_eq!(body.island_id, crate::INVALID_USIZE);
-
- if !body.is_dynamic() {
- return;
- }
-
- self.traversal_body_timestamps
- .ensure_element_exists(handle.0, 0);
-
- if body.can_sleep() {
- body.island_id = self.islands.len();
- body.island_offset = 0;
- self.islands.push(Island {
- bodies: vec![handle],
- })
- } else {
- let mut active_island = &mut self.islands[self.active_island];
- body.island_id = self.active_island;
- body.island_offset = active_island.bodies.len();
- active_island.bodies.push(handle);
- }
- }
-
- pub fn contact_started(
- &mut self,
- bodies: &mut RigidBodySet,
- mut h1: RigidBodyHandle,
- mut h2: RigidBodyHandle,
- ) {
- let island1 = bodies[h1].island_id;
- let island2 = bodies[h2].island_id;
-
- self.wake_up_island(bodies, island1);
- self.wake_up_island(bodies, island2);
- }
-
- pub fn body_sleep_state_changed(&mut self, bodies: &mut RigidBodySet, handle: RigidBodyHandle) {
- let body = &mut bodies[handle];
- let island_id = body.island_id;
-
- if island_id == crate::INVALID_USIZE {
- self.add_rigid_body(handle, body);
- } else if island_id == self.active_island && body.can_sleep() {
- // The body is sleeping now.
- self.islands_to_extract.push_back(handle);
- } else if island_id != self.active_island && !body.can_sleep() {
- // The body is awake now.
- self.wake_up_island(bodies, island_id);
- }
- }
-
- #[inline(always)]
- fn push_contacting_bodies(
- handle: RigidBodyHandle,
- bodies: &mut RigidBodySet,
- colliders: &ColliderSet,
- narrow_phase: &NarrowPhase,
- queue: &mut Vec<RigidBodyHandle>,
- traversal_body_timestamps: &mut Coarena<u64>,
- first_traversal_timestamp: u64,
- traversal_timestamp: u64,
- ) -> bool {
- for collider_handle in &bodies[handle].colliders {
- if let Some(contacts) = narrow_phase.contacts_with(*collider_handle) {
- for inter in contacts {
- let other = crate::utils::select_other((inter.0, inter.1), *collider_handle);
- let other_body_handle = colliders[other].parent;
- let other_body = &bodies[other_body_handle];
-
- if other_body.is_dynamic() {
- if !other_body.can_sleep() {
- return false;
- }
-
- let other_body_timestamp =
- &mut traversal_body_timestamps[other_body_handle.0];
-
- if *other_body_timestamp >= first_traversal_timestamp
- && *other_body_timestamp < traversal_timestamp
- {
- // We already saw this body during another traversal this frame.
- // So we don't need to continue any further.
- return false;
- }
-
- if *other_body_timestamp != traversal_timestamp {
- *other_body_timestamp = traversal_timestamp;
- queue.push(other_body_handle);
- }
- }
- }
- }
- }
-
- true
- }
-
- pub fn update_sleeping_islands(
- &mut self,
- bodies: &mut RigidBodySet,
- colliders: &mut ColliderSet,
- narrow_phase: &NarrowPhase,
- ) {
- let first_traversal_timestamp = self.traversal_timestamp + 1;
- let mut island_found = false;
-
- while let Some(handle) = self.islands_to_extract.pop_front() {
- self.traversal_timestamp += 1;
- island_found = self.extract_sleeping_island(
- bodies,
- colliders,
- narrow_phase,
- handle,
- first_traversal_timestamp,
- ) || island_found;
-
- // Make sure our `traversal_timestamp` remains correct
- // even if it overflows (can happen in very long-running
- // simulations).
- if self.traversal_timestamp == u64::MAX - 1 {
- // Stop the work now because the overflowing timestamp
- // will cause issues with the traversal. Forcibly reset all
- // the timestamps and continue next frame.
- for body in bodies.iter_mut_internal() {
- body.1.traversal_timestamp = 0;
- }
- self.traversal_timestamp = 1;
- break;
- }
- }
-
- if island_found {
- // Now we need to remove from the active set all the bodies
- // we moved to a sleeping island.
- let mut i = 0;
- let mut new_len = 0;
- let active_island = &mut self.islands[self.active_island];
-
- while i < active_island.bodies.len() {
- let handle = active_island.bodies[i];
- let body = &mut bodies[handle];
-
- if body.island_id == self.active_island {
- // This body still belongs to this island.
- // Update its offset.
- body.island_offset = new_len;
- active_island.bodies[new_len] = handle;
- new_len += 1;
- }
-
- i += 1;
- }
-
- active_island.bodies.truncate(new_len);
- }
- }
-
- fn extract_sleeping_island(
- &mut self,
- bodies: &mut RigidBodySet,
- colliders: &mut ColliderSet,
- narrow_phase: &NarrowPhase,
- handle: RigidBodyHandle,
- first_traversal_timestamp: u64,
- ) -> bool {
- // Attempt to extract a sleeping island by traversing the
- // contact graph starting with the given rigid-body.
- if let Some(body) = bodies.get(handle) {
- if body.is_dynamic() && body.can_sleep() {
- // Perform a breadth-first search of the contact graph starting
- // with this body. We stop the search when an active body is
- // found (meaning that the island cannot sleep), or if we
- // extracted the whole island.
- // We do a breadth-first search in order to increase our chances
- // to find a non-sleeping body quickly: if this body just started
- // sleeping, chances are that a non-sleeping body is close.
- self.islands_extraction_queue.clear();
- self.islands_extraction_queue.push(handle);
- self.traversal_body_timestamps[handle.0] = self.traversal_timestamp;
- let mut i = 0;
-
- while i < self.islands_extraction_queue.len() {
- let handle = self.islands_extraction_queue[i];
-
- let continue_traversal = Self::push_contacting_bodies(
- handle,
- bodies,
- colliders,
- narrow_phase,
- &mut self.islands_extraction_queue,
- &mut self.traversal_body_timestamps,
- first_traversal_timestamp,
- self.traversal_timestamp,
- );
-
- if !continue_traversal {
- // This island cannot sleep yet.
- return false;
- }
-
- i += 1;
- }
-
- // If we reached this point, then we successfully found a sleeping island.
- for (k, handle) in self.islands_extraction_queue.iter().enumerate() {
- let body = &mut bodies[*handle];
- body.island_id = self.islands.len();
- body.island_offset = k;
- }
-
- // FIXME: recycle old islands.
- self.islands.push(Island {
- bodies: std::mem::replace(&mut self.islands_extraction_queue, Vec::new()),
- });
-
- return true;
- }
- }
-
- false
- }
-
- pub fn wake_up_island(&mut self, bodies: &mut RigidBodySet, island_id: usize) {
- if island_id == crate::INVALID_USIZE {
- return;
- }
-
- let mut island_id1 = self.active_island;
- let mut island_id2 = island_id;
-
- if island_id1 != island_id2 {
- let (mut island1, mut island2) =
- utils::get2_mut(&mut self.islands, island_id1, island_id2);
-
- // Make sure island1 points to the biggest island.
- // The typical scenario is that only a few object are awaking
- // one big island. So in this typical scenario, we actually want
- // to merge the active island into the sleeping island, and then
- // mark the sleeping island as active.
- if island2.len() > island1.len() {
- std::mem::swap(&mut island1, &mut island2);
- std::mem::swap(&mut island_id1, &mut island_id2);
- }
-
- // Now merge island2 (the smallest island) into island1 (the bigger one).
- island1.bodies.reserve(island2.len());
-
- for handle in island2.bodies.drain(..) {
- let body = &mut bodies[handle];
- body.island_id = island_id1;
- body.island_offset = island1.len();
- island1.bodies.push(handle);
- }
-
- // Islands can get big so let's save some memory.
- island2.bodies = vec![];
- self.active_island = island_id1;
- }
- }
-}
diff --git a/src/dynamics/mod.rs b/src/dynamics/mod.rs
index 691e504..ab39fb1 100644
--- a/src/dynamics/mod.rs
+++ b/src/dynamics/mod.rs
@@ -13,7 +13,7 @@ pub use parry::mass_properties::MassProperties;
// #[cfg(not(feature = "parallel"))]
pub use self::coefficient_combine_rule::CoefficientCombineRule;
// pub use self::island_set::{Island, IslandSet};
-pub use self::island_set2::{Island, IslandSet};
+pub use self::island_set::{Island, IslandSet};
pub(crate) use self::joint::JointGraphEdge;
pub(crate) use self::rigid_body::RigidBodyChanges;
@@ -25,7 +25,7 @@ pub(crate) use self::solver::ParallelIslandSolver;
mod coefficient_combine_rule;
mod integration_parameters;
// mod island_set;
-mod island_set2;
+mod island_set;
mod joint;
mod rigid_body;
mod rigid_body_set;