use avian3d::{dynamics::solver::joint_graph::JointGraph, math::*, prelude::*};
use bevy::prelude::*;
use examples_common_3d::ExampleCommonPlugin;
fn main() {
let mut app = App::new();
app.add_plugins((DefaultPlugins, ExampleCommonPlugin));
app.add_plugins(
PhysicsPlugins::default()
.build()
.disable::<BvhBroadPhasePlugin>()
.add(BruteForceBroadPhasePlugin),
);
app.add_systems(Startup, setup).run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
Mesh3d(meshes.add(Plane3d::default().mesh().size(8.0, 8.0))),
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
RigidBody::Static,
Collider::cuboid(8.0, 0.002, 8.0),
));
commands.spawn((
Mesh3d(meshes.add(Cuboid::default())),
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
Transform::from_xyz(0.0, 4.0, 0.0),
RigidBody::Dynamic,
AngularVelocity(Vector::new(2.5, 3.4, 1.6)),
Collider::cuboid(1.0, 1.0, 1.0),
));
commands.spawn((
PointLight {
intensity: 2_000_000.0,
shadows_enabled: true,
..default()
},
Transform::from_xyz(4.0, 8.0, 4.0),
));
commands.spawn((
Camera3d::default(),
Transform::from_xyz(-4.0, 6.5, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
));
}
pub struct BruteForceBroadPhasePlugin;
impl Plugin for BruteForceBroadPhasePlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PhysicsSchedule,
collect_collision_pairs.in_set(BroadPhaseSystems::CollectCollisions),
);
}
}
fn collect_collision_pairs(
colliders: Query<(Entity, &ColliderAabb, &ColliderOf)>,
bodies: Query<&RigidBody>,
mut contact_graph: ResMut<ContactGraph>,
joint_graph: Res<JointGraph>,
) {
for [
(collider1, aabb1, collider_of1),
(collider2, aabb2, collider_of2),
] in colliders.iter_combinations()
{
let Ok(rb1) = bodies.get(collider_of1.body) else {
continue;
};
let Ok(rb2) = bodies.get(collider_of2.body) else {
continue;
};
if !rb1.is_dynamic() && !rb2.is_dynamic() {
continue;
}
if !aabb1.intersects(aabb2) {
continue;
}
if joint_graph
.joints_between(collider_of1.body, collider_of2.body)
.any(|edge| edge.collision_disabled)
{
continue;
}
let mut contact_edge = ContactEdge::new(collider1, collider2);
contact_edge.body1 = Some(collider_of1.body);
contact_edge.body2 = Some(collider_of2.body);
contact_graph.add_edge(contact_edge);
}
}