Skip to content

Commit

Permalink
Fix usage without Parry (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jondolf committed Aug 3, 2024
1 parent 5c2188c commit e2a1695
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 65 deletions.
8 changes: 7 additions & 1 deletion src/collision/collider/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::marker::PhantomData;

use crate::{broad_phase::BroadPhaseSet, prelude::*, prepare::PrepareSet};
#[cfg(feature = "bevy_scene")]
#[cfg(all(feature = "bevy_scene", feature = "default-collider"))]
use bevy::scene::SceneInstance;
use bevy::{
ecs::{intern::Interned, schedule::ScheduleLabel, system::SystemId},
Expand Down Expand Up @@ -233,6 +233,7 @@ impl<C: ScalableCollider> Plugin for ColliderBackendPlugin<C> {
.ambiguous_with_all(),
);

#[cfg(feature = "default-collider")]
app.add_systems(
Update,
(
Expand Down Expand Up @@ -315,6 +316,7 @@ fn update_root_collider_parents<C: AnyCollider>(
/// # Panics
///
/// Panics if the [`ColliderConstructor`] requires a mesh but no mesh handle is found.
#[cfg(feature = "default-collider")]
fn init_collider_constructors(
mut commands: Commands,
#[cfg(feature = "collider-from-mesh")] meshes: Res<Assets<Mesh>>,
Expand Down Expand Up @@ -371,6 +373,7 @@ fn init_collider_constructors(
/// Generates [`Collider`]s for descendants of entities with the [`ColliderConstructorHierarchy`] component.
///
/// If an entity has a `SceneInstance`, its collider hierarchy is only generated once the scene is ready.
#[cfg(feature = "default-collider")]
fn init_collider_constructor_hierarchies(
mut commands: Commands,
#[cfg(feature = "collider-from-mesh")] meshes: Res<Assets<Mesh>>,
Expand Down Expand Up @@ -481,6 +484,7 @@ fn init_collider_constructor_hierarchies(
}
}

#[cfg(feature = "default-collider")]
fn pretty_name(name: Option<&Name>, entity: Entity) -> String {
name.map(|n| n.to_string())
.unwrap_or_else(|| format!("<unnamed entity {}>", entity.index()))
Expand Down Expand Up @@ -728,9 +732,11 @@ pub(crate) fn update_collider_mass_properties<C: AnyCollider>(

#[cfg(test)]
mod tests {
#[cfg(feature = "default-collider")]
use super::*;

#[test]
#[cfg(feature = "default-collider")]
fn sensor_mass_properties() {
let mut app = App::new();

Expand Down
4 changes: 0 additions & 4 deletions src/collision/collider/hierarchy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,6 @@ impl Plugin for ColliderHierarchyPlugin {
}
}

#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq)]
#[reflect(Component)]
pub(crate) struct PreviousColliderTransform(pub ColliderTransform);

/// Updates [`ColliderParent`] for descendant colliders of [`RigidBody`] entities.
///
/// The [`ColliderBackendPlugin`] handles collider parents for colliders that are
Expand Down
7 changes: 6 additions & 1 deletion src/collision/collider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ mod hierarchy;

pub use backend::{ColliderBackendPlugin, ColliderMarker};
pub use hierarchy::ColliderHierarchyPlugin;
pub(crate) use hierarchy::PreviousColliderTransform;

/// The default [`Collider`] that uses Parry.
#[cfg(all(
Expand All @@ -30,7 +29,9 @@ pub use parry::*;
mod world_query;
pub use world_query::*;

#[cfg(feature = "default-collider")]
mod constructor;
#[cfg(feature = "default-collider")]
pub use constructor::{
ColliderConstructor, ColliderConstructorHierarchy, ColliderConstructorHierarchyConfig,
};
Expand Down Expand Up @@ -466,3 +467,7 @@ impl MapEntities for CollidingEntities {
.collect()
}
}

#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq)]
#[reflect(Component)]
pub(crate) struct PreviousColliderTransform(pub ColliderTransform);
2 changes: 1 addition & 1 deletion src/collision/contact_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ pub fn contact_manifolds(
normal2,
-contact.dist,
)
.with_feature_ids(contact.fid1, contact.fid2)
.with_feature_ids(contact.fid1.into(), contact.fid2.into())
})
.collect(),
index: manifold_index,
Expand Down
76 changes: 76 additions & 0 deletions src/collision/feature_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use bevy::prelude::*;

/// A feature ID indicating the type of a geometric feature: a vertex, an edge, or (in 3D) a face.
///
/// This type packs the feature type into the same value as the feature index,
/// which indicates the specific vertex/edge/face that this ID belongs to.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Reflect)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
#[reflect(Debug, Hash, PartialEq)]
pub struct PackedFeatureId(pub u32);

impl PackedFeatureId {
/// Packed feature id identifying an unknown feature.
pub const UNKNOWN: Self = Self(0);

const CODE_MASK: u32 = 0x3fff_ffff;
const HEADER_MASK: u32 = !Self::CODE_MASK;
const HEADER_VERTEX: u32 = 0b01 << 30;
#[cfg(feature = "3d")]
const HEADER_EDGE: u32 = 0b10 << 30;
const HEADER_FACE: u32 = 0b11 << 30;

/// Converts a vertex feature id into a packed feature id.
pub fn vertex(code: u32) -> Self {
assert_eq!(code & Self::HEADER_MASK, 0);
Self(Self::HEADER_VERTEX | code)
}

/// Converts a edge feature id into a packed feature id.
#[cfg(feature = "3d")]
pub fn edge(code: u32) -> Self {
assert_eq!(code & Self::HEADER_MASK, 0);
Self(Self::HEADER_EDGE | code)
}

/// Converts a face feature id into a packed feature id.
pub fn face(code: u32) -> Self {
assert_eq!(code & Self::HEADER_MASK, 0);
Self(Self::HEADER_FACE | code)
}

/// Is the identified feature a face?
pub fn is_face(self) -> bool {
self.0 & Self::HEADER_MASK == Self::HEADER_FACE
}

/// Is the identified feature a vertex?
pub fn is_vertex(self) -> bool {
self.0 & Self::HEADER_MASK == Self::HEADER_VERTEX
}

/// Is the identified feature an edge?
#[cfg(feature = "3d")]
pub fn is_edge(self) -> bool {
self.0 & Self::HEADER_MASK == Self::HEADER_EDGE
}

/// Is the identified feature unknown?
pub fn is_unknown(self) -> bool {
self == Self::UNKNOWN
}
}

impl From<u32> for PackedFeatureId {
fn from(code: u32) -> Self {
Self(code)
}
}

#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
impl From<crate::parry::shape::PackedFeatureId> for PackedFeatureId {
fn from(id: crate::parry::shape::PackedFeatureId) -> Self {
Self(id.0)
}
}
9 changes: 3 additions & 6 deletions src/collision/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,13 @@ pub use collider::*;
mod layers;
pub use layers::*;

mod feature_id;
pub use feature_id::PackedFeatureId;

use crate::prelude::*;
use bevy::prelude::*;
use indexmap::IndexMap;

/// A feature ID indicating the type of a geometric feature: a vertex, an edge, or (in 3D) a face.
///
/// This type packs the feature type into the same value as the feature index,
/// which indicates the specific vertex/edge/face that this ID belongs to.
pub type PackedFeatureId = parry::shape::PackedFeatureId;

// TODO: Refactor this into a contact graph.
// Collisions are stored in an `IndexMap` that uses fxhash.
// It should have faster iteration than a `HashMap` while mostly retaining other performance characteristics.
Expand Down
11 changes: 10 additions & 1 deletion src/dynamics/ccd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@
//!
//! ## Swept CCD
//!
//! *Note: Swept CCD currently only supports the built-in `Collider`.*
//!
//! **Swept CCD** is a form of Continuous Collision Detection that sweeps potentially colliding objects
//! from their previous positions to their current positions, and if a collision is found, moves the bodies
//! back to the time of impact. This way, the normal collision algorithms will be able to detect and handle
Expand Down Expand Up @@ -225,11 +227,14 @@
//! However, this comes at the cost of worse performance for the entire simulation.

use crate::{collision::broad_phase::AabbIntersections, prelude::*, prepare::PrepareSet};
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
use bevy::ecs::query::QueryData;
use bevy::{
ecs::{intern::Interned, query::QueryData, schedule::ScheduleLabel},
ecs::{intern::Interned, schedule::ScheduleLabel},
prelude::*,
};
use derive_more::From;
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
use parry::query::{
cast_shapes, cast_shapes_nonlinear, NonlinearRigidMotion, ShapeCastHit, ShapeCastOptions,
};
Expand Down Expand Up @@ -272,6 +277,7 @@ impl Plugin for CcdPlugin {

physics.configure_sets(SweptCcdSet.in_set(SolverSet::PostSubstep));

#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
physics.add_systems(solve_swept_ccd.in_set(SweptCcdSet));
}
}
Expand Down Expand Up @@ -510,6 +516,7 @@ fn init_ccd_aabb_intersections(mut commands: Commands, query: Query<Entity, Adde
}
}

#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
#[derive(QueryData)]
#[query_data(mutable)]
struct SweptCcdBodyQuery {
Expand All @@ -534,6 +541,7 @@ struct SweptCcdBodyQuery {
/// are essentially moved back in time, making them appear to momentarily move slower.
/// Secondary contacts are also not accounted for.
#[allow(clippy::useless_conversion)]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
fn solve_swept_ccd(
ccd_query: Query<(Entity, &AabbIntersections), With<SweptCcd>>,
bodies: Query<SweptCcdBodyQuery>,
Expand Down Expand Up @@ -698,6 +706,7 @@ fn solve_swept_ccd(

/// Computes the time of impact for the motion of two objects for Continuous Collision Detection.
/// If the TOI is larger than `min_toi` or the shapes never touch, `None` is returned.
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
fn compute_ccd_toi(
mode: SweepMode,
motion1: &NonlinearRigidMotion,
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ pub use type_registration::PhysicsTypeRegistrationPlugin;
pub mod prelude {
#[cfg(feature = "debug-plugin")]
pub use crate::debug_render::*;
#[cfg(feature = "default-collider")]
pub(crate) use crate::position::RotationValue;
pub use crate::{
collision::{
self,
Expand All @@ -494,9 +496,7 @@ pub mod prelude {
};
pub(crate) use crate::{
math::*,
position::{
PreSolveAccumulatedTranslation, PreSolveRotation, PreviousRotation, RotationValue,
},
position::{PreSolveAccumulatedTranslation, PreSolveRotation, PreviousRotation},
};
pub use avian_derive::*;
}
Expand Down
55 changes: 11 additions & 44 deletions src/spatial_query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,40 +152,22 @@
//!
//! To specify which colliders should be considered in the query, use a [spatial query filter](`SpatialQueryFilter`).

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
mod pipeline;
mod query_filter;
mod ray_caster;
#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
mod shape_caster;
#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
mod system_param;

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
pub use pipeline::*;
pub use query_filter::*;
pub use ray_caster::*;
#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
pub use shape_caster::*;
#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
pub use system_param::*;

use crate::{prelude::*, prepare::PrepareSet};
Expand Down Expand Up @@ -273,10 +255,7 @@ fn init_ray_hits(mut commands: Commands, rays: Query<(Entity, &RayCaster), Added
}
}

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
fn init_shape_hits(
mut commands: Commands,
shape_casters: Query<(Entity, &ShapeCaster), Added<ShapeCaster>>,
Expand Down Expand Up @@ -356,10 +335,7 @@ fn update_ray_caster_positions(
}
}

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
type ShapeCasterPositionQueryComponents = (
&'static mut ShapeCaster,
Option<&'static Position>,
Expand All @@ -368,10 +344,7 @@ type ShapeCasterPositionQueryComponents = (
Option<&'static GlobalTransform>,
);

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
#[allow(clippy::type_complexity)]
fn update_shape_caster_positions(
mut shape_casters: Query<ShapeCasterPositionQueryComponents>,
Expand Down Expand Up @@ -459,10 +432,7 @@ fn update_shape_caster_positions(
}
}

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
fn raycast(mut rays: Query<(Entity, &RayCaster, &mut RayHits)>, spatial_query: SpatialQuery) {
for (entity, ray, mut hits) in &mut rays {
if ray.enabled {
Expand All @@ -473,10 +443,7 @@ fn raycast(mut rays: Query<(Entity, &RayCaster, &mut RayHits)>, spatial_query: S
}
}

#[cfg(all(
feature = "default-collider",
any(feature = "parry-f32", feature = "parry-f64")
))]
#[cfg(any(feature = "parry-f32", feature = "parry-f64"))]
fn shapecast(
mut shape_casters: Query<(Entity, &ShapeCaster, &mut ShapeHits)>,
spatial_query: SpatialQuery,
Expand Down
Loading

0 comments on commit e2a1695

Please sign in to comment.