Skip to content

Commit

Permalink
working cam / physics need to be debugged
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienjuif committed Nov 24, 2023
1 parent 246ee58 commit f4543d1
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 77 deletions.
67 changes: 45 additions & 22 deletions camera/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ use bevy::{
system::{Commands, Res, ResMut},
},
gizmos::{gizmos::Gizmos, GizmoConfig},
math::{Vec2, Vec3},
log::{debug, warn},
math::{self, Vec2, Vec3},
prelude::{
default, App, Camera2dBundle, Entity, Plugin, PostUpdate, Query, Transform, With, Without,
default, App, Camera2dBundle, Entity, Plugin, PostUpdate, Query, Time, Timer, TimerMode,
Transform, With, Without,
},
render::{
color::Color,
mesh::{shape, Mesh},
},
sprite::{ColorMaterial, MaterialMesh2dBundle},
time::Time,
};

#[derive(Component)]
Expand All @@ -31,7 +32,8 @@ pub struct Camera {
// it allow us to place the camera a bit ahead of time
look_at: Vec3,
ahead_factor: Vec3,
moving: bool,
traveling: bool,
center_after: Timer,
}

impl Camera {
Expand All @@ -42,7 +44,8 @@ impl Camera {
target_prev_translation: Vec3::ZERO,
look_at: Vec3::ZERO,
ahead_factor,
moving: false,
traveling: false,
center_after: Timer::from_seconds(0.4, TimerMode::Once),
}
}

Expand All @@ -53,7 +56,8 @@ impl Camera {
target_prev_translation: Vec3::ZERO,
look_at: Vec3::ZERO,
ahead_factor: Vec3::ONE,
moving: false,
traveling: false,
center_after: Timer::from_seconds(0.4, TimerMode::Once),
}
}
}
Expand Down Expand Up @@ -119,29 +123,48 @@ fn cameraman(
continue;
}

// process velocity
// process target velocity
let mut target_velocity = target_transform.translation - camera.target_prev_translation;
if target_velocity != Vec3::ZERO {
target_velocity /= time.delta_seconds()
let target_moving = target_velocity != Vec3::ZERO;
if target_moving {
target_velocity /= time.delta_seconds();
}
camera.look_at = target_transform.translation + (target_velocity * camera.ahead_factor);
camera.target_prev_translation = target_transform.translation;

// if the target is in the dead zone, do nothing on camera
let diff = camera_transform.translation - target_transform.translation;
let diff_abs = diff.abs();
if !camera.moving
&& diff_abs.x <= camera.dead_zone.x
&& diff_abs.y <= camera.dead_zone.y
{
break;
// process dead zone
let diff_pos_abs = (target_transform.translation - camera_transform.translation)
.truncate()
.abs();
let dead_zone =
diff_pos_abs.x <= camera.dead_zone.x && diff_pos_abs.y <= camera.dead_zone.y;
let centered = diff_pos_abs.x < 3.0 && diff_pos_abs.y < 3.0;

// center after some time in the dead zone
if dead_zone && !centered && !target_moving && !camera.traveling {
camera.center_after.tick(time.delta());
} else {
camera.center_after.reset();
}

// triggers travelling if we are out of dead zone
if !dead_zone {
camera.traveling = true;
}

// moving camera
camera.moving = target_velocity != Vec3::ZERO;
let next_pos = (camera.look_at - camera_transform.translation) * 0.02;
camera_transform.translation.x += next_pos.x;
camera_transform.translation.y += next_pos.y;
// once the camera is moving we keep moving until we reach the center
if camera.traveling || camera.center_after.finished() {
let next_pos = camera.look_at - camera_transform.translation;
camera_transform.translation.x += next_pos.x * 0.02;
camera_transform.translation.y += next_pos.y * 0.02;

// we arrived
if centered && !target_moving {
camera.traveling = false;
}
}

// if the target is in the dead zone, do nothing on camera
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() {
// --- camera ---
.add_plugins((
CameraPlugin,
CameraDebugPlugin,
// CameraDebugPlugin,
))
// --- physics ---
.add_plugins((
Expand Down
108 changes: 54 additions & 54 deletions src/physics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,58 +87,58 @@ fn check_collisions(
mut event_writer: EventWriter<CollisionEvent>,
query: Query<Entity>,
) {
let mut before = collisions.clone();
let mut events = Vec::<CollisionEvent>::new();

// first pass detects intersections
for (e1, e2, _) in rapier_context.intersection_pairs() {
if !query.contains(e1) || !query.contains(e2) {
// entity are removed from ECS
// so we are not spawning events for them
// they will be removed in last loop
continue;
}

let pair = EntityPair::new(e1, e2);
before.remove(&pair);
if collisions.contains(&pair) {
// we already have a started event for this intersection
continue;
}

collisions.add(pair);
events.push(CollisionEvent::Started(pair.entity1, pair.entity2));
}

// second pass detects contacts
for c in rapier_context.contact_pairs() {
let e1 = c.collider1();
let e2 = c.collider2();

if !query.contains(e1) || !query.contains(e2) {
// entity are removed from ECS
// so we are not spawning events for them
// they will be removed in last loop
continue;
}

let pair = EntityPair::new(e1, e2);
before.remove(&pair);
if collisions.contains(&pair) {
// we already have a started event for this intersection
continue;
}

collisions.add(pair);
events.push(CollisionEvent::Started(e1, e2));
}

// emit ended collisions
// TODO: implement iter() that return an iterator on the collisions struct
for (pair, _) in before.pairs {
collisions.remove(&pair);
events.push(CollisionEvent::Stopped(pair.entity1, pair.entity2));
}

event_writer.send_batch(events);
// let mut before = collisions.clone();
// let mut events = Vec::<CollisionEvent>::new();

// // first pass detects intersections
// for (e1, e2, _) in rapier_context.intersection_pairs() {
// if !query.contains(e1) || !query.contains(e2) {
// // entity are removed from ECS
// // so we are not spawning events for them
// // they will be removed in last loop
// continue;
// }

// let pair = EntityPair::new(e1, e2);
// before.remove(&pair);
// if collisions.contains(&pair) {
// // we already have a started event for this intersection
// continue;
// }

// collisions.add(pair);
// events.push(CollisionEvent::Started(pair.entity1, pair.entity2));
// }

// // second pass detects contacts
// for c in rapier_context.contact_pairs() {
// let e1 = c.collider1();
// let e2 = c.collider2();

// if !query.contains(e1) || !query.contains(e2) {
// // entity are removed from ECS
// // so we are not spawning events for them
// // they will be removed in last loop
// continue;
// }

// let pair = EntityPair::new(e1, e2);
// before.remove(&pair);
// if collisions.contains(&pair) {
// // we already have a started event for this intersection
// continue;
// }

// collisions.add(pair);
// events.push(CollisionEvent::Started(e1, e2));
// }

// // emit ended collisions
// // TODO: implement iter() that return an iterator on the collisions struct
// for (pair, _) in before.pairs {
// collisions.remove(&pair);
// events.push(CollisionEvent::Stopped(pair.entity1, pair.entity2));
// }

// event_writer.send_batch(events);
}

0 comments on commit f4543d1

Please sign in to comment.