Skip to content

Commit

Permalink
[editor] bezier - control points and actual points
Browse files Browse the repository at this point in the history
  • Loading branch information
Nertsal committed Oct 18, 2024
1 parent bbebeb8 commit 039cfc8
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
2 changes: 1 addition & 1 deletion crates/ctl-core/src/model/collider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct Collision {
pub penetration: Coord,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Collider {
pub position: vec2<Coord>,
pub rotation: Angle<Coord>,
Expand Down
36 changes: 24 additions & 12 deletions src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,35 +818,43 @@ impl LevelEditor {
d <= MAX_VISIBILITY
};

// TODO: use cached
let curve = light_event.light.movement.bake();
let mut points: Vec<_> = light_event
.light
.movement
.timed_positions()
.map(|(i, trans, time)| {
.map(|(i, trans_control, time)| {
let trans_actual = match i {
WaypointId::Initial => curve.get(0, Time::ZERO),
WaypointId::Frame(i) => curve.get(i, Time::ONE),
}
.unwrap_or(trans_control); // Should be unreachable, but just in case
(
Waypoint {
visible: visible(time),
original: Some(i),
collider: base_collider.transformed(trans),
control: base_collider.transformed(trans_control),
actual: base_collider.transformed(trans_actual),
},
time,
)
})
.collect();
points.sort_by_key(|(point, time)| {
(
point.collider.position.x,
point.collider.position.y,
point.control.position.x,
point.control.position.y,
(event_time + *time - self.current_beat).abs(),
)
});

{
let mut points = points.iter_mut();
if let Some(last) = points.next() {
let mut last = last.0.collider.position;
let mut last = last.0.control.position;
for (point, _) in points {
let pos = point.collider.position;
let pos = point.control.position;
if last == pos {
point.visible = false;
}
Expand All @@ -863,17 +871,19 @@ impl LevelEditor {
let i = match points.binary_search_by_key(&new_time, |(_, time)| *time) {
Ok(i) | Err(i) => i,
};
let control = base_collider.transformed(Transform {
translation: cursor_world_pos_snapped,
rotation: self.place_rotation,
scale: self.place_scale,
});
points.insert(
i,
(
Waypoint {
visible: true,
original: None,
collider: base_collider.transformed(Transform {
translation: cursor_world_pos_snapped,
rotation: self.place_rotation,
scale: self.place_scale,
}),
actual: control.clone(),
control,
},
new_time,
),
Expand All @@ -883,7 +893,9 @@ impl LevelEditor {
let points: Vec<_> = points.into_iter().map(|(point, _)| point).collect();

let hovered = points.iter().position(|point| {
point.visible && point.collider.contains(cursor_world_pos)
point.visible
&& (point.control.contains(cursor_world_pos)
|| point.actual.contains(cursor_world_pos))
});

waypoints = Some(Waypoints {
Expand Down
3 changes: 2 additions & 1 deletion src/editor/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ pub struct Waypoint {
/// Index of the original keyframe.
/// `None` when placing a new waypoint.
pub original: Option<WaypointId>,
pub collider: Collider,
pub control: Collider,
pub actual: Collider,
}

impl EditorLevelState {
Expand Down
43 changes: 40 additions & 3 deletions src/render/editor/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,45 @@ impl EditorRender {
continue;
}

if point.actual != point.control {
self.util.draw_outline(
&point.control,
0.025,
crate::util::with_alpha(color, alpha),
&level_editor.model.camera,
&mut pixel_buffer,
);

// Connect control and actual with a line
let color = crate::util::with_alpha(color, alpha * 0.75);
let mut from = draw2d::ColoredVertex {
a_pos: point.control.position.as_f32(),
a_color: color,
};
let to = draw2d::ColoredVertex {
a_pos: point.actual.position.as_f32(),
a_color: color,
};

let period = options.dash_length + options.space_length;
let speed = 1.0;
let t = ((level_editor.real_time.as_f32() * speed) / period)
.fract()
* period;
from.a_pos += (to.a_pos - from.a_pos).normalize_or_zero() * t;
self.util.draw_dashed_chain(
&[from, to],
&util::DashRenderOptions {
width: options.width * 0.5,
..options
},
&level_editor.model.camera,
&mut pixel_buffer,
);
}

self.util.draw_outline(
&point.collider,
&point.actual,
0.05,
crate::util::with_alpha(color, alpha),
&level_editor.model.camera,
Expand All @@ -286,7 +323,7 @@ impl EditorRender {
let text_color = crate::util::with_alpha(THEME.light, alpha);
self.util.draw_text_with(
format!("{}", i + 1),
point.collider.position,
point.control.position,
TextRenderOptions::new(1.5).color(text_color),
Some(util::additive()),
&level_editor.model.camera,
Expand All @@ -304,7 +341,7 @@ impl EditorRender {
if let Some(beat) = beat_time {
self.util.draw_text_with(
format!("at {}", beat),
point.collider.position - vec2(0.0, 0.6).as_r32(),
point.control.position - vec2(0.0, 0.6).as_r32(),
TextRenderOptions::new(0.6).color(text_color),
Some(util::additive()),
&level_editor.model.camera,
Expand Down

0 comments on commit 039cfc8

Please sign in to comment.