traaains/sim/track/
pos.rs1use std::f32::consts::PI;
2
3use bevy::{
4 ecs::{component::Component, entity::Entity, query::Without, system::Query},
5 math::Quat,
6 transform::components::Transform,
7};
8use shapes::{Derivable, lerp::Lerp};
9
10use crate::{sim::track::segment::TrackSegment, utils::Dir};
11
12#[derive(Component, Clone, Copy, Debug)]
14pub struct TrackPos {
15 pub segment: Entity,
17 pub idx: f32,
19 pub dir: Option<Dir>,
22}
23
24#[derive(Component)]
27pub struct IgnoreTrackPosUpdate;
28
29pub fn update_on_track_pos(
31 on_track: Query<(&TrackPos, &mut Transform), Without<IgnoreTrackPosUpdate>>,
32 segment: Query<(&TrackSegment, &Transform), Without<TrackPos>>,
33) {
34 for (track_pos, mut transform) in on_track {
35 if let Ok((segment, segment_transform)) = segment.get(track_pos.segment) {
36 transform.translation =
37 segment.shape.lerp(track_pos.idx).extend(1.0) + segment_transform.translation;
38
39 let tangent = segment.shape.derivative().lerp(track_pos.idx);
41 let mut angle = f32::atan2(tangent.y, tangent.x);
42 if track_pos.dir == Some(Dir::Positive) {
43 angle += PI;
44 }
45 transform.rotation = Quat::from_rotation_z(angle);
46 }
47 }
48}